EOS

Advanced ColdFire TCP/IP Clients

Freescale/NXP ha proposto un’interessante suite TCP/IP che intende coniugare prestazioni e facilità di impiego allo scopo di fornire un client ottimizzato particolarmente indicato per sistemi embedded.

Freescale/NXP con il suo Advanced ColdFire TCP/IP clients è riuscita ad ottenere uno stack TCP/IP per sistemi embedded con un uso minimo di memoria, in modo particolare di memoria volatile. Lo stack di Freescale offre un http, un DHCP client e un DNS utilizzato dal protocollo http per la traslazione di nomi di host in indirizzi IP e viceversa.

Figura 1: schema di una comunicazione http.

Figura 1: schema di una comunicazione http.

Il modello OSI si basa su sette strati o livelli, ognuno si occupa di una parte dedicata ed è in relazione sola con un modulo funzionale ben definito, figura 2.

Figura 2: il modello ISO/OSI.

Figura 2: il modello ISO/OSI.

Lo strato più basso (physical e Data Link Layer) è tradizionalmente implementato in hardware, mentre gli strati successivi sono realizzati in software. Lo strato superiore, o applicativo, definisce i  più comuni protocolli di comunicazione utilizzati su Internet: dall’http al tftp. Non solo, questo strato è anche utilizzato per realizzare protocolli custom. Grazie allo strato applicativo http è possibile implementare diversi servizi, tra cui un Rss feed reader.

Http

Il protocollo http, o Hyper-Text Transport Protocol, è il protocollo di comunicazione utilizzato sul web: è attraverso http che si accedono alle pagine web in modo ipertestuale. Lo scopo del protocollo HTTP è di permettere un trasferimento di file (essenzialmente in formato HTML) localizzati grazie ad una stringa di caratteri detta URL tra un navigatore  (il client) e un server web. T ipicamente con la parte client si è in grado di ricevere e di leggere le pagine mentre il lato server si utilizza per immagazzinare le informazioni e trasferire le pagine. Il  protocollo http è definito attraverso la specifica RFC 2616 (versione 1.1 di http) e RFC 1945 (versione 1.0). Il protocollo è del tipo request/reply: un client richiede un servizio (pagina web) al server e questo risponde con il contenuto della pagina in formato HTML. Non solo, il protocollo http può anche essere utilizzato per spedire qualsiasi tipo di dati, incluso dati in forma binaria.  Il client, in base al protocollo, richiede  il file attraverso il comando, o metodo, GET; il server risponde inserendo le informazioni che identificano  il protocollo, haeder http, in testa alle informazioni  richieste.  Il lato client può anche spedire un file con il comando POST. La figura 3 mostra una sessione tipica, mentre il listato 1 pone in evidenza la informazioni che si scambiano i due attori: client e server.

GET /filename.htm HTTP/1.1
# Asks the server to respond with the contents of filename.htm
# Tells the server that it supports the HTTP1.1 standard
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword
# Tells the server that it supports: gif, x-xbitmaps, jpeg, and pjpeg images,
# and msword documents
Accept-language: en-us
# Tells the server that the language is English
Accept-Encoding: gzip, deflate
# The gzip and deflate decompression algorithms are available
User-Agent: Mozzilla/4.0 (compatable; MSIE 6.0; Windows NT 5.1)
# Tells the server that the browser is running IE6.0 on a Windows computer
Connection: Keep-Alive
# Tells the server not to close the connection after the file is sent
HTTP/1.1 200 OK
# Tells the client/browser that HTTP1.1 is supported, and the 200 status code tells
# the client that the file was found
Server: Microsoft-IIS/6.0
# Informs the client of the web server type and version
Cache-Control: no-cache
# Tells the client to disable cache
Content-Type: text/html
# Tells the client the type of data that follows
Content-Encoding: gzip
# Tells the client that the following data is encrypted using gzip
Content-Length: 9062
# Tells the client how many bytes are to follow
Listato 1-Scambio di messaggi tra client/server HTTP
Figura 3: schema di una comunicazione Request-Response in http.

Figura 3: schema di una comunicazione Request-Response in http.

La tabella 1 mostra i diversi comandi previsti dallo standard RFC 2616. La suite di Freescale non ha ignorato un’esigenza fondamentale per un sistema embedded, vale a dire la necessità di ridurre l’overhead della pila TCP/IP e, nel contempo, di incrementarne le prestazioni.

Tabella 1 – RFC 2616

Tabella 1 – RFC 2616

Per raggiungere questo obiettivo Freescale ha implementato un Keep Alive o connessione persistente. La RFC 793 non prevede particolari azioni da seguire quando non ci sono dati da tra smettere. Per questa ragione alcune implementazioni prevedono di trasmettere pacchetti privi di informazioni in modo periodico per controllare la presenza di connessioni non più attive: questo particolare sistema è chiamato Keep Alive. Un meccanismo Keep Alive prevede necessariamente un timer dedicato: questo è reimpostato alla ricezione o alla trasmissione di ogni segmento e, allo scadere, è spedito successivamente un segnale di Keep Alive. In un sistema tipico si mantengono sempre attive le connessioni, viceversa nel caso di una transizione http in modo non persistente il flusso delle informazioni è mostrato nella figura 4.

Figura 4: transazione http non persistente

Figura 4: transazione http non persistente

In sostanza una volta stabilita la connessione TCP/IP e richiesto  il servizio, il lato server risponde ponendo sulla linea l’informazione associata e, al termine, le connessioni stabilite sono chiuse. Al contrario, con una connessione persistente con Keep Alive implementato, la connessione non è chiusa ad ogni comando elaborato, ma solo alla fine della sessione di lavoro. In questo modo il server si pone in attesa per un comando successivo, ad esempio GET. A questo proposito si veda la figura 5.

Figura 5: transazione http persistente.

Figura 5: transazione http persistente.

La tabella 2 risalta le API disponibili sul lato client, mentre la tabella 3 mostra i file e le definizioni utilizzate in questa implementazione del protocollo http.

Tabella 3 – API http Client

Tabella 2 – API http Client

 

Tabella 3 – API http Client

Tabella 3 – API http Client

Dhcp

Il  DHCP (Dinamic Host Configuration Protocol) è un protocollo di configurazione Host Dinamico. Vale a dire il protocollo DHCP stabilisce  il meccanismo di comunicazione  attraverso  il quale un sistema può connettersi ad una rete ed ottenere le informazioni necessarie per comunicare. In sostanza, il DHCP permette ai dispositivi che ne facciano richiesta di essere automaticamente con figurati per entrare a far parte della LAN. Tramite questo protocollo, non è necessario specificare manualmente parametri di rete in quanto il DHCP-server  fornisce tutte le informazioni necessarie al client nel momento stesso in cui questo effettua  il boot. Il protocollo è definito attraverso  i due RFC 2131 e 2132 e i pacchetti sono trasferiti utilizzando lo strato UDP con le porte BOOTP, cioè 67 e 68. La prima fase del processo di configurazione si esplicita attraverso la richiesta di IP. Inizialmente  il client configura ‘sommariamente’ il TCP/IP per ricevere automaticamente un IP dal server DHCP. La richiesta fatta dal client è indirizzata all’indirizzo di broadcast visto che l’indirizzo IP del server è sconosciuto. Di conseguenza la richiesta conterrà come mittente 0.0.0.0 (poiché l’IP non è stato ancora configurato) e come destinazione 255.255.255.255. La richiesta (DHCPDISCOVER) deve contenere inoltre l’indirizzo MAC della scheda di rete e il  nome del computer, in questo modo è identificato univocamente dal server. Successivamente, il server  DHCP  invia  un  messaggio (DHCPOFFER)  broadcast  contenente l’indirizzo IP. Il client utilizzerà  il primo IP in ricezione, nel caso che ci siano più server DHCP sulla rete, mentre gli altri saranno ignorati. Dopo aver accettato un IP, il  client invia un messaggio (simile a DHCPREQUEST)  broadcast informando tutti i server DHCP che ha accettato un IP. Il messaggio  include l’indirizzo del server DHCP che ha mandato l’IP accettato, in questo modo  tutti gli altri server ritirano le loro offerte. Il  server DHCP manda quindi un messaggio di conferma (DHCPACK) al client, contenente  il valore per l’IP. Quando il client riceve il messaggio di ACK si completa la configura zione del TCP/IP. La figura 6 mostra il comportamento del protocollo DHCP. La norma RFC 2132 specifica le diverse opzioni che possono essere richieste dal lato client. Il file dhcpclnt.h presente nella suite mostra le opzioni disponibili. Le opzioni che si ritengono più interessanti sono DHOP_NAME e DHOP_DOMAIN. Il  client DHCP è implementato dai file dhcpclnt.c, dhcpclnt.h e dhcsetup.c. La struttura netstatic[] deve essere inizializzata a zero prima di chiamare la routine dhc_setup() utilizzata per far partire la transazione DHCP. Per gestire il protocollo il client dispone di due API, dhc_setup() e dhc_second(). La prima funzione inizializza  il  client DHC P, mentre la seconda, chiamata ogni secondo, si preoccupa di supportare il DHCP per gestire il colloquio sulla linea.

Figura 6: transazione DHCP.

Figura 6: transazione DHCP.

Dns

Per ultimo il DNS client comunica, come risulta ovvio, con il DNS (domain name server). La presenza del DSN è particolarmente importante; infatti, è il DNS che ci permette di collegarci ai diversi siti attraverso una stringa, ad esempio www.inware.it, in luogo di una poco mnemonica stringa numerica. I DNS quindi, non fanno altro che trovare e restituirci la corrispondenza tra il nome a dominio e il relativo indirizzo  IP, indirizzando la nostra navigazione verso il  sito web desiderato. Il  protocollo è descritto nel documento RFC 1305 e può utilizzare UDP o TCP con la porta 53. Tutte le informazioni sono contenuti in un singolo messaggio e il protocollo è descritto nella nota RFC La presenza della macro DNS_CLIENT nel file ipport.h permette di abilitare o meno il servizio.  Inoltre, il client è costantemente aggiornato ogni secondo con la funzione dns_check(). Per lavorare correttamente il client deve essere inizializzato mediante un array, dns_server, di indirizzi IP dei nomi dei server. La gestione del protocollo è garantita attraverso le API che curano l’aspetto implementativo, la tabella 4 pone in evidenza le diverse funzioni disponibili mentre il listato 2 mostra un esempio.

// url is a NULL terminated string containing the complete url
// The host name can be a dot notation ip address, or a Domain name
// example 75.18.69.29/index.html
// or www.emgware.com/index.html
// The parse_ipad function returns a 0 if the string contains a ip address in dot
// notation

cp = parse_ipad(&ipaddr, &snbits, (char *)url);

// Is it a ip address?
if(cp)
  { // String is not a ip address
                                      // Pre-process string to eliminate any prefix (http://) and anything
after                                  //domain name
                                      // Copy domain name only to allocated buffer;
  temp_buffer = (unsigned char *)npalloc(strlen((char *)url)+10);
                                      if(temp_buffer)
                                      {
                                      temp_buffer(0) = 0; // in case
                                      // The preprocess_url function copies only the domain name into
                                      // temp_buffer.
                                      (void)preprocess_url(temp_buffer, url);
                                      ipaddr = 0;
                                      // We will make multiple attempts at connecting to the DNS
                                      // server
                                      for(i=0; i<EMG_HTTP_CLIENT_DNS_SEARCH_TIME_SECS; i++)
                                      {
                                      tk_sleep(200);
                                      // Send DNS client only the domain name (www.freescale.com)
                                      test = gethostbyname((char *)temp_buffer);
                                      if(test != NULL)
                                            {
                                            // IP address returned from DNS
                                            ulp = (unsigned long *)test->h_addr_list[0);
                                            ipaddr = *ulp;
                                            break;
                                            }
                                      }
 npfree(temp_buffer);
 if(!ipaddr)
 return(EMG_HTTP_CLIENT_CONNECT_ERROR_DNS);
 }
 else
 return(EMG_HTTP_CLIENT_CONNECT_ERROR_ALLOC);
 }
Listato 2 – DNS esempio
Tabella 2 – API DNS Client

Tabella 4 – API DNS Client

Una risposta

  1. Stefano Lovati Stefano Lovati 12 gennaio 2019

Scrivi un commento

EOS