Anda di halaman 1dari 176

Reti di Calcolatori

MODELLI
I sistemi distribuiti sono sistemi nati dallesigenza di soddisfare richieste distribuite con accessi eterogenei. Questi sistemi
devono offrire caratteristiche solide di:
Accessibilit e condivisione di risorse
Affidabilit (dependability) per la tolleranza ai guasti.
o La dependability comunque un attributo generico derivato dalla sintesi dei seguenti attributi di sistema:
Affidabilit (Reliability): capacit del sistema di funzionare ininterrottamente senza guasti.
Manutenibilit (Maintainability): tendenza del sistema a poter essere riparato;
Disponibilit (Availability): capacit del sistema di continuare a funzionare correttamente anche in
presenza di guasti. ( correlata con affidabilit e manutentibilit).
Performanza (Performability): capacit del sistema di offrire i servizi nei tempi prefissati;
Incolumit (Safety): Capacit di non arrecare danni a cose, persone ed ambiente.
Sicurezza (Security) capacit del sistema di fornire confidenzialit (impedire la fuga di informazioni
riservate permettendo accessi solo ad utenti autorizzati) ed integrit (accesso e modifica ai dati da
parte degli utenti esclusivamente nelle modalit previste).
o Le minacce che possono violare la dependability di un sistema sono classificate in: guasti, errori, disastri
(naturali), attacchi (Intrusioni informatiche, vandalismo...)
Uniformit in crescita e Scalabilit: indipendenza in prestazioni dal numero di nodi nel sistema.
o La scalabilit un fattore che in ogni caso non pu essere infinito. Infatti la scalabilit di un sistema si misura
sempre allinterno di un range prefissato che ne assicura luniformit in prestazioni.
Apertura (openness): capacit di evolvere e operare seguendo naturali evoluzioni di specifiche.
Architetture MIMD (Multiple Instruction Multiple Data) un'architettura hardware parallela in cui diverse unit effettuano
diverse elaborazioni su dati diversi con comunicazione attraverso memoria condivisa.
Architetture Software
Per una applicazione distribuita: Analisi, sviluppo tramite algoritmo e
sua codifica in linguaggi di programmazione.
Mapping: Configurazione per larchitettura di destinazione del sistema e
gestione dellallocazione delle risorse.
Binding: il processo tramite cui viene effettuato il collegamento fra
una entit logiche e entit fisiche (o di sistema). Questo processo pu
avvenire in modo STATICO (collegato allinizio e utilizzato) o DINAMICO
(collegamento effettuato solo al momento del bisogno)
Per i sistemi operativi esiste uno standard per le funzioni di accesso
(API) e un modello architetturale.
UNIX: Sistema operativo concentrato che fornisce un modello di
conformit per laccesso ai file, la concorrenza e la comunicazione con
primitive di sistema (kernel) invocabili da diversi ambienti. In tutto questo importante che si stabiliscano degli STANDARD
(anche di fatto) affinch tutti i sistemi siano uniformi e possano facilmente interagire.
Modello dei processi
Processo autocontenuto che contiene
tutto ci che serve alla sua esecuzione.
Non esiste condivisione di dati o variabili
tra diversi processi. Esso contiene uno
spazio di indirizzamento e uno spazio di
esecuzione: parte di supporto per
linterazione con il sistema operativo e
per la comunicazione.
I processi pesanti richiedono molte
risorse (es in UNIX). Il cambiamento di contesto (passaggio da
un processo allaltro) unoperazione molto pesante con
overhead soprattutto per la parte di sistema.

Sono entit pi leggere con limiti


precisi di visibilit e barriere di
condivisione. I processi leggeri sono
attivit che condividono visibilit tra
di loro e sono caratterizzate da uno
stato limitato e producono overhead
limitato. Come contenitore unico di
queste attivit si considera in genere
un processo pesante che fornisce la
visibilit comune a tutti i thread. In Java i processi sono
supportati come processi leggeri allinterno di un unico
processo pesante (la JVM un processo pesante che
contiene i thread mappati in processi leggeri). In UNIX
esistono diverse realizzazioni di processi leggeri ma nessuna
di queste diventata standard.

Il modello CLIENTE / SERVITORE


un modello a due entit: Il cliente che effettua una richiesta e il servitore (o server) che offre il servizio e risponde.
Il modello SINCRONO (ci si aspetta una risposta) BLOCCANTE (attesa della risposta). Questo risolve il problema del rendezvous (per sincronizzare i processi comunicanti) con il server che rappresenta un processo sempre in attesa di richieste di
servizio. Quindi ci si aspetta che il servitore ci sia e questo non viene attivato, ad esempio, alla ricezione del primo messaggio.
Se il servitore non attivo il supporto invia una indicazione di errore al cliente, in tutti gli altri casi il cliente aspetta la risposta.
Il modello di comunicazione 1 a molti (1 Server e N Clienti):
Asimmetrico e dinamico perch il cliente conosce il servitore, solo al momento dellinvocazione e il servitore non
conosce a priori i clienti possibili.
Dinamico perch il binding (collegamento) tra cliente e servitore dinamico (fatto solo quando il cliente fa una
richiesta)
Sincrono perch di prevede risposta dal servitore al cliente
Bloccante perch il cliente aspetta la risposta da parte del servitore
Il modello client/server intrinsecamente molto utile perch molto adatto alla interazione in unambiente distribuito
organizzato su molti nodi con risorse e servizi diversi da fornire.
Il progetto del server pi complesso rispetto al progetto del cliente. Questo perch il server, oltre alla comunicazione, deve
gestire laccesso alle risorse di sistema considerando molteplici clienti e altri problemi come integrit dei dati, accessi
concorrenti, autorizzazione di utenti, autorizzazione allaccesso e privacy delle informazioni. Inoltre il servizio deve essere
sempre pronto alle eventuali richieste ->Server infinito o eterno (processo demone).
Il Cliente, se non arriva la risposta dal server, effettua azioni compensative. Non aspetta per sempre (timeout predeterminato
che porta ad uneccezione locale), pu fare la richiesta ad un altro server o ripetere la richiesta (secondo politiche locali al
cliente). Il server pu non rispondere se guasto (down o crashed) o lento e congestionato da richieste precedenti.
Il modello implica un accoppiamento molto stretto tra le entit interagenti che devono essere presenti insieme per interagire.
Anche se unaccoppiamento forte (strong coupling) come questo potrebbe essere troppo vincolante.
Il Server deve aspettare le richieste che sono messe in coda: prende una richiesta, la serve, d risposta e passa alla successiva
>Ciclo di lavoro sequenziale molto semplificante. Il server deve riconoscere una stessa richiesta e fare un solo servizio e
fornire una sola risposta. Il coordinamento facilitato dalla coda delle richieste e da un supporto dello stato delle richieste.
Il cliente deve identificare in modo unico le richieste. Il server dopo avere fatto loperazione e prodotto il risultato deve
mantenerlo fino alla consegna richiesta dal cliente specifico.
Ci sono anche modellidiversi da quelli di default (sincrono bloccante): modelli verso lasincronia (senza risposta).
PULL: Si semplifica il progetto del servitore e il cliente decide quando fare la richiesta ripetuta, quanto spesso e
quante volte identificando opportunamente le richieste. Il cliente ha sempre liniziativa. Il cliente si occupa del
recupero del risultato con o senza attesa.
PUSH: Il cliente fa la richiesta, una sola volta, si sblocca e pu fare altro. Il server accoda la richiesta, arriva a fare il
servizio e ha la responsabilit di consegna del risultato al cliente. Il modello push fa diventare il servercliente di ogni
cliente. Carica di ulteriori compiti il servitore. Questo modello molto usato per ampliare la fascia di utenza.
Modelli a delegazione
Possibilit di delegare una funzionalit ad unentit che opera al posto
del responsabile e lo libera di un compito. Entit Proxy, Delegate,
Agenti, Attori che svolgono una funzione al posto di qualcun altro. I
proxy, solitamente, sono locali al cliente. Richiesta sincrona bloccante
su un proxy -> Server libero. Questo permette di avere
uninterazionesincrona non bloccante. La notifica avviene mediante
eventi che si interpongono tra utenti e basso livello e permettono una
gestione applicativa del sistema isolando i dettagli.
Modello a Framework
Modello che prevede richieste sincrone a kernel. Il framework tende a rovesciare il controllo (per eventi di sistema). Il
processo utente non aspetta, ma registra con una propria funzione. Esempio: in Windows nei processi previsto un loop di
attesa di eventi da smistare ai richiedenti. Allarrivo di un risultato questo viene portato al processo significativo. Le risposte
dal framework al processo utente sono dette backcall o upcall(push del framework). Questi sono assimilabili a eventi
asincroni generati dal supporto che le applicazioni devono gestire.

Modello Publish/Subscribe
Modello molti a molti. In caso di iniziativa mista, e necessario che
gli interessati manifestino interesse alle informazioni attraverso una
registrazione (subscribe) e poi si ricevono tutte le informazioni
generate (publish).
Rappresenta un modello push a tre untit:
1. Gli utenti (subscriber o consumatori) che si registrano
come interesse (subscribe).
2. Un gestore (servitore di notifica) che registra gli interessi,
riceve la notizia degli eventi generati e notifica ai consumatori
sottoscrittori.
3. I produttori che generano gli eventi e fanno publish.

Modello ad eventi
Il modello ad eventi asincrono e fortemente disaccoppiato: prevede di avere molti produttori, molti consumatori, e ad
assumere lesistenza di un supporto. In questo modo si gestisce linvio di messaggi disaccoppiando gli interessati.
I produttori segnalano.
I consumatori ricevono dopo sottoscrizione (pub/sub),
il gestore degli eventi segnala loccorrenza degli eventi e i relativi messaggi agli interessati sottoscrittori (push dei
messaggi).
Confronto C/S con Scambio di messaggi
Client/Server
o Modello a accoppiamento forte (strong coupling) che implica la compresenza di entrambe le entit
interagenti.
o Meccanismo molto adatto per comunicazioni di alto livello e semplici per uso applicativo e utente.
o Non cos flessibili per situazioni diverse e specifiche (impossibilit di MX e BX)

Eventi, PUB/SUB e Scambio di messaggi Sender/receiver


o Modello a scarso (minimo) accoppiamento (loosecoupling) che non impone la compresenza delle entit
interagenti.
o Molto flessibile, primitivo ed espressivo, ma non facile da usare.
o Molto a basso livello (e adatto per ogni possibile uso del sistema), si permettono molti diversi usi eterogenei
del sistema.
o Supporto ad ogni possibile tipo di comunicazione (anche BX e MX)

Connessione nel C/S


Nella interazione C/S si considerano due tipi principali riguardo allinsieme delle richieste:
Interazione connection-oriented(con connessione)
o Si stabilisce un canale di comunicazione virtuale prima di iniziare lo scambio di dati
o Tutti i messaggi seguono la stessa strada (route) per la coppia mittente destinatario decise staticamente e
impegnano risorse intermedie.
o Alcuni modelli a connessione (TCP basato su IP) non impegnano risorse intermedie ma solo mittente
destinatario
Interazione connectionless (senza connessione)
o Senza connessione virtuale, ma semplice scambio di messaggi isolati tra loro
o I messaggi possono seguire strade diverse decise dinamicamente e non impegnano risorse intermedie.
La scelta dipende dal tipo di applicazione e anche da vincoli imposti dal livello di comunicazione sottostante.
Per esempio, in internet il livello di trasporto prevede protocolli TCP e UDP basati su IP (tipicamente connectionless e best
effort):
UDP senza connessione, non reliable e non preserva lordine dei messaggi
TCP con connessione, reliable (affidabile) e preserva lordine di invio dei messaggi e a maggiore affidabilit

Visibilit
Nella comunicazione importante se si possa essere in visibilit di tutti i potenziali partecipanti (scalabilit).
Modelli locali(o ristretti) prevedono limiti alla interazione
o Operazioni Scalabili poco dipendenti dal diametro del sistema
Modelli globali Non impongono restrizioni alle interazioni
o Operazioni non scalabili dipendenti dal diametro del sistema
Si va verso la localit, vincoli, domini per ottenere scalabilit.
Stato
In una interazione C/S un aspetto centrale lo stato delle richieste contro lautocontenimento delle richieste. Lo stato
dellinterazione viene usualmente memorizzato nel Server che pu essere
Stateless non tiene traccia dello stato: ogni messaggio completamente indipendente dagli altri e autocontenuto.
o pi leggero e pi affidabile in presenza di malfunzionamenti (soprattutto causati dalla rete)
o Fornisce API pi complete e complesse perch, essendo i messaggi auto contenuti, c bisogno di essere pi
specifici
o Porta ad un progetto del cliente pi complesso ma semplificano il progetto del Server
o Una interazione stateless sensata e possibile SOLO se il protocollo progettato per operazioni
idempotenti: operazioni che tendono a produrre lo stesso risultato anche se ripetute (a meno che non cambi
lo stato del server stesso)
Stateful si mantiene lo stato dellinterazione tra chi interagisce un messaggio con loperazione conseguente pu
dipendere da quelli precedenti
o Garantisce efficienza: dimensioni messaggi pi contenute e migliore velocit di risposta del Server
o API pi semplici
o Un Server stateful deve sicuramente presentare un impegno di risorse ulteriore per identificare la sessione
del Client e tenerne traccia per le interazioni future.
o Il vantaggio di avere minore costo delle operazioni in termini di banda impegnata, sicurezza e garanzie di
ripristino in caso di problemi dei clienti.
o Lo stato si distingue in:
Stato permanente mantenuto per sempre
Stato soft o a tempo
Progetto del Servitore
Modelli di servizio

Servitore sequenziale o iterativo si possono introdurre ritardi se


la coda di richieste cresce
o Serve una richiesta alla volta e itera il servizio
o Per limitare overhead: limitare la lunghezza della coda
(sveltendo il servizio), rifiutare le richieste a coda piena (rifiutando il
servizio)

Servitore concorrente capacit di servire pi richieste insieme sfruttando i tempi morti


o Serve molte richieste insieme e pu ottimizzare luso della risorsa processore eliminando i tempi di idle.
o Un servitore concorrente pu essere
multiprocesso un processo server che si occupa della coda delle richieste e genera i processi figli >
uno per ogni servizio)
monoprocesso unico processo server si divide tra il servizio della coda delle richieste e le operazioni
vere e proprie.

Servitore con stato interazione il servitore tiene traccia dellinterazione con i clienti
Servitore senza stato interazione il servitore dimentica le richieste appena le ha eseguite
Servitore con connessione le richieste arrivano in ordine di emissione del cliente
Servitore senza connessione ogni richiesta arriva in modo indipendente (senza ordine)

Progetto del C/S


Schema di base: asimmetrico, sincrono, bloccante
Progetto dei Clienti pi semplice. Spesso sono sequenziali, potrebbero essere anche concorrenti.
Progetto dei Servitori pi complesso per la operazione svolta dal server stesso e dai molteplici clienti (molti a 1). Un
server deve essere sempre presente al momento delle richieste dei clienti. Processi demoni che rimangono attivi per
tutta la durata del sistema. Demoni -> eseguono un ciclo infinito di attesa di richiesta e esecuzione delle stesse
(sequenziali ma spesso concorrenti). In Java thread Daemon rispetto a un thread comune (user) esegue per tutta la
durata di una sessione della JVM terminandone lesecuzione solo quando termina lultimo thread user
Modello ad agenti multipli

Schema in cui i servizi sono forniti dal coordinamento di pi servitori detti agenti che forniscono un servizio globale unico. Gli
agenti forniscono il servizio coordinato e possono partizionare le capacit di servizio o replicare le funzionalit del servizio,
tutto in modo trasparente al cliente.
Vi possono esser anche modelli a livelli multipli per la divisione dei compiti:
Clienti che interagiscono con Agenti
Agenti, anche paralleli, capaci di coordinarsi
Server di operazione paralleli, replicati e coordinati
Con necessit di protocolli di coordinamento, sincronizzazione, rilevazione e tolleranza ai guasti.
Sistemi di Nomi
Nella relazione C/S, il cliente deve riferire il servitore. Questo reso possibile dal nome del servitore nel cliente. I clienti
possono usare molte forme di nomi diversi:
nomeGestore.nomeServizio
123:123456 (non trasparente)
nomeServizio
stampa (trasparente) (binding dinamico)
Esistono nomi Trasparenti e Non Trasparenti alla allocazione. La trasparenza non lega il nome a dettagli di basso livello.
I nomi, ossia i riferimenti ad altre entit, sono distribuiti nel codice dei clienti, degli utilizzatori, delle librerie ecc. e se ne deve
garantire la consistenza.
Per la risoluzione dei riferimenti e la qualifica dei nomi si effettua unoperazione di binding:
Statico i riferimenti sono risolti prima dellesecuzione.
o Tipico di sistemi concentrati, si risolve tutto staticamente e non si necessita di un servizio di nomi
considerata linvarianza dei nomi e della allocazione delle entit
o Non consentito cambiare alcuna allocazione (problemi)
Dinamico i riferimenti sono risolti solo al momento del bisogno e durante lesecuzione.
o Tipico in sistemi distribuiti in cui le risorse sono dinamiche e non prevedibili staticamente.
o I sistemi di nomi sono presenti durante lesecuzione per effettuare il binding.
o Le entit non sono staticamente fissate
o Nasce la necessit di un servizio di nomi (name server -> Agente) che mantiene e risolve i nomi e che
fornisce il servizio durante la esecuzione coordinandosi con i gestori della allocazione
o Tipicamente si usano delle tabelle di allocazione controllare da opportuni gestori di nomi
I nomi possono essere a loro volta non trasparenti (dipendenti dalla locazione) o trasparenti (non dipendenti dalla locazione).
I nomi trasparenti permettono ad un entit di cambiare allocazione senza cambiare nome.
In sistemi aperti tipicamente si devono introdurre molteplici gestori di nomi distinti e coordinarne lesecuzione.
Partizionamento dei gestori ciascuno responsabile di una sola parte dei riferimenti e localit.
Replicazione dei gestori ciascuno responsabile con altri di una parte (partizione) dei riferimenti e coordinamento.
I gestori sono spesso organizzati a livelli: un gestore generale che coordina gestori di pi basso livello in molti livelli con localit
di informazioni. Questo li rende pi efficienti per la localit e meno efficienti per sistemi pi lontani ma un prezzo che si
disposti a pagare a vantaggio dellefficienza dellintero sistema.

DNS (Domain Name System)


Insieme di gestori di tabella di nomi logici host e indirizzi IP
corrispondenti. DNS organizza i nomi logici in una gerarchia (albero
DNS) intesa come gerarchia di domini logici e centri di servizio. La
corrispondenza tra nomi logici e indirizzi fisici avviene
dinamicamente tramite un servizio di nomi che risponde
(dinamicamente) alle richieste.
Ogni nome diviso in parti che rappresentano domini diversi
(server), i domini di base (di primo livello) sono ad esempio: IT,
COM, EDU, GOV ecc.

Es. deis33.deis.unibo.it
Riferisce ad un dominio nazionale italiano. a 4 livelli. Il numero di livelli dinamico (non standardizzato).
Ogni nome permette dei mappaggi logici propri. I singoli nomi sono case sensitive e al massimo 63 caratteri per dominio.
Nome completo massimo 255 caratteri. I domini sono del tutto logici e non sono collegati in nessun modo alle reti fisiche o
alle organizzazioni di rete. Ogni dominio pu essere usato in modo relativo o assoluto. Ogni dominio relativo fa riferimento al
dominio che lo contiene.
Architettura del DNS
Ogni nome di dominio corrisponde ad un server di responsabilit. I domini sono organizzati su responsabilit primaria di un
server (detto ZONA > 1 o pi server). Ogni zona riconosce una autorit, ossia un server che fornisce le corrette
corrispondenze e garantisce caratteristiche specifiche come, ad esempio, replicazione. I diversi servitori che gestiscono domini
suddivisi on zone possono a loro volta delegare la gestione ad altri server con sottodomini e servitori sottostanti. Le richieste
sono smistate dal sistema in modo opportuno.
Ogni richiesta di utente viene fatta al servizio di nomi in modo
indiretto tramite un agente specifico (Name Resolver) per la
gestione dei nomi della localit. (Caching)
I diversi server DNS sono organizzati per ottenere diversi requisiti:
affidabilit, efficienza e localit. Ogni dominio ha un Name
Resolver e domain name server locali (un o pi in replicazione) e
usa estensivamente cache per conoscenze pregresse.
Il resolver fornisce la risposta o perch conosce gi la corrispondenza (in cache) o la trova attraverso una richiesta
C/S ad un name server.
I DNS name server sono organizzati come agenti per ottenere informazioni reciprocamente (dalla pi corretta
autorit) e poter fornire a loro volta risposte consultando le rispettive tabelle DNS
Lorganizzazione ad albero consente di muoversi tra i DNS con le richieste necessarie fino a raggiungere il dominio di
autorit.
I diversi DNS sfruttano la replicazione per fornire la risposta anche in cado di problemi (Affidabilit).
Clienti e Resolver (anche fra diversi DNS) fanno richieste usando il protocollo UDP (porte 53). In caso di messaggi troppo
lunghi (>64k) allora si usa TCP. Viene usato TCP per laggiornamento dei secondari.
Query DNS:
Ricorsiva
o Richiede al resolver (o DNS) che fornisca la risposta (chiedendo ad altri) o segnali un errore.
o Si prevede una catena di server request/reply
o Il resolver o DNS rimane impegnato fino a risposta o timeout
Iterativa
o Richiede al resolver (o DNS) che fornisca la risposta o il migliore suggerimento come riferimento al miglior
DNS server
o Si prevede una sequenza di server request/reply a server
o Risponde con un riferimento al gestore pi vicino che possa ragionevolmente rispondere

OSI
Open System Interconnection stabilisce standard di comunicazione tra sistemi aperti con lobiettivo di realizzare interoperabilit tra
sistemi eterogenei. uno standard di comitato, di gestione, non operativo: non fornisce realizzazioni. Gestione dei sistemi: definisce
come si possono controllare, coordinare, monitorare sistemi interconnessi eterogenei. Quindi non definire come avviene la
comunicazione ma come gestire il sistema interconnesso.
uno standard: organizzato a livelli precisi, ad oggetti, come scenario generale di soluzione, senza legami con le realizzazioni.

Livelli
Ci sono 7 livelli. Ogni sistema a livelli, come OSI, si basa sul principio di separazione dei compiti (delega) e della trasparenza della
realizzazione (astrazione).

Ogni livello fornisce al livello superiore uninterfaccia o servizio (visione verticale):


Definizione del servizio: definizione astratta dei servizi del livello corrente disponibili al livello immediatamente superiore.
Ogni livello ha lobiettivo di comunicare con il livello corrispondente e di gestirlo.
Questo viene realizzato tramite un protocollo (visione orizzontale):
Specifica del protocollo: specifica dettagliata di come il livello fornisce il servizio tramite scambio di dati ed informazioni tra le
due realizzazioni dei sistemi comunicanti.
OSI introduce un sistema di nomi molto preciso per i servizi e i protocolli.

SAP
Service Access Point o (N)-SAP: una interfaccia logica tra una (N-1)-entity ed una (N)-entity. Quando un livello ha bisogno di
comunicare con un altro il SAP si occupa di gestire le richieste tra i livelli. Quindi per chiedere
qualcosa ad un particolare livello si deve far riferimento alla SAP relativa al livello
corrispondente. Esempio: se voglio chiedere qualcosa al livello di trasporto (T, Layer 4) devo
chiederlo alla SAP corrispondente (T-SAP) che fornir la risposta.
Ogni SAP ha un nome unico che la identifica. Per identificare unentit (es di Layer 6) si
dovrebbero nominare tutti i SAP di ogni livello (fino all1). In questo caso ci si ferma ai nomi di
rete (Layer 3 Network). Una entit (pari) viene quindi identificato come SAP di rete e con la
sequenza di stack dei nomi delle entit per identificare il livello superiore (IP, porte, socket,
processo ecc.)
> Si specifica in modo non ambiguo ogni partecipante.
Dimostrazione del fatto che OSI non legato alle implementazioni.
Lorganizzazione a SAP completamente astratta e potrebbe essere applicata alla modellazione di sistemi molto diversi.

Comunicazione
In genere per una comunicazione si hanno un mittente, un destinatario e degli intermediari. In OSI gli intermediari sono fissi e devono
partecipare alla comunicazione intesa come risorse per mantenerla.
Standardizzazione dei messaggi -> descrizione i messaggi che permettono:
Chiedere il servizio SDU (Service Data Unit o Interface Data Unit, IDU)
Specificare il protocollo PDU (Protocol Data Unit)
Le informazioni che vanno verso il basso sono incapsulate e devono poi essere trattate
dal protocollo.
Linterfaccia con il livello sottostante IDU contiene anche la parte di specifica di
protocollo: ICI (Interface Control Information) coordina operazioni, determinando il
protocollo e definendo il PCI (Protocol Control Information).
PDU fornito dal protocollo diventa SDU (Service e Interface) per il livello sottostante.

Su iniziativa del mittente ogni livello introduce le proprie esigenze specifiche


(header -> PDU) a quelle del dato e le passa al SAP sottostante, fino al
livello fisico, dopo il quale, dalla parte del destinatario si ricomincia a risalire
fino allApplication corrispondente rimuovendo man mano gli header ad ogni
livello di competenza. C molto overhead relativo allinclusione di tutti
questi dati aggiuntivi utili a realizzare e gestire la comunicazione. Livello di
intrusione di un protocollo = quanto snelli sono gli header.

Modalit

Connectionless: Ogni unit di dati trasferita in modo indipendente dalle altre unit ed autocontenuta (senza ordine)
Nessuna qualit di servizio. Lo scambio di informazioni tra due pari avviene senza storia e senza concetto di negoziazione.
Soluzione a basso costo
o Adatta per dati occasionali e senza qualit della comunicazione. Costo limitato ma scarse garanzie.
Connection-Oriented: Soluzione privilegiata da OSI. Si stabilisce una connessione tra entit pari che devono comunicare, con
caratteristiche della connessione negoziate nella fase iniziale. Oltre a mittente e destinatario, quindi, si interpone una terza
entit che la connessione. La comunicazione avviene tutta nellambito di una sessione di comunicazione che eretta dalla
connessione. Negoziazione iniziale per stabilire regole ben precise sulla comunicazione per la qualit.
o Comunicazione in tre fasi: Apertura, Trasferimento dati, Chiusura
o Il servizio di un livello deve fornire anche opportune funzionalit per le tre fasi con qualit di servizio.
In OSI > Garanzia piena per la connessione: OSI garantisce che gli intermediari ci sono e ognuno di essi garantisce
banda e QoS.
o La comunicazione pu avere luogo in modo bidirezionale sulla connessione.
o Su una connessione costi pi elevati ma maggiori garanzie

Primitive
Le due entit pari cooperano per implementare le funzionalit del livello cui appartengono.
Primitive base: DATA per trasmettere contenuto, CONNECT, DISCONNECT per aprire e chiudere una connessione.
Quattro possibili forme per una primitiva:
1. Request il service user richiede un servizio (una azione)
2. Indication il service provider indica al service user che stato richiesto un servizio (segnalazione di evento)
3. Response il service user specifica la risposta alla richiesta di servizio (una azione)
4. Confirm il service provider segnala la risposta alla richiesta di servizio (segnalazione di evento)

Asincrona Bloccante:
Mittente invia con una Request, arriva al destinatario con
una Indication per c un blocco locale di Confirm che dice
che le cose sono state spedite dallaltra parte.
Tipica sequenza con connessione:
o CONNECT apertura della connessione con negoziazione (tipicamente sincrona, tutte e 4 le forme)
o molte DATA invio dati
o DATA.request - Invio dati
o DATA.indication - Segnala dati con la qualit della connessione
o DISCONNECT chiusura della connessione
OSI tipicamente con QoS e impegno intermedi
TCP/IP solo best effort e impegno solo endpoint

OSI Livello Network


Tiene conto dei nodi intermedi tra due pari. Il livello di network si occupa delle diverse realizzazioni di routing tra reti diverse oltre a
definire il sistema di nomi delle entit.
Obiettivo: passaggio delle informazioni interferendo meno possibile sul comportamento locale
Compiti del Livello di Rete
Indirizzamento (vedi nomi di IP)
Controllo di flusso tra due pari
Controllo di congestione nel sistema intero
Obiettivi: migliorare efficienza ed evitare ingiustizia, deadlock
Principio di separazione: i nodi intermedi devono potere interagire solo per le funzionalit necessarie e non essere toccati ai livelli
applicativi.
Nei nodi intermedi di una comunicazione abbiamo solo i livelli fisici -> fino al livello di Rete.

OSI Livello Trasporto


il Trasporto comincia a considerare la struttura dei nodi partecipanti, in particolare gli endpoint. Livello end-to-end per separare i
livelli relativi alla comunicazione da quelli pi vicini allapplicazione.
Obiettivo: spedizione di dati sul canale di connessione con correttezza, con certi tempi di risposta, e con una certa qualit di servizio, su
richieste dal livello di Sessione superiore.
In OSI, dal Trasporto in su, tutto con connessione -> Modalit connection-oriented. Ci possono essere anche modalit non connesse
(es Internet). Interazioni con apertura e terminazione (CONNECT e DISCONNECT) della connessione e trasferimento di dati (normali o
privilegiati con la primitiva DATA.
Ogni livello ha le proprie entit e SAP.
Se focalizziamo solo T e N, un nodo potrebbe avere molte SAP di trasporto e una sola di rete: in questo caso le applicazioni devono
specificare quali enti sono coinvolti per ogni comunicazione.
Il trasporto pu spezzare il dato e ricomporlo dopo averlo portato suddiviso fino al pari Il trasporto pu lavorare unendo o
decomponendo flussi di trasporto rispetto a quelli di rete (Multiplexing). Pu essere fatto verso lalto e verso il basso.

Primitive Livello di Trasporto


T-CONNECT
T-DATA
T-EXPEDITED-DATA
T-DISCONNECT

Servizio confermato
(sincrono)
Servizio non confermato
(asincrono)
Servizio non confermato
(asincrono)
Servizio non confermato
(asincrono)

Indirizzo del chiamante e del chiamato, opzione per luso di dati privilegiati, qualit
di servizio e dati dutente (4 primitive)
Dati di utente (normali).
Dati di utente. Dati che devono essere consegnati in modo preferenziale (urgenti).
Ragione della terminazione, Dati di utente.

OSI Livello Sessione


La sessione si occupa del controllo del dialogo: nei sistemi con sessione posso strutturare il dialogo in modo molto
Dialogo fatto di attivit. Le attivit sono separate e indipendenti (se fallisce/termina una non influenza in nessun modo le altre)
(Processi) nellambito della stessa connessione tra due entit.
In Internet il livello di Sessione assolutamente vuoto (tutto in mano al programmatore). Socket non hanno sessione in accordo con
OSI. Nella sessione il dialogo pu essere bidirezionale, molteplice (strutturato in attivit separate e diverse), considerare le risorse
impegnate e avere garanzie di correttezza e affidabilit.

Primitive Livello di Sessione


Nella sessione coordina il dialogo basandosi sul servizio offerto organizzato in unit funzionali. Ognuna legata da un insieme di primitive
e parametri. Le primitive sono 58 raggruppate in 14 unit funzionali. Uso di connessione, con QoS negoziata, e semantica pi
complessa. Il dialogo strutturato attraverso azioni di controllo, attivit, eccezioni.
Il livello di Sessione fornisce servizi analoghi a quelli del livello di Trasporto, e ogni livello:
Apertura e Chiusura della connessione
Trasferimento dati, fino a 4 tipi di dato
Gestione dellinterazione, modalit dialogo half-duplex, full-duplex o simplex

Sincronizzazione, inserimento dei punti di sincronizzazione e gestione delle eccezioni.

Mittente
S-CONNECT
S-DATA

SYNC ->

Ricevente

Con SYNC (sincrona) se fallisce la connessione linterazione non riparte dallinizio ma da questo punto di
sincronizzazione. Richiede allaltro di ricevere tutti i dati e garantire successivamente di confermare la
S-DATA

ricezione dei dati (S-DATA asincrona).


Esistono due tipi di punti di sincronizzazione:
1. Punti di sincronizzazione maggiore il mittente attende (modo sincrono bloccante) che il ricevente confermi. (Attesa)
2. Punti di sincronizzazione minore (invio con conferma o meno), il mittente pu continuare a spedire dati o punti di
sincronizzazione. Il mittente non deve segnalare la ricezione di un punto minore e la conferma di un punto minore conferma
anche tutti i punti precedenti (Accumulo e poi Attesa)
a. Sono gestiti a finestra, rappresentano una modalit di sincronizzazione differita e non immediata. Si definisce una
finestra che rappresenta il numero massimo di punti di sincronizzazione non confermati che si possono avere
pendenti. Quando una finestra si riempie -> Attesa di conferma. Ad ogni conferma la finestra scorre (sliding window)
I punti di sincronizzazione di un dialogo possono essere usati nel recovery per ritrovare uno stato significativo. Strategie diverse:
abbandono, ripristino, ripristino diretto dallutente.
Punti maggiori e minori possono coesistere nella stessa connessione rendendo molto articolato il dialogo.
Le connessioni tipicamente sono bidirezionali. In alcuni momenti per solo una delle due entit connesse gestisce certe attivit.
La primitiva S-CONNECT per stabilire la connessione permette di negoziare anche i token che rappresenta unautorizzazione per
effettuare una certa operazione (es Sync) ad esempio, l'utente che richiede la connessione e l'utente che la accetta indicano i servizi da
implementare. L'intersezione dei due insiemi di requisiti determina la S-connessione. Vari tipi di token distinti come diritto di:
data token: spedire i dati in Half Duplex
release token: richiedere la terminazione
synchronize minor token: creare punto di sincronizzazione minore
synchronize major token: creare punti maggiori

OSI Livello di Presentazione


Il livello di presentazione il livello che si occupa di gestire la rappresentazione dei dati. In sistemi eterogenei assolutamente
necessario gestire la rappresentazione dei dati. Ad esempio nelle Socket: htonl e ntohl (Internet big-endian).
Necessit di codifiche diverse:
Differenze naturali tra i sistemi che comunicano
Migliorare la comunicazione (efficienza e sicurezza) (Compressione e criptazione)
I dati devono essere scambiati dopo un accordo tra i pari che superi i problemi di eterogeneit.
In OSI si prevede una fase statica iniziale di accordo tra le parti per definire i tipi di dati e di connessioni. Ma, in OSI, questo si pu fare
anche in modo dinamico, durante lesecuzione.

In caso di N nodi eterogenei nel primo caso le funzioni di conversione sono N*(N-1) nel secondo sono N verso ed N per il formato
comune. Si usa sempre e solo la seconda. Solo trasformazioni dallo standard definito al nodo e viceversa. Differenza: Invece di una
trasformazione se ne fanno due. In questo modo, ogni nodo, conosce solo la sua trasformazione e quella standard e questo facilita
anche laggiunta di altri nodi nel sistema. Per scalabilit.

Dati e Formati
Tipicamente in una comunicazione vengono scambiati dati. La comunicazione pu introdurre errori e corrompere un dato inviato.
Vengono introdotte delle ridondanze per verificare che il dato ricevuto non sia stato corrotto. Quindi si possono inviare informazioni
aggiuntive (descrizioni) che qualificano il dato inviato -> Impegno di banda maggiore per avere affidabilit.
Per il formato dei dati ci sono due tipi di approccio utilizzabili:
Statico: i due nodi che comunicano hanno gi scritto al loro interno il tipo di dati che verranno scambiati.
Buono per sistemi piccoli. Tempo di vita breve.
Dinamico: Trasferimento di informazioni sul tipo di dati non note a tempo di progetto. Accordo da stabilire durante
lesecuzione. OSI descrive anche come (fasi) deve avvenire laccordo (descrizione astratta dellaccordo). Astratta perch
vengono descritti i dati in modo astratto.
Indicato per sistemi grandi e eterogenei. Tempo di vita lungo.

Accordo Trasformazioni e Ridondanza


Possiamo usare diversi gradi di ridondanza a secondo del costo associato alla comunicazione (impegno di banda)
I dati possono essere:
valore
lunghezza del valore, valore
tipo, lunghezza campo valore, valore
Se non c un accordo bisogna stabilirlo attraverso un linguaggio comune e standard per laccordo.
Molto spesso i linguaggi astratti, nel livello di presentazione, prevedono molte fasi di negoziazione non prevedibili poich non si pu
sapere a priori il numero preciso di stack di rappresentazioni del singolo nodo. I protocolli del livello di presentazione sono molto
complessi. API molto numerose divise in unit funzionali. Necessit di accordarsi e definire:
Contesto di comunicazione (magazzino)
Soggetto della comunicazione (scorte del magazzino)
Semantica delle informazioni (dominio comune di cui vogliamo parlare)
Informazioni vere e proprie (dati relativi)

Protocolli di Negoziazione
Protocolli multifase -> numero di informazioni scambiate molto maggiore rispetto ad una interazione cliente/servitore.
BIDDING (asta, offerta) (Contract Net) tra sender e receiver si prevedono molte fasi (almeno 5 anche ripetute).
stato definito per il settore dellIA, di livello applicativo, molto costoso, usato per sistemi ampi in cui si vuole raggiungere una risorsa
che pu essere offerta da pi contraenti nel sistema.
1. Sender fa un broadcast della propria esigenza (ANNOUNCE)
2. Receiver fanno un'offerta (BID). Contiene anche QoS.
3. Sender sceglie tra i bid dei receiver. (AWARD). Manda un messaggio al contraente.
4. Receiver accoglie l'ok definitivo (contract).
5. Accordo
Se il receiver occupato: alla fase 4, il receiver pu rifiutare e si riparte da 3 (o da 1). Soluzione molto flessibile ma costosa e non
ottimale. Nel distribuito non ottimo perch si potrebbe mancare unofferta migliore (che viene dopo ad esempio).

BER e ASN.1
OSI per il livello di presentazione definisce due standard:
Un linguaggio astratto di specifica (parte astratta accordo)
o ASN.1 (Abstract Syntax Notation)
Linguaggio usato in modo astratto per descrivere le funzioni di
accordo fra entit che non si sono accordate in modo statico.
Non descrive solo i dati ma anche possibile descrivere in modo
non ambiguo le informazioni che servono per stabilire il contesto,
il soggetto, la semantica di comunicazione.
Usato raramente (in caso di bisogno) in casi in cui deve essere
fatto un accordo in modo dinamico.
Si pu descrivere, e quindi comunicare, anche del codice.

Un linguaggio concreto di descrizione dei dati (parte concreta accordo)


o BER (Basic Encoding Rules):
Regole di codifica della rappresentazione standard che viene
scambiata tra un nodo ed un altro. Usato sempre perch
fornisce la descrizione dei dati veri e propri. Ogni dato deve
viaggiare con una tripla (Tag-Length-Value, tipo-lunghezzavalore).
In questo modo viene introdotto molto overhead a vantaggio
della affidabilit. In internet, ad esempio, viene inviata solo la
parte di value (best-effort).
Formato standard da cui ricevono/attraverso cui vengono
scambiati i messaggi

OSI Livello di Applicazione


Il livello di Applicazione il livello che si interfaccia con l'utente finale della comunicazione in base al modello OSI. Obiettivo Astrazione
nascondere la complessit dei livelli sottostanti coordinando il dialogo tra le applicazioni distribuite.
Il livello applicativo OSI standard definisce un insieme di servizi indipendenti dal sistema e li fornisce a programmi di utente o ad
utenti - diversi servizi ed ambienti standard (ISO 9545):
Message Handling System MHS (es email)
Directory service X.500
System Management X.700
Common Management Information Service & Protocol CMISE & CMIP
File Transfer, Access and Management FTAM (anche per file molto complessi in termini di struttura)
Virtual Terminal Standard VT (es telnet)
Distributed Transaction Processing DTP
OSI adotta un approccio particolare basato sul modello ad Oggetti per la specifica delle applicazioni. Uso di template e package per
definire gli oggetti. Pura ereditariet statica tra astrazioni. Oggetti da manipolare come interfaccia ed espressi attraverso l'uso di
package (anche condizionali). Unicit dei nomi necessaria come presupposto di base per laccordo e il coordinamento.
NOMI UNICI come servizio (X.500).
La struttura delle applicazioni OSI a livelli. Alla base dei servizi forniti dal livello di applicazione ci sono un po di strumenti:
ACSE (Association Control Service Element) di base per ogni servizio
RTSE (Reliable Transfer Service Element) per ottenere servizi affidabili
ROSE (Remote Operation Service Element) per operazioni remote
CCR (Commitment Concurrency and Recovery) per azioni multiple coordinate
Servizi X.500 (Directory)
Il servizio di direttorio consente di collocare e classificare ogni entit di interesse (ogni dispositivo noto) in base al contenuto degli
attributi in un sistema gerarchico (ad albero) di conoscenza, molto accessibile (24/7). Spesso si riferisce una entit attraverso il suo
identificatore specificato come sequenza di decisioni e scelte (1.3.6.1.2.1.4)
Il sottoalbero per la descrizione del protocollo IP per gestione Negli altri casi, si negoziano le propriet con ASN.1.

Reti e Routing
Reti
Le reti permettono ed attuano le interconnessione tra i diversi sistemi di calcolo. Le reti sono il mezzo di interconnessione punto a
punto o via comunicazioni globali che coordinano molte entit.
La rete misurata dal costo, velocit ed affidabilit di invio dei messaggi, nellintero percorso da dove provengono a dove devono
essere consegnati.
Le reti si possono misurare in molti modi e secondo molte metriche.
Le reti come mezzo di interconnessione punto a punto o via interconnessioni di molte entit (es multicast e broadcast)
Parametri:
Tempo di latenza (tempo di ritardo sulla comunicazione)
Banda (quantit di dati trasmessi per unit di tempo)
Connettivit (tipo di interconnessione e topologia)
Costo apparati
Reliability (affidabilit) (percorsi ridondanti)
Funzionalit (ad esempio, attraverso operazioni sui messaggi come combinazione e frammentazione dei messaggi e
ricomposizione)

Topologie
Le reti possono adottare molte topologie, o statiche (reti dirette) o dinamiche (reti indirette).
Le reti dirette statiche prevedono architetture non variabili, fissate, definite, e regolari di interconnessione.
Bus: (ethernet CSMA/CD) tutti trasmettono nello stesso
canale comune. Problema: molto traffico -> Molte
collisioni -> Operativit limitata.
Bus (dinamico): interconnessione di tutti i nodi
attraverso un unico mezzo di interconnessione -> bus
dinamico unico. Va usato bene in accesso considerato
che il mezzo condiviso. Se un nodo sta comunicando
gli altri attendono.
Mesh: Ogni nodo ha un numero di vicini. Le connessioni
verso un altro nodo sono molteplici -> in caso di guasto
posso comunque comunicare.
Queste topologie vengono realizzate in reti relativamente piccole per ottenere qualit di servizio.
Ipercubo una topologia regolare che prevede un grado di connettivit crescente.
Molte architetture parallele usano questa topologia
perch consente di avere tempi di latenza molto bassi visto che il numero di link per
nodo abbastanza elevato. In un ipercubo di dimensione 4 ogni nodo ha 4 link per
comunicare con gli altri nodi -> il numero di link pari alla dimensione del cubo ->
Problema del Costo di interconnessione.
Interconnessione Completa: interconnettere tutti con tutti. Con n elementi, n^2 connessioni con il costo conseguente di una serie di
switch hardware.

Switching
Linterconnessione di diverse entit deve ottimizzare luso delle risorse e metterle a disposizione in modo dinamico di chi manifesta la
necessit di uso. Lo switching permette di dedicare le risorse a pi richieste in tempi diversi e non mantenerle allocate ad un unico
obiettivo di connessione. Lo switching permette di prevedere un impegno anche condiviso delle risorse per consentire di passare i dati
in caso di nodi non in visibilit in modi diversi. Nel caso di messaggi diversi, possono essere frammentati in pezzi corti che possono
viaggiare insieme su tratte di reti disponibili.
Nelle reti si fa Switch di Pacchetto che pu avvenire attraverso canali creati dinamicamente (circuiti virtuali) cio risorse dedicate nei
nodi intermedi o essere del tutto libero senza stabilire connessioni di alcun tipo (usando frammentazione in datagrammi)

Reti Omega Reti basate su una sequenza di switch binari che, con un costo pi basso, permettono di ottenere lo stesso effetto di una
matrice di switch. Reti a stage che interconnettono p elementi, con log2(p) stage; ogni stage ha p input e p output.
Comandando gli stage composti da switch binari, si ottengono dinamicamente le potenziali interconnessioni desiderate
Switch di Circuito Ossia avere canali dedicati (o connessioni statiche) predeterminati e mantenuti anche se non usati -> A priori,
staticamente, conosco il cammino che congiunge mittente e destinatario di una comunicazione. Questo modo di lavorare non mai
utilizzato in internet, ma in OSI s, dove bisogna garantire ad esempio la banda durante il cammino -> Qualit.
Molto spesso vengono realizzati circuiti virtuali. Permettono la condivisione delle risorse per ottenere un migliore uso del sistema di
comunicazione.
Sia circuiti dedicati che virtuali non sono attuabili in TCP/IP -> solo switch di datagrammi
Switch di datagrammi Nessun circuito o canale, ma solo datagrammi, unit di trasmissione, che possono essere mandate tra nodi vicini
(politica ottimista) mirando ad ottenere il migliore uso del sistema di comunicazione
Comunicazione a datagrammi (tecnica ottimista): Con i datagrammi, non si garantisce nessuna connessione end-to-end, e quindi nessun
controllo flusso, nessuna garanzia (no ordine, no QoS). Ogni entit da inviare (datagramma) porta indirizzo del ricevente e viene
smistato in modo indipendente; si possono introdurre molti ritardi e jitter. Congestione -> si lavora male.
Controllo delle reti Se dobbiamo gestire connessioni abbiamo necessit di operazioni per preparare la comunicazione (stabilire la
connessione), mantenerla e garantirla, e chiuderla al termine.
Possibilit di Segnalazione (o Controllo)
I dati e/o i controlli, allinterno del mezzo, possono essere trasmessi:
in-band: usando gli stessi cammini e risorse per i dati
out-of-band: cammini separati per il controllo e il signaling
Ci sono diversi livelli di comunicazione:
Piano User (protocolli utente) (in-band)
o Livello applicativo
Piano di Controllo (controllo connessione) (out-of-band)
o Controlla come va la connessione ed eventualmente la migliora in termini di qualit
Piano di Management (stabilire e gestire il canale) (out-of-band)
o Stabilisce la connessione. Allocazione e deallocazione delle risorse per ottenere un servizio.
Controllo e management sono necessari entrambi per ottenere qualit. Internet usa solo il piano utente (controllo in banda ->
intrusione).

Reti
Spesso i sistemi di interesse sono costituiti da reti molto differenziate ossia reti destinate a interconnettere entit geograficamente
molto eterogenee
Wide Area Network WAN per reti geografiche anche a copertura molto ampia (globale)
o Si trovano in mesh, reti magliate e ridondate, come nel sistema telefonico, Public Switch Telephone Network (PSTN)

Metropolitan Area Network MAN area di copertura di una citt


Local Area Network LAN reti di dimensione limitata e con forte limitazione sui partecipanti
o Sono state usate molto come banco di prova e di esperienza dei protocolli, oltre che ampia palestra di uso
o Alta velocit ed ampia banda di trasmissione
o Facilit di broadcast
o Bassa probabilit di errori
o Topologie utilizzate:
Stella, come i PABX (Private Automatic Branch Exchange)
Bus anche un insieme di bus interconnessi
Ring (anello)
Hub, ossia un bus inglobato in una unica unit centrale di connessione, simile al nodo centrale di una stella
Personal Area Network PAN reti di dimensione veramente limitata e ad uso di utenti singoli con tecnologie ad hoc e
propagazione ancora pi limitata (reti wireless)

Controllo daccesso
Tipici controlli di accesso sono (standard IEEE 802.x):
CSMA/CD (Ethernet), standard 802.3
Carrier Sense Multiple Access/Collision Detection. Accesso ottimistico, reattivo, dinamico al bus, in caso di impegno si deve
avvertire la collisione e ritrasmettere con intervallo random.
Token (control token o token ring), standard 802.5
Accesso pessimistico garantito da un ring in modo statico: in un anello un solo possessore del token ha il diritto di trasmettere;
si forza il passaggio del token da un vicino ad un altro dopo un intervallo.
Slotted ring (anello a slot), standard 802.4
Accesso pessimistico usando messaggi che circolano in modo proattivo sul ring; anello come insieme di contenitori di
messaggi circolanti (o slot) che possono essere riempiti se vuoti.
Interconnessione tra reti
Possiamo avere molti apparati per interconnettere e/o separare entit a diversi livelli OSI
Ripetitori: rigeneratori di un segnale a livello fisico, superando e rimediando ad uneventuale livello di attenuazione. Un
ripetitore non effettua alcuna separazione. (livello fisico - 1)
Bridge: apparati che collegano reti diverse, con capacit di separazione e maggiore intelligenza (livello data link - 2)
Router (o gateway): apparati e sistemi per il passaggio da una rete ad un'altra con obiettivo di supportare la comunicazione dei
messaggi ed il routing (livello network - 3)
Protocol converter: sistemi che collegano reti diverse a pi alto livello con protocolli diversi di interconnessione (dal livello di
trasporto in su)

Bridge (Livello Data Link 2 OSI)


Un bridge collega e separa due (o pi) reti a livello di data link, controllando il passaggio e la separazione delle due reti, ad esempio
passando e bufferizzando (nella sua memoria) i frame dall'una all'altra, solo se necessario, e trattando anche situazioni di errore.
Vantaggi
Separazione effettiva delle reti
Bufferizzazione dei frame (trattando il caso di overflow)
Capacit di gestire controlli di accesso diversi (topologie e protocolli diversi in due reti)
Monitoring della rete: della performance ed affidabilit
Svantaggi
Ritardo di bufferizzazione
Bufferizzazione limitata e non infinita
Trasformazione dei frame (con controllo)
I bridge possono lavorare in molti modi diversi
Bridge multiporta, collegano pi segmenti di rete diversi (statici)
Bridge trasparenti, che operano in modo invisibile agli utenti (dinamici -> con fase di learning)
Devono collegare solo le entit interessate, ossia bloccare i pacchetti che devono rimanere locali e fare passare solo ci
che deve transitare
Si parla di routing isolato, anche se siamo a livello di frame, e dobbiamo avere previsto un database di forwarding
Informazioni della tabella come database in PROM
Bridge con capacit di apprendimento osservando il traffico. Il bridge impara la allocazione vedendo il traffico della rete e dai
vicini (il tutto ripetuto quando necessario coordinarsi). Allinizio fanno passare tutto. Vedendo da dove arrivano le
informazioni stabilisce dove sono allocate le connessioni (entit) della rete.
Se si usano molti bridge, non si potrebbe riconoscere facilmente la collocazione delle connessioni.
Soluzione: Bridge con priorit -> Viene definita una struttura ad albero di bridge nella fase precedente alla fase di apprendimento.
Algoritmo spanning tree - i bridge si scambiano messaggi per trovare i costi pi bassi di collegamento e costruire un albero unico che
percorre tutta la topologia di collegamenti. Si sceglie un bridge radice tra tutti e ognuno degli altri trova il cammino minimo per
collegarsi a lui (passi e velocit).
Bridge rimangono in una sola rete, solo tra tratte diverse della stessa rete.

Route e Routing (Livello Network 3 OSI)


Il problema del cammino dal sorgente al destinatario in caso di comunicazione viene affrontato dal routing attraversando un
insieme di nomi intermedi (dinamica) -> Necessit di mapping efficiente.
Quando arriva un datagramma in un ingresso il router deve sapere esattamente dove farlo uscire per farlo arrivare a destinazione
(prossimo hop o destinatario).

Propriet del routing


Correttezza Percorso pi breve (per numero di hop, tempi o altro) verso la destinazione.
Semplicit Algoritmi di smistamento devono essere semplici e ben realizzati
Robustezza (tolleranza ai guasti e variazioni) Reazione corretta alle sollecitazioni.
Stabilit della soluzione: Politiche e soluzioni che non cambiano nel tempo. Garanzia che la situazione di regime venga stabilita
in tempi brevi e che rimanga operativa a lungo.
Ottimalit Molte variabili da ottimizzare.
Fairness (giustizia) Nessun Privilegio -> FIFO. Non consente di gestire la QoS.
Classificazione Routing
Classificazione delle strategie di routing
Globale: c unentit che pu vedere globalmente lo stato di tutto sistema e attuare decisioni a livello globale. Problemi di
scalabilit.
Locale: ogni nodo prende decisioni di routing. Isolato perch ogni nodo ha delle strategie proprie, con visione limitata e costo
basso
Statico: routing in cui le strade da seguire sono decise in modo molto proattivo (staticamente). Molto poco flessibile.
Dinamico: prende decisioni che tengono conto dello stato del sistema. pi costoso perch, durante lesecuzione deve fare
delle operazioni (Visto che siamo in-band)
Adattattivo: Si adatta ai cambiamenti (fallimenti) nella rete, si sfruttano anche le risorse libere in modo dinamico
Non Adattattivo: NON si adatta ai cambiamenti (fallimenti) nella rete. I cammini sono fissi e non variano.
anche non deterministico / deterministico

Strategie di Routing
Per la classificazione si possono considerare molteplici attributi e ruoli
1. Chi prende le decisioni di routing
2. Chi attua le decisioni di routing
3. Il momento delle decisioni di routing
4. Il controllo del routing adattativo
1. Chi prende le decisioni di routing
Sulle strategie di routing, le decisioni prese da diverse entit
Sorgente (source route) Il mittente specifica l'intero cammino (in modo stretto e completo o solo parzialmente); gli altri
devono rispettare la decisione (statica per il datagramma).
Hop-by-hop
Ogni nodo ha uno scope di decisione e decide lui il prossimo hop. Decisione e strategia distribuita.
La decisione non viene guidata dal mittente, ma decisa ad ogni passo e ad ogni intermedio in modo indipendente il sorgente
non conosce il cammino e neanche gli intermedi che comandano solo la propria uscita.
Potrebbero non raggiungere tutti i nodi. Tabelle locali.
Broadcast
Si invia ad ogni possibile entit ricevente il messaggio ed ognuno lo riceve (costoso): non ci sono decisioni per il mittente ma
consegna a tutti (eliminando duplicati). Applicabile in sistemi molto limitati.
2. Chi attua le decisioni di routing
Sulla attuazione delle decisioni di routing, dobbiamo considerare il ruolo dei router intermedi che provvedono funzionalit opportune
Le decisioni possono essere attuate da agenti intermedi.
Unici e centralizzati (usato raramente) Un unico gestore del routing prende le decisioni: questo consente di ottenere anche
decisioni ottimali sullintero sistema. Per sistemi piccoli o in aree limitate.
Distribuiti Non esiste un unico luogo di controllo ma una serie di entit distribuite nellintero sistema e che si occupano del
routing, in modo pi o meno coordinato.
3. Il momento delle decisioni di routing
Per laspetto di tempo delle decisioni di routing, si considera routing:
Statico (fisso o deterministico) La strategia di routing rimane fissata nel sistema e non cambia.
Dinamico (adattativo) Lalgoritmo di routing evolve e si pu adattare alle informazioni di stato del sistema, in modo da
ottenere un costante adattamento alla situazione corrente. Supera problemi e guasti non previsti ad esempio.

4. Controllo routing adattativo In caso di adattivit, si deve prevedere una costante interazione con le risorse impegnate
Dal punto di vista della comunicazione, possiamo
avere Switching di Pacchetto (Internet) o uso di
Circuit Switch ossia canali predeterminati.
La scelta del cammino tra quelli possibili in modo
fissato o meno, adattandosi o meno allo stato del
sistema. Si noti che normalmente si considerano solo
cammini minimi (ottimi). In alcuni casi si possono
anche prevedere cammini non minimi facendo
misrouting (capacit di scegliere una strada diversa se
quella ottima non rispetta pi alcune caratteristiche di qualit o congestionata ad esempio).

Algoritmi tipici di routing


Shortest Path First (Dijkstra)
Ogni nodo costruisce un grafo completo dell'intera interconnessione, stabilendo una metrica di distanza in base a pesi.
Con successive iterazioni, si calcolano le distanze minime per ogni nodo (da scegliere successivamente).
Il traffico di routing segue il cammino pi corto determinato. Ogni nodo responsabile per il routing.
Svantaggi / Vantaggi
Costo della propagazione dei valori in caso di variazione.
Possibilit di usare al meglio tutte le risorse esistenti.
Implementazioni (famiglie)
Algoritmi Spanning tree (statico) (single-path)
Si tende ad identificare un albero di interconnessione tra tutti i nodi della rete, consentendo la eliminazione dei cicli e
determinando cammini senza problemi in modo globale. Non ottimo -> tutti i nodi occupano gli stessi cammini ->
congestione.
Algoritmi Distance Vector (dinamico) (single-path)
Per ogni gateway, la tabella mantiene la sola distanza in passi e il primo passo di uscita per il routing. Le tabelle sono minime
e consentono un istradamento statico facile. Problemi nei cambiamenti e nella propagazione delle variazioni. Sistema poco
coordinato. Usato in internet dallinizio. Single-path -> tutto il traffico da una rete ad unaltra passano su solo cammino. Non
reagiscono molto bene e hanno tempi di adattivit non accettabili.
Algoritmi Link State (dinamico) (multi-path)
Ogni nodo mantiene tutto il grafo e tende a limitare la propagazione delle informazioni, rendendo facili anche cammini
multipli. Variazioni (fallimenti) sono propagate in broadcast, spesso uso di spanning tree.
Sono interessanti ed usati anche algoritmi MULTIPATH ossia strategie che permettano di utilizzare anche pi possibili percorsi
per uno stesso destinatario. In Internet non si usa molto il multi-path. Internet lavora a livelli applicando in base al livello diversi
algoritmi.
Algoritmi Backward Learning
Ogni messaggio porta l'indicazione del mittente e, quindi, consente di inferire la distanza del mittente stesso ad ogni messaggio
I nodi intermedi possono stimare la distanze e la topologia.
La fase iniziale di apprendimento dell'algoritmo deve lavorare in base ad una politica, da cui dipendono le stime successive.
La conoscenza della topologia della interconnessione completa (globale) permette di evitare situazioni di ciclo o livelock (messaggio
continua a circolare senza andare da nessuna parte) in cui un messaggio si perde in passaggi inutili ripetuti.
Algoritmi isolati e adattativi
Strategie dinamiche indipendenti dalla topologia di interconnessione che si basano su informazioni solo locali (isolati) o solo di vicinato
(distribuiti e locali) possono essere molto efficaci. Vantaggi ad esempio se un nodo si muove.
Algoritmo Random, se non a destinazione, ogni messaggio, viene smistato con scelta casuale delluscita (non input).
Algoritmo Patata Bollente: Un messaggio viene smistato (se non a destinazione) attraverso la coda di uscita pi scarica del
nodo. Non si pu predire il numero di passi per arrivare a destinazione e dipende dal traffico.
Mancano del tutto i costi delle fasi di coordinamento e si limita fortemente overhead in caso di variazioni, e di cammini diversi. Si
possono introdurre problemi per la perdita della visibilit della topologia e del coordinamento: sono possibili cicli o livelock.
Algoritmo Flooding Un messaggio viene smistato (se non arrivato a destinazione) attraverso tutte le code di uscita del nodo
(nella direzione giusta). Uso di contatori per limitare i passi di un messaggio. Uso di identificatori per evitare generazione senza
fine.

Teorema per sistemi ideali di interconnessione (a messaggi)


Algoritmo di routing ottimale in un sistema dinamico con un numero infinito di nodi una combinazione del routing random.
M mittente e D destinatario, si determina in modo random un nodo R (diverso da M e D) e si manda il messaggio in due hop: la prima
fase da M ad R e la seconda da R a D.
In sistemi globali le tabelle devono essere aggiornate spesso: algoritmi senza tabelle limitano l'overhead e possono consentire di
raggiungere destinatari anche in movimento.
Ottimalit come uso ottimale delle risorse disponibili, usare al meglio le risorse disponibili.

Problemi nel Routing


Alcune situazioni sono critiche per il supporto al routing:
Congestione Situazione (globale) in cui un area della rete (internet) presenta un carico eccessivo.
C necessit di controllare gli asincronismi che possono impegnare le risorse e mantenerle.
opportuno un buon controllo dei buffer per evitare il problema (su un nodo/router). Possibilit:
Si inviano indicazioni al mittente (messaggi di choke: stop al mittente quando riceve un pacchetto oltre il limite. ICMP)
Si scartano tutti i messaggi successivi (tecnica reattiva)
Si prevede un numero massimo fisso di messaggi circolanti (tecnica proattiva)
Deadlock impegno totale dei buffer con blocco critico
Avoidance si numerano i buffer e si acquisiscono in ordine (proattiva)
Prevention si mantengono buffer per fare scambi in caso di saturazione (proattiva)
Recovery si tratta il problema quando rilevato (reattiva)
Livelock con messaggi che continuano a permanere nel sistema senza giungere a destinazione (persi in cicli o altro)
Soluzioni a priori si mantiene il cammino percorso e si evitano i loop
Soluzioni a posteriori si elimina il messaggio oltre un certo numero di passi (time to live)

Livello Network
Indirizzi IP
Sistema di nomi Internet (IPv4), parole di 4 byte (32 bit), diviso in due parti (parte di rete e parte di host). In Internet se si cambia rete si
cambia IP (cambiando la parte di rete) -> Tipici della rete in cui ci si trova.
I nomi di IP sono dati di autorit dal Network Information Center (NIC) che assegna i numeri di rete, cio informazione usata nei
gateway per routing. La parte di rete quindi assegnata di autorit.
La parte di nodo in IP soggetta a 3 classi primarie (in base al numero di reti e al numero di host collegabili) e differisce per numero
di bit delle singole parti: analizzando un indirizzo IP si pu distinguere la classe in modo automatico.

Datagrammi
Un Datagramma IP la unit base di informazione che viaggia in Internet. Contiene una parte di intestazione (di protocollo) e una
parte di dati.

Header del Datagramma


5 parole di 32 bit, con eventualmente, delle opzioni che possono occupare
le parole da 6 a 16 (parte dati)
Header (minimo 20 byte, max 64), e dati.
1. VERS Versione del protocollo,
HLEN (4bit) lunghezza dellheader (variabile),
TOTAL LENGTH lunghezza totale del datagramma (64k incluso lheader),
SRV TP Service Type qualificano il tipo di servizio, sono usati per scegliere
strade diverse.
2. IDENTIFICATION numero associato al datagramma utilizzato nella
frammentazione per identificare i frammenti.
FRAGMENT OFFSET offset dei vari frammenti. FLAGS per
frammentazione (primo e altri MF a 1 e lultimo MF a 0). DNF a 1 il datagramma non viene frammentato.
3. TIME TO LIVE, tempo di permanenza del datagramma (valore decrementato ad ogni hop: se 0 viene buttato),
PRTCL tipo di protocollo superiore (anomalia perch non si dovrebbe sapere ma pu servire) (TCP 6, UDP 17),
HEADER CHECKSUM per il controllo (complemento a 1 a 16 bit)
4. Indirizzo IP del mittente
5. Indirizzo IP del destinatario
6. Opzioni per monitoraggio e controllo rete
SeRVice TyPe
Consentono di selezionare il tipo di servizio. Bit da settare:
D (Delay): minimizzare il ritardo, T (Throughput) da massimizzare lo throughput, R (Reliability) massima affidabilit, C (Cost) costo
minore, PRECEDENCE: selezionare precedenze diverse in base al valore specificato.

Protocollo IP
I datagrammi viaggiano in modo indipendente e autonomo (anche come sottoparti o frammenti).
IP un protocollo best-effort a basso costo e non garantisce Quality of Service QoS n ordine.
Il protocollo IPv4 prescrive come si deve realmente implementare linstradamento dei datagrammi, obiettivo fondamentale del livello
Il protocollo prescrive per ogni nodo che deve comportarsi come un router, ossia fare routing, due funzioni principali da svolgere
Elaborazione del messaggio del livello superiore nel formato per la trasmissione
o Incapsulamento / Frammentazione. Il datagramma deve contenere le informazioni di livello superiore,
eventualmente i dati devono essere frammentati (se possibile)
Instradamento (routing) cio:
o Traduzione da indirizzo logico IP a indirizzo fisico di frame (ARP) (MAC)
o Scelta della porta di uscita (in base al percorso)
Invio di un datagramma IP
Un datagramma deve essere smistato da un nodo ad un nodo successivo secondo le normali regole di incapsulamento.
Ogni nodo deve incapsulare ogni datagramma in un frame di livello data link (livello 2) (aggiunge indirizzi di livello 2 MAC al
datagramma). Ovviamente questo avviene anche per ogni singolo datagramma, e senza legami tra i diversi frammenti e datagrammi,
che vengono trattati in modo indipendente dalla driver di routing (FIFO).
Ogni intermediario pu operare sul messaggio, a partire dal mittente. Ogni nodo pu frammentare il datagramma (decomposizione al
mittente, decomposizione ad ogni intermediario, ricomposizione solo al destinatario).
Frammentazione Datagramma IP
I datagrammi devono essere incapsulati nei frame di livello data link su cui transitano in base alla MTU (maximum transfer unit), ossia
la lunghezza massima dei frame a livello fisico (di Internet cio 2 OSI). Per determinare la dimensione massima del datagramma:
1. Calcolo statico da parte del mittente
2. Decisione passo passo (quella usata)
MTU scelta indipendente dalle tecnologie sottostanti per rendere efficiente la comunicazione a livello utente (fissata
tipicamente a 64Kb)
Il destinatario, unico che ricompone il datagramma, riceve diversi frammenti, li identifica in base allo stesso ID e li mette insieme in
base alloffset: se lintero datagramma stato ricevuto allora viene considerato, altrimenti viene eliminato.

Opzioni: Monitoraggio e controllo rete


Record route: genera una lista degli indirizzi IP dei gateway che il frame ha attraversato (al massimo 9 intermedi)
o Otteniamo una indicazione dei gateway intermedi attraversati dal datagramma.
Timestamp: genera una lista dei tempi di attraversamento sugli intermedi. Possiamo ottenere una indicazione dei tempi di
passaggio e della permanenza del datagramma nei gateway intermedi (vedi mail) per attuare anche azioni correttive e cercare
strade diverse
Source route (instradamento al sorgente): il sorgente fornisce indicazioni sul cammino da seguire nel routing del frame
o strict source: il datagramma porta nella parte opzione una indicazione di tutti i gateway intermedi da attraversare.
o loose source: indicazione di un insieme di percorsi da attraversare non in modo contiguo ed unico.
Numero massimo di parole nella parte opzione del datagramma limite al controllo del percorso: al massimo spazio per
registrare 9 passi
Famiglie di Algoritmi di routing
Due famiglie principali globali, basate su tabelle.
Distance Vector (dinamico con overhead)
o Per ogni gateway (router), la tabella mantiene la sola distanza in passi (num di hop) e il primo passo di uscita per il
routing.
o Le tabelle sono minime e consentono un istradamento statico facile.
o Problemi nella costruzione delle tabelle, nei cambiamenti e nella propagazione delle variazioni.
o Tabelle non statiche (no prom) ma completamente dinamiche e definite durante lesecuzione
Propagazione:

1.
2.

3.
4.

Ognuno dei gateway vede le reti vicine (distanza 0) (G1)


Si scambiano le tabelle (G1 e G2) tra i gateway.
Dopo lo scambio asincrono delle tabelle, se lofferta dice qualcosa di nuovo, aggiorna la tabella, altrimenti la lascia
invariata. Non c nessuna propagazione di informazioni in broadcast.
A regime ogni gateway contiene la distanza di ogni rete -> 100 reti = 100 entry.
Algoritmo assolutamente non scalabile. La propagazione molto lenta (esponenziale con il numero dei nodi)
Se si inserisce una nuova rete (es tra G1 e G3): se ne accorgono G1 e G3 inizialmente e per G1 diventa una scorciatoia
per arrivare a G3. Il cambiamento non viene assorbito velocemente da tutta la rete.
Problema
Counting-To-Infinity
Una volta definita una tabella e i relativi percorsi il traffico verso una certa rete seguir sempre lo stesso percorso.

Se un link cade, e da una parte c una rete magliata, in questa rete iniziano a essere scambiate offerte che possono
essere accettate (erroneamente) e ci prosegue allinfinito.
Problema generale dovuto al non tenere traccia di chi fornisce una distanza da un nodo (e cammino relativo) che
rende possibile utilizzare lofferta anche se non rilevante o affidabile.
In un primo momento stato risolto limitando il numero di passi a 16.
Strategie migliorative
Split Horizon: per evitare di passare informazioni sbagliate, non si offrono cammini ai nodi da cui le abbiamo
ottenute (necessarie maggiori informazioni) -> non si propaga solo la distanza ma anche chi lha fornita. Problemi con
reti magliate.
Hold-Down: stabilisce un protocollo pi coordinato quando c una variazione. Dopo una notifica di un problema, si
ignorano le informazioni di cammino per un certo intervallo: tutti hanno modo di accorgersi del problema e non ci
sono propagazioni errate.

Split Horizon con poisoned reverse e triggered broadcast: In caso di variazione, ogni nodo invia immediatamente un
broadcast con la indicazione del problema ed il cammino. Poco scalabile (per il broadcast -> costoso).

Link State (dinamico con overhead)


o Ogni nodo mantiene tutto il grafo, rendendo possibili anche cammini multipli e quindi sfruttando meglio le risorse.
Quindi ogni gateway ha una conoscenza completa della topologia di interconnessione -> Possibilit di MultiPath.
o Il LS permette intrinsecamente la possibilit di fare source routing e anche di spedire messaggi diversi su cammini
diversi (routing dinamico) e di utilizzare tutte le risorse di interconnessione.
o Si tende a limitare la propagazione delle informazioni. Le variazioni sono propagate in broadcast.
o Capacit espressive superiori.
o Tabelle di routing basate sulla conoscenza dell'intero cammino e tipicamente stabilisce percorsi unici da ogni nodo
ad ogni rete. Il grafo di interconnessione, per evitare cicli, viene gestito con algoritmi che possono favorire decisioni
locali (routing dinamico) -> (Dijkstra) shortest-path-first. Struttura ad albero > nessuna maglia.
o Non scalabile per le dimensioni del grafo.
o Ogni gateway tiene sotto controllo le proprie connessioni e le verifica periodicamente
invio periodico di un messaggio ai vicini per controllo della correttezza delle risorse locali
Identificazione del guasto (uso di messaggi specifici per evitare transitori in caso di variazione)
Non appena si verifica un problema, chi ha rilevato il problema invia il messaggio di variazione a tutti i
partecipanti (broadcast o flooding del messaggio). Propagazione non lenta come DV ma comunque molto
costosa. Tempi di down pi limitati.
Vantaggi
o Si controlla solo il vicinato
o Azioni di variazioni propagate rapidamente (senza ambiguit)
o Possibilit di scelte differenziate dei cammini nella topologia
o Conoscenza dei cammini completi e source routing
Svantaggi
o Necessit di mantenere tutta la topologia
o Azioni costose (broadcast) in caso di variazione

In generale, necessit di limitare i domini di conoscenza reciproca.


Tutti i protocolli dinamici sono poco scalabili in caso di variazioni (causa broadcast)
Algoritmo Shortest Path First (OSPF) Dijkstra
Protocollo usato in sistemi Link State per determinare i percorsi da usare nel routing.
Ogni nodo costruisce una propria tabella di cammini in modo iterativo e la usa per il normale routing.
Per ogni altro nodo, si deve memorizzare il cammino che permette di raggiungerlo, tenendo come base il grafo di interconnessione
(che viene mantenuto aggiornato).
Lalgoritmo permette di calcolare il routing di tutti i cammini minimi considerando lalbero che parte dal nodo stesso (spanning tree)
Lalgoritmo funziona in modo iterativo per passi, e comincia a calcolare le distanze dai vicini adiacenti, poi i nodi di distanza due
hop ecc. fino a trovare un albero completo di cammini minimi. Dopo N-1 cicli si raggiungono tutti i nodi e trovato tutti i percorsi
minimi.

Routing Internet
In Internet si lavora con degli indirizzi IP che rappresentano una connessione. La connessione stata pensata per un indirizzamento
punto-punto. Internet prevede una strategia precisa per raggiungere tutti i possibili nodi che possono intervenire in una
comunicazione.
Ogni connessione appartiene ad una rete ed una sola
per connessioni punto-a-punto
Ogni connessione libera di indirizzare nella rete facendo operazioni solo locali e a basso costo
per comunicazioni punto-a-punto o broadcast
Ogni connessione pu indirizzare in Internet (in modo globale) ma deve usare opportuni intermediari
routing previsto per Internet basato su responsabili della comunicazione globale a costo pi elevato
Linsieme delle reti Internet tende a minimizzare il costo di supporto del routing.
Basata sulla separazione delle reti e sulla loro interconnessione.
RETI uniche logicamente connesse
RETI fisiche separate

Indirizzamento diretto solo nellambito di nodi della stessa rete, altrimenti si devono usare gateway, ossia nodi intermediari con
almeno due indirizzi IP, ossia connessioni su reti diverse che connettono reti diverse.

Sottoreti
Possibilit di limitare la visibilit allinterno di una rete per garantire una migliore propagazione dellinformazione.
Un nodo in una sottorete pu comunicare direttamente con ogni nodo della sottorete e non pu comunicare direttamente con nodi
di altre sottoreti. In modo operativo, ogni nodo divide il campo host in subnet+host
In reti di classe B, subnet host suddiviso in 8 bit e 8 bit
dida01 137.204.56 subnet 56
deis33 137.204.57 subnet 57
In questo modo riconosce le proprie limitazioni, usando i router anche per comunicazioni allinterno della sua rete stessa.
DALL'ESTERNO DELLA RETE -> il subnetting invisibile e non produce alcuna differenza.
Maschere (NETMASK): sono 32 bit a 1 o 0. I bit a 1 specificano la rete che si sta considerando a livello globale, quelli a 0 lasciano la
visibilit diretta allinterno della specifica rete.
NETMASK esempio maschera in classe B (per 3 byte)
11111111 11111111 11111111 0000000 o 255.255.255.000
La maschera in sostanza un insieme di bit a livello di rete che determina quali siano i limiti di comunicazione che richiedono un router
apposito per uscire FUORI dalla SOTTORETE.
In Internet si attua un Routing Gerarchico per aree distinte di gestione e con domini amministrativi diversi.
Unico protocollo di routing per area. La connessione tra le aree avviene attraverso gerarchie di router.
Distinzione tra sistemi core e noncore (ARPANET)
core insieme di gateway chiave con tabelle complete (e replicate)
non core con informazioni di routing solo parziali (e locali)
I nodi CORE si scambiano tutte le informazioni di routing (algoritmo Distance Vector e Link State)
Scalabilit? problemi aumentando il numero delle reti -> Necessit di routing con astrazione e gerarchia.
Introduzione dei sottosistemi autonomi (di livello inferiore).
Insieme di reti e gateway controllati da una autorit unica centrale, con proprie politiche di routing interne e non visibili
Alcuni gateway di controllo provvedono al protocollo verso l'esterno
o Exterior Gateway Protocol (EGP)
Protocollo del gateway di controllo per trovare il percorso fino ai core. Struttura ad albero con i core come radice
I sistemi autonomi devono scambiarsi informazioni di routing e coordinamento solo intra-sistema
o Interior Gateway Protocol (IGP)
Protocollo per trovare il percorso all'interno di un sistema autonomo (intra-sistema).
Politica che consente percorsi multipli e con possibilit di tollerare i guasti (algoritmi multipath IGRP CISCO)

Routing Locale Internet


Routing Information Protocol (RIP) implementato in routed UNIX
Nodi attivi e passivi
ATTIVI partecipano a determinare i percorsi (router)
PASSIVI restano ad ascoltare le decisioni degli altri (nodi)
Si manda un messaggio ogni 30 secondi nel vicinato con la tabella di routing locale -> Poco reattivo.
Si aggiornano le tabelle in base ai messaggi ricevuti: se i messaggi rilevano cammini pi brevi di quelli noti si stabiliscono nuovi cammini
Adatto solo per reti di piccole dimensioni.
NB: In Internet si fa Routing per RETE e non per NODO.
Routing diretto: se messaggio per la stessa rete non si passa per un router.
Routing indiretto: se messaggio verso lesterno bisogna inserire a livello 2 (MAC) lindirizzo del router -> sapendo che non per lui lo
smista verso lesterno inserendo se stesso come mittente e lasciando invariato il destinatario.

Propriet Routing IP
Routing statico
tutto il traffico per una data rete stesso percorso e non eventuali percorsi alternativi (vedi problemi in caso di limiti di tempo ed
urgenze). Tabelle non cambiate troppo spesso. Non multipath in generale.

10

Autonomia
Ogni gateway autonomo: ogni datagramma da A verso B pu seguire un percorso differente rispetto a quello da B verso A i gateway
devono cooperare per garantire le due vie di comunicazione nei due sensi.
Visibilit
Solo il gateway finale comunica con il destinatario e verifica se l'host esiste ed operativo: quindi pu rimandare al mittente.
Indicazioni dei problemi di mancata consegna gli intermediari mandano il datagramma in base alla tabella corrente o alle decisioni di
routing attuali.
PERCORSO A DEFAULT
Scelta di un gateway cui inviare i messaggi se non si conosce alcuna informazione correttamente.
Indirizzamento IP cerca nella tabella locale poi invia il datagramma al gateway di default.
Strategia usata da host che servono una piccola quantit di utenti e sono collegati attraverso una sola connessione ad Internet.
PERCORSO DIRETTO AD UNO SPECIFICO HOST
Indirizzamento diretto ad un host in modo diretto e specifico, per esigenze particolari con un migliore controllo delle risorse in caso di
traffico speciale.

Algoritmo
function Route_IP_Datagram (datagram, routing_table)
Separazione indirizzo IP destinatario (Idest) datagramma
Valutazione indirizzo IP della rete di destinazione (Inet)
If
Inet un indirizzo raggiungibile direttamente
then invio diretto del datagramma sulla rete destinataria
(trasformazione indirizzo IP in indirizzo fisico e incapsulamento del datagramma in frame)
else if
Idest un host con un cammino proprio
then
invio del datagramma in base alla tabella
else if
Inet si pu ottenere da una entry nella tabella di routing (tenendo conto di subnet)
then
si invia il datagramma al prossimo gateway
else
percorso di default per tutti i restanti datagrammi
Si tiene conto della sottorete usando la maschera ed Idest. Non competenza delle tabelle -> c sempre un router di default.

11

Internet
TCP/IP
Semantiche di Comunicazione
MAY-BE (o BEST-EFFORT) Per limitare i costi ci si basa su un solo invio di ogni informazione -> il messaggio pu arrivare o meno
Internet tutto BEST-EFFORT. Rappresentato da IP in cui ogni azione fatta una volta, senza preoccuparsi di qualit, di affidabilit e di
garanzie. (UDP e IP)
AT-LEAST-ONCE Si prevedono ritrasmissioni ad intervallo. Il messaggio pu arrivare anche pi volte a causa della duplicazione dei
messaggi dovuti a ritrasmissioni da parte del mittente. Semantica adatta per azioni idempotenti in caso di insuccesso nessuna
informazione. Il Cliente di preoccupa della affidabilit.
AT-MOST-ONCE Pi invii ad intervalli e stato sul server. Cliente e Servitore lavorano in modo coordinato per ottenere garanzie di
correttezza e affidabilit. Il messaggio, se arriva, viene considerato al pi una volta. La semantica non introduce vincoli sulle azioni
applicative. (TCP)
EXACTLY-ONCE (ATOMICIT) Il messaggio arriva una volta sola oppure il messaggio o arrivato o non stato considerato da entrambi
-> Semantica molto coordinata sullo stato. Al termine i pari sanno se l'operazione stata fatta o meno. I pari lavorano entrambi per
ottenere il massimo dell'accordo e della reliability.
TUTTO o NIENTE Semantica senza durata massima. Se le cose vanno bene il messaggio arriva una volta e una volta sola viene trattato,
riconoscendo i duplicati (tutto). Se le cose vanno male il cliente e il servitore sanno se il messaggio arrivato (e considerato 1 volta sola
- tutto) o se non arrivato. Se il messaggio non arrivato a uno dei due, il tutto pu essere riportato indietro (niente). Completo
coordinamento delle azioni, ma durata delle azioni non predicibile. Se uno dei due fallisce, bisogna aspettare che abbia fatto il
recovery. Entrambi sanno realmente come andata (tutto o niente).

Azioni di Gruppo
Broadcast
NON sono consentiti broadcast a livello globale vista la dimensione del sistema -> per evitare costo inaccettabile
Broadcast permessi solo nell'ambito di una rete locale
BROADCAST limitato: Limitato perch i router non li fanno passare (rimane sulla stessa rete locale) indipendentemente dall'indirizzo
IP. Indirizzo in cui tutti i 32 bit sono a 1 (limited broadcast address). Costo basso.
BROADCAST diretto: Verso tutti gli host in una rete specifica. Indirizzo in cui tutti i bit di hostid a 1 (broadcast direttivo o directed
broadcast) trasmesso in Internet, arrivato alla destinazione, broadcast.

Multicast
Indirizzamenti multicast di Classe D. Indirizzi a cui gli host interessati si possono registrare. Tutti gli host che si sono registrati possono
ricevere messaggi e possono mandare messaggi al gruppo di multicast (vedi socket multicast). Problema -> Costo

ARP Address Resolution Protocol


Definito insieme a RARP (non usato). ARP permette di ottenere lindirizzo MAC di un nodo a partire dal suo indirizzo IP. Questo serve
in caso di routing diretto (allinterno della stessa rete locale). un protocollo costoso perch fa broadcast sulla rete locale. Per questo
vengono mantenute delle corrispondenze gi note (in tabelle) in cache locali. Quando viene fatta una richiesta ARP sulla rete tutti i nodi
della rete vedono la risposta qualificando quindi le tabelle di tutti i nodi (per evitare troppi broadcast).
ARP distingue due ruoli nel protocollo, che ogni nodo realizza
Attivo richiede l'indirizzo fisico per un pacchetto
Esamina la cache per risolvere indirizzo IP localmente, altrimenti esegue una richiesta ARP broadcast
la gestione della richiesta broadcast deve prevedere di non ricevere risposta o riceverla con ritardo
Passivo risponde alle richieste di altri
Risponde alle richieste di altri (come server) processando il pacchetto estraendo sia indirizzo IP sia il fisico per pacchetto ARP
Se richiesta del proprio indirizzo -> invio risposta
Se non risponde -> nodo non connesso -> datagramma buttato via.

Livello Data Link (Livello 2 OSI): Ethernet


ETHERNET, standard di fatto a livello MAC (Medium Access
Control). Formato di un frame con indirizzi a 6 byte o 48 bit
con dati di lunghezza variabile da 46 a 1500 byte.
Indirizzi a 48 bit per il nodo mittente e destinatario
Si introducono sia preamboli, sia delimitatori finali
Controllo del frame attuato con controllo CRC
In un frame, per linvio di 1 solo byte (applicativo oltre il
trasporto) con 1 byte applicativo -> overhead 46 byte
(20 IP e 20 TCP/UDP, 5 riempimento)

RARP Reverse Address Resolution Protocol


Protocollo fortemente deprecato. Dato il MAC di un nodo restituisce lindirizzo IP corrispondente. Serve nel caso in cui ci siano nella
rete macchine diskless che non sono quindi in grado di mantenere in memoria la corrispondenza MAC-IP. Quindi deve esserci un Server
che in grado di rispondere alla richiesta. Se sono previsti, spesso ci sono server multipli per RARP:
Modello a server attivi Troppi server sovraccaricano il sistema se cercano di rispondere contemporaneamente alla richiesta.
Modello a server attivi/passivi soluzioni possibili con gerarchia di server.
Per evitare interferenza:
Modello dinamico con server differenziati in ascolto: il server primario il solo a rispondere; gli altri server rispondono solo se arriva
una seconda richiesta RARP (anche in gerarchia).
Modello statico con server differenziati e ritardi diversi: si prevede che il server primario risponda immediatamente, gli altri con un
ritardo calcolato random, con una bassa probabilit di risposta simultanea.
stato uno dei primi casi in cui si considerata la replicazione di un servizio.

DHCP - Dynamic Host Configuration Protocol


Protocollo per la attribuzione dinamica di indirizzi IP per ottenere una configurazione dinamica e con risparmio rispetto ad IP statici.
Si basa su due ruoli distinti: clienti e servitori con protocollo di offerta tipo asta (bidding) a pi fasi, con iniziativa del cliente:

Broadcast della richiesta di discovery (richiesta di ingresso) (Discover)


Offerte da parte dei servitori (con parametri di scelta) (anche non bx)
Scelta di una offerta (in broadcast)
Conferma della offerta (ACK)
Messaggi prima della scadenza (lease). Riconferma dellindirizzo.
Rilascio dellofferta (release).

Al contratto viene associata una durata: se durante lintervallo non si usa, il server
pu riassegnare lindirizzo. Il lease permette di confermare l'uso, senza rieseguire il
protocollo. DHCP permette lattribuzione di tutta una serie di parametri di gestione:
maschera di rete, sottorete, diritti, ecc. ecc

NAT Network Address Translation


Usato per traslare indirizzi intranet privati in indirizzi IP globali in rete aperta. Serve perch molto spesso si vuole lavorare in reti
interne con indirizzi IP propri (interni e privati). Quando la comunicazione deve passare attraverso internet un router NAT attua le
traslazione degli indirizzi dallindirizzo interno ad un indirizzo esterno realmente assegnato alla rete in cui ci si trova. In questo modo
per per ogni indirizzo interno bisogna avere un indirizzo esterno. Nelle prime realizzazioni era possibile associare ad un unico indirizzo
esterno diversi indirizzi interni (problema con i provider).
Questo reso possibile da un NAT pi flessibile, NAT a porte, e che impegna meno risorse esterne (vedi contratti con provider):
permette di mappare molti indirizzi interni in un unico indirizzo esterno, distinguendo molteplici indirizzi interni attraverso luso di
porte diverse di connessione, associate ai diversi indirizzi interni. Questo porta a limitare limpegno di indirizzi esterni (con molti
indirizzi interni associati) ed i costi.

ICMP Internet Control Message Protocol


Protocollo di metalivello di gestione e controllo su IP migliorando la qualit best-effort. ICMP usato per coordinare le entit di livello
IP. ICMP consente di inviare messaggi di controllo o di errore (datagrammi) al nodo sorgente del messaggio (e solo a questo). Gestisce
anche situazioni in cui bisogna controllare la sincronizzazione. Protocollo non connesso -> uso di datagrammi ICMP che si incapsulano in
un datagrammi IP -> lavora in-banda. Se viene buttato via questo non viene segnalato altrimenti si genererebbe troppo traffico nella
rete (congestione).
Formato (Header)
Type identificatore del messaggio
Code informazioni di tipo messaggio
Checksum (16 bit) utilizzato dal relativo algoritmo
Se c un errore nella parte DATA si inserisce lheader del datagramma che ha
avuto errori.
Type:
0 Echo Reply
12 Problemi sui parametri del datagramma
3 Destinazione irraggiungibile
13 Richiesta di timestamp
4 Problemi di congestione (source quench)
14 Risposta di timestamp
5 Cambio percorso (redirect)
15 Richiesta di Address mask
8 Echo Request
16 Risposta di Address mask
11 Superati i limiti di tempo del datagramma
Echo Request e Echo Reply consentono di fare il servizio di Ping.

Code: intero dipendente dai valori di TYPE.


0 Rete irraggiungibile
1 Host irraggiungibile
2 Protocollo irraggiungibile
3 Porta irraggiungibile

4 Frammentazione necessaria
5 Errore nel percorso sorgente (source route fail)
6 Rete di destinazione sconosciuta

Comando ping per stimare il RoundTrip Time o RTT


Si mandano echo request al nodo e attesa di echo reply. Si possono variare le dimensioni dei dati ed il numero di invii, secondo le
diverse necessit di gestione
Comando traceroute (o tracert) per visualizzare il percorso da un nodo fino ad un altro nodo della rete
Si mandano messaggi con TimeToLive crescente. Il nodo che riceve il datagramma con TTL=0 lo scarta e manda un messaggio ICMP al
mittente. Ogni perdita forza un messaggio ICMP catturato dal mittente. Cos si pu ricostruire tutto il percorso. Funziona bene se le
tabelle di routing non cambiano spesso.

UDP User Datagram Protocol


UDP protocollo di trasporto (Livello 4 OSI) molto semplice, best-effort e a basso costo. UDP deve distinguere tra pi processi in
esecuzione su un dato nodo connesso alla rete, processi identificati con numero di porta UDP.
Si appoggia a IP per consegnare i datagrammi.
Indirizzo: indirizzo IP + numero di porta (16 bit)
Header
Composto da due parole da 32 bit.
Porta sorgente e porta destinataria, checksum e lunghezza del messaggio
(necessaria per definire il payload). Datagramma al massimo 64kb.
Uno user datagram (UDP) del tutto contenuto nell'area dati del datagramma IP,
senza nessuna frammentazione. Se supera la dimensione massima -> tronca.
Overhead molto limitato.
Per le porte: C ununica driver UDP che prende decisioni di multiplexing/demultiplexing sulle porte.
Multiplexing: messaggi da pi processi applicativi paralleli con un solo servizio IP.
Demultiplexing: lo stesso messaggio recapitato alla porta corretta.
UDP/TCP adottano soluzione ibrida: alcuni numeri di porta a priori (well known port) e gli altri assegnati dinamicamente.
Porte note
0 Riservato
37 time
7 echo
69 tftp (trivial file transfer protocol)
9 discard
111 Sun RPC protocol
11 users
513 who (demone di rwho)
13 daytime
514 system log

TCP Entit e connessioni


TCP permette la connessione end-to-end tra pi processi di nodi distinti, creando l'astrazione connessione come coppia di endpoint
Un endpoint definito come coppia di interi {host, port} con host l'indirizzo IP dell'host, e port della porta TCP
La connessione la quadrupla {host1, port1, host2, port2}
Pu esistere una sola connessione per quadrupla
La driver TCP fa multiplexing/demultiplexing sulle porte.
Porta Protocollo
Descrizione
20
FTP-DATA
File Transfer Protocol (dati)
21
FTP
File Transfer Protocol
23
TELNET
Terminale Remoto
25
SMTP
Protocollo di posta elettronica
80
HTTP
Protocollo web
119
NNTP
Protocollo news

ARQ - Automatic Repeat reQuest


Protocollo di ritrasmissione automatica. Se non si riceve un ACK relativo ad una richiesta si ritrasmette (Semantica At-Least-Once).
Protocollo fortemente sincrono bloccante (con stop and wait).

Continuous Requests
Protocollo pi complesso rispetto al caso ARQ
Non attesa in modo sincrono della ricezione conferma (ACK) ma si mandano messaggi in modo ripetuto.
Il mittente manda messaggi che sono mantenuti fino a saturare la memoria disponibile (finestra buffer) e sono scartati solo alla
conferma. Il mittente scorre la finestra in caso di conferma (all'acknowledgement). Attesa del mittente solo a finestra piena. La
dimensione della finestra imposta dal ricevente. Variazione imposta dal ricevente (se a 0 attesa finch non si libera).
In caso di Errore:
SELECTIVE RETRANSMISSION attesa dellesito dei messaggi tenendo conto degli ack ricevuti e anche ack negativi (dovuti al time-out del
ricevente) e ritrasmissione di quelli persi.
GO-BACK-N attesa di ack e ritrasmissione (solo con time-out al mittente) e tenendo conto di ack del ricevente (che salta i non ricevuti);
il mittente scarta i messaggi successivi non in sequenza e li rimanda tutti al ricevente go-back confonde messaggi non in ordine con
perdite (TCP usa GO-BACK-N ottimizzato e ack cumulativi). Nellimplementazione TCP (nel ricevente) i messaggi gi ricevuti non
vengono sostituiti. Un ack pu confermare anche i messaggi precedenti.
Nei protocolli continuous requests, ogni direzione di trasmissione usa una finestra scorrevole (sliding window) per la gestione della
memoria di bufferizzazione. La decisione della dimensione del buffer sempre del ricevente che deve allocarla e mantenerla per i
messaggi. Gli slot non sono mai della stessa dimensione.

TCP - Transmission Control Protocol


TCP fornisce un servizio di trasmissione dati affidabile basato su
Reliable stream full duplex
Connessione o canale virtuale bidirezionale
Due stream di byte. Su ognuno semantica at-most-once. Lo stream, ossia il flusso, costituito di dati in ordine preciso e non
alterabile.
Flusso di dati non strutturato (byte stream) e dati normali
Dati prioritari in banda limitata (1 byte)
La connessione TCP NON impegna i nodi intermedi si usano solo le risorse dei nodi degli end-user. Nessun cammino statico.
Il protocollo TCP si basa su alcuni principi e vincoli da rispettare:
Formato dei dati trasmessi (segmenti con header fissato)
Possibilit di dati urgenti
Regole per la bufferizzazione e l'invio degli acknowledgement (sliding window) e relativo formato
Possibilit di comporre messaggi e decomporre in segmenti (default 536kb). Decisione del protocollo.
Meccanismi di de/multiplexing (vedi UDP) attraverso il concetto di porta per distinguere pi processi su uno stesso host
La realizzazione si basa sulla implementazione della connessione e sulla comunicazione, permettendo servizi che devono occuparsi di
1. Stabilire la connessione (Prologo)
2. Scambiare dati sulla connessione
3. Chiudere la connessione (Epilogo)

Header
5 parole da 32 bit (4 byte). (IP nellheader del Datagramma)
Sequence Number: Numero che indica la posizione precisa nel flusso del byte
contenuto nel segmento.
Acknowledgement Number: Indica lo stato di ricezione del mittente, quanto
stato ricevuto del flusso. Viene inviato sempre.
(Piggybacking: Sfrutta la trasmissione per fare controllo.)
Checksum: Complemento a 1 per il controllo.
HLEN: Header Length, tipicamente 5, ma che pu essere maggiore perch
possono esserci Opzioni.
Window: indicazione in byte della dimensione della finestra di ricezione.
CODE BIT (6bit a 0 o 1):
ACK: se a 1 lacknowledgement number e valido.
SYN: bit per stabilire una connessione.
FIN: bit per chiudere una connessione.
RST: Se a 1, ci sono stati problemi nella connessione (o di qualit) quindi si ristabilisce.
URG: Se a 1 indica che il flusso contiene un dato urgente e viene letto lurgent pointer. Il campo urgent pointer dice la distanza dalla
posizione corrente nel flusso. Banda di 1 byte -> pu essere sovrascritto da un URG successivo. Se viene segnalato un dato urgente da
livello applicativo sul flusso -> tutti gli header portano la segnalazione del dato urgente.
PUSH: Se a 1, il segmento viene mandato immediatamente senza bufferizzazione. Anche se in realt sono le driver a decidere.

TCP Comunicazione
TCP pu spezzare i messaggi applicativi in segmenti di dimensione variabile, e tende a frammentare messaggi in segmenti
N troppo corti: grosso overhead di trasmissione
N troppo lunghi: frammentazione a livello di IP e possibili perdite
TCP usa CONTINUOUS REQUEST per efficienza e affidabilit
I messaggi prevedono ack, che essendoci traffico nei due sensi, gli ack sono inseriti sul traffico in direzione opposta (piggybacking)
USO di finestra scorrevole, espressa in byte, determinata e decisa dal ricevente e comunicata per ogni invio di segmento.
TCP Ritrasmissione
TCP usa GO BACK-N, in caso di non ricezione di un segmento
il ricevente pu scartare quelli successivi e attendere il segmento mancante
il mittente deve rimandare i segmenti da quello che manca
reinvio anche ripetuto fino ad una eccezione (fallimento)
il ricevente deve favorire il reinvio di segmenti mancanti
In realt il ricevente ottimizza e non scarta immediatamente i segmenti fuori ordine (ma li mantiene se pu per integrarli).
DOPO quanto tempo si ritrasmette, QUANTE VOLTE si esegue le ritrasmissione, COME si frammentano i segmenti decide tutto la driver.
Il protocollo a stream pu rimandare parti del flusso ossia segmenti con dimensioni diverse senza garanzie di lunghezze predefinite o
stabili.
TCP Conferme
TCP conferma con ack cumulativi (numero di ack non uguale al numero di messaggi ricevuti)
Un ack specificato del ricevente porta l'indicazione di tutto ci che stato ricevuto nello stream fino al momento dell'ack. In caso di
perdita, si continua a mandare ack per l'ultimo ricevuto.

TCP Fasi di Operativit


Fase iniziale - three-way handshaking
In cui si stabiliscono una serie di parametri operativi per la connessione e si prepara l'avvio
Fase di comunicazione transitorio e regime
Transitorio iniziale: si comincia a lavorare in fase esplorativa (per scaldare il canale)
Regime in varie condizioni operative diverse. Si devono considerare situazioni di congestione individuando o prevenendo i colli
di bottiglia fino a ristabilire una situazione normale o fino ad un abort della connessione
Fase finale chiusura mono e bidirezionale (a quattro vie)
Chiusura manifestata da uno dei due pari e accettata dall'altro. Operativit con canale monodirezionale di dati, ma con
messaggi di controllo in entrambe le direzioni.
TCP Fase Iniziale Three-way handshake
Fase solo di gestione. Costituisce la negoziazione iniziale fra le due parti. 3 messaggi (senza dati) scambiati.
1. A invia a B il segmento con SYN e richiede la connessione
(SYN nell'header del segmento e X valore iniziale del flusso scelto da A)
2. B riceve il segmento SYN e ne invia uno identico ad A con ACK
(anche del valore mandato da A, X+1) anche SYN con Y valore scelto da B
per il suo verso.
3. A riceve il segmento SYN ed ACK e conferma la ricezione a B
attraverso un ACK a sua volta (Y+1)
Sono 3 perch servono a dimensionare finestre e time-out. X e Y sono numeri casuali perch se si partisse da 0 potrebbe interferire con
altre richieste di connessione. Bidding (senza rifiuto). Se si dovesse perdere un messaggio si reinvia con intervalli di time-out crescenti
e dopo si chiude.
In fase iniziale si possono negoziare altre opzioni:
Accordo sul segmento medio o MSS (Maximum Segment Size) (default 536 byte)
Fattore di scala della finestra (max 64kb perch espresso in 16bit)
Richiesta di tempo e risposta per il coordinamento degli orologi
Tutta la fase iniziale legata alla connect dalla parte del cliente.
TCP Fase Finale Chiusura in 4 fasi
Si prevede una semplice operazione di chiusura graceful.
Chiusura monodirezionale di output ossia definitiva per un solo
verso (il verso di autorit) senza perdita dei messaggi in trasferimento e
di quelli in arrivo.
1. A invia segmento FIN in ordine dopo linvio dei dati precedenti
TCP aspetta a dare corso alla chiusura, ma invia da A a B solo ack.
2. B invia LACK relativo al FIN. Si mandano altri dati da B ad A.
3. Al termine del traffico applicativo da B ad A, B invia ad A il segmento
FIN che informa della disponibilit a chiudere la connessione
4. L'ultimo passo conferma (ACK) da A a B della ricezione del segmento
FIN e la chiusura totale della connessione
TCP Fase Transitoria
Le connessioni in TCP, nella fase transitoria iniziale vengono scaldate. Cio a la operativit sulla connessione avviene solo dopo avere
cominciato in modo graceful e tentando di andare verso la situazione di regime nel modo migliore possibile. Consente ai router di
sostenere le bande necessarie a realizzare la connettivit.
TCP A Regime
Nella fase iniziale si sono dimensionati i time-out. Durante linterazione potrebbe cambiare qualcosa e quindi potrebbero cambiare
anche di molto. TCP ricalcola dinamicamente la distanza in tempo utilizzando solo i messaggi confermati (con ACK).
Ricalcolo del Time-out in base a una formula del tipo (Karn)
Timeout = * Intervallo precedente + * Intervallo corrente
Cio si tiene conto della storia e si aggiunge un po di dinamica (con i fattori alfa e beta)
Non viene fatta nessuna ritrasmissione -> time-out ricalcolato solo in caso di successo.

TCP Controllo di Flusso


Il controllo di flusso fondamentale in Internet in cui ci sono connessioni con macchine molto diverse fra loro.
Sono meccanismi fondamentali di coordinamento:
la finestra
La dimensione della finestra viene inviata per ogni segmento e comunica al pari quali siano le esigenze di memoria della
connessione. Una finestra a 0 significa di non inviare alcune segmento. Ogni pari comunica allaltro la propria situazione con la
finestra
la dimensione preferenziale dei segmenti da inviare attesa di dati prima di inviarli fino ad avere un segmento che sia
conveniente inviare (Maximum Segment Size come opzione TCP).
Si deve evitare di avere trasmissioni di messaggi corti: Silly window (finestre limitate) e messaggi brevi.
Algoritmo di Nagle: si ammette di avere pendente senza ack al pi un solo messaggio corto - retroazione automatica per non inviare
messaggi corti in eccesso. Problemi ad esempio in telnet: movimenti del mouse (messaggi molto corti) -> disabilitato.
TCP Congestione
Per congestione di intende la situazione in cui non si riescono pi a consegnare dati in tempi utili (rispetto alla operativit corrente).
uno stato che pu essere non solo dipendente dai soli endpoint della connessione stessa, ma anche da una pi ampia situazione
dellintero sistema. Pu presentarsi in due casi:
stato forzato troppo il cammino della connessione e abbiamo congestionato solo le nostre risorse locali
Tutti i router sono con buffer pieni e nessuno scambio pu pi avvenire, fino alla de-congestione. Anche se i router possono
segnalare buffer pieni.
Per il secondo caso si pu agire con meccanismi di Avoidance (azione preventiva) o con azioni di Recovery (azione reattiva).
Lidentificazione della congestione avviene dopo un time out che scatta in modo continuo.
In questo modo si assume che il destinatario non sia raggiungibile e che la congestione sia in atto.
Come azione di Recovery si devono attuare azioni locali per evitare di aggravare il problema:
In modo unilaterale il mittente dimezza la finestra di invio e raddoppia il time-out (finch non arriva a 0)
Al termine della congestione, per ritornare a regime, si riparte con un transitorio con finestra piccola (slow start)
Come azione di Avoidance si attua lo Slow Start in cui variazioni vengono fatte in modo dolce.
Lo Slow Start il transitorio sulla finestra del mittente per arrivare da una situazione iniziale fredda (senza comunicazione) ad una
comunicazione a regime calda (diversa banda) in modo graduale (dolce).
In questo meccanismo si considerano tre variabili:
La cwnd (congestion window): finestra corrente lato mittente (variabile).
La rwnd (receiving window): finestra segnalata e dettata dal ricevente.
ssthresh (Slow Start Threshold): valore variabile, soglia di slow start.

Il controllo di congestione lavora in due fasi distinte di operativit


1. Slow start (se cwnd < ssthresh)
cwnd viene incrementato (a partire da 1).
La crescita avviene in modo esponenziale fino allo ssthreshold (viene raddoppiato)
Poi diventa lineare (fase di congestion avoidance)
Cresce fino alla dimensione totale della finestra (rwnd) o fino a time-out.
2. Congestion avoidance (se cwnd >= ssthresh)
In caso di congestione avvenuta (time-out), si ridimensiona tutto e si riparte in modo esplorativo (slow start)
Lssthreshold viene dimezzato.
Ricapitolando: Slow Start - Si inizia con un segmento nella finestra di congestione, e si raddoppia (exponential backoff) appena arriva
un ACK. Quando la finestra di congestione raggiunge quella di ricezione, siamo a regime e si incrementa/decrementa di
unit alla volta (fase lineare) fino ad eventuali situazioni di congestione.

Strategie tipiche TCP

Ricalcolo del time-out in modo dinamico


Il time out corrente viene tarato rispetto a quanto calcolato come media con la stima del time-out precedente.
Exponential backoff
In caso di ritrasmissione, il time-out raddoppia, fino ad un tempo massimo (ad es. 4'), poi si chiude la connessione.
Silly window
Per evitare di lavorare un byte alla volta, non si annunciano finestre di dimensione troppo piccole (MSS/2) a parte la finestra
chiusa (0 per blocca trasmissioni pari)
Limiti al time-wait
Per limitare la durata delle risorse per la connessione. Ricordiamo che la memoria sulla porta dovrebbe essere mantenuta per
tempi necessari per smaltire tutto il contenuto del buffer ma non troppo superiori a quelli. (in caso di close che mantengono la
memoria in uscita fino a consegna)
Long fat pipes
Per mantenere piene le pipe a banda elevata (fornendo indicazioni di buffer superiori a quelli di utente e bufferizzando a livello
di supporto).

Socket in Java
Progetto C/S
Le socket rappresentano il terminale locale (end-point) di un canale di comunicazione bidirezionale (da e per lesterno). In Java
(standard) si risolve il problema della comunicazione tra macchine distinte, diverse e fortemente eterogenee.
Le Socket possono realizzare due tipi di comunicazione:
Con connessione, in cui viene stabilita una connessione tra Client e Server (esempio, il sistema telefonico) (socket STREAM)
o Protocollo Internet TCP
o Classe Socket, per socket lato Client
o Classe ServerSocket, per socket lato Server
Senza connessione, in cui non c connessione e i messaggi vengono recapitati uno indipendentemente dallaltro (esempio, il
sistema postale) (socket DATAGRAM)
o Protocollo Internet UDP
o Classe DatagramSocket, per socket (C/S)

Sistema di nomi
Necessit di un sistema di identificazione degli enti in gioco. Per risolvere il problema dellidentificazione reciproca dei processi (Client e
Server nella rete ad ogni processo deve essere associato un nome globale: visibile in modo univoco, non ambiguo e semplice. Questo
viene risolto dai livelli bassi di protocollo (trasposto e rete).
Un nodo identificato univocamente da:
Indirizzo IP (4 byte / 32 bit) -> livello IP (della macchina)
o Identificativo della macchina nella rete
o Esempio 137.204.57.186
Porta (numero intero di 16 bit) -> astrazione in TCP e UDP
o Porta allinterno della macchina a cui deve essere collegata la socket
o 4 cifre esadecimali XXXXh (valori tra 1 e 65535). Le prime 1024 sono riservate (well-known port)
Uso di questo NOME GLOBALE che rappresenta lend-point di un canale di comunicazione.
Per raggiungere una risorsa con NOME LOCALE: un processo (o pi) si lega a una porta per ricevere o spedire dei messaggi. In questo
modo possibile identificare un processo senza conoscere il suo PID locale.

Server Sequenziali e Paralleli in Java


Tipicamente una socket comprende una coda di ingresso (buffer).
Server Sequenziali
Server che gestiscono una richiesta alla volta (con connessione o meno)
Con Connessione (uso TCP) Servizi che devono garantire affidabilit, limitando lo stato. Overhead per controllo connessione.
Necessaria quando i dati da scambiare sono molti per questioni di ordine e affidabilit (che tutto arrivi sicuramente).
Senza connessione (uso UDP) Servizi senza stato e poco soggetti a guasti
Server Paralleli
Server concorrente multiprocesso con pi richieste alla volta. Uso di processi multipli, con un master server (main) che genera processi
interni (thread) per ogni servizio.
In Java di difficile realizzazione un server concorrente monoprocesso.

Socket Datagram
Le socket datagram permettono a due thread diversi di scambiarsi messaggi senza stabilire una connessione tra i thread coinvolti.
Classe java.net.DatagramSocket. Modello non affidabile.
Uno dei costruttori presenta la seguente interfaccia
DatagramSocket( InetAddress localaddress, int localport) throws SocketException;
Una volta invocato il costruttore la socket pronta a realizzare uno scambio di messaggi con unaltra socket.
Lo scambio di messaggi con socket avviene tramite meccanismi primitivi di comunicazione. Su una istanza di DatagramSocket si fanno
azioni di:

void send(DatagramPacket p);

void receive(DatagramPacket p);

Le due primitive sono reali operazioni di comuncazione


La send invia il messaggio (asincrona con la receive) consegnando solamente il messaggio al livello sottostante (kernel) che si occuper
dellinvio.
La receive invece ha una semantica sinctona (localmente) per il ricevente (bloccante localmente): basta ricevere un messaggio per
sbloccare la receive.

Modello di comunicazione
Le socket datagram per lo scambio di messaggi devono essere state inizializzate correttamente e devono conoscersi.
Il mittente deve specificare nel messaggio un ricevente. Si devono specificare informazioni di tipo applicativo e di controllo (messaggio
e inirizzo IP e porta del destinatario). Quando il pacchetto arriva al destinatario le driver inseriscono nelle informazioni di controllo IP e
porta del mittente. Lo stesso datagramma viene usato per la richiesta e la risposta. Ovviamente nessuna garanzia di consegna con
qualit a causa del protocollo di supporto usato (UDP e IP).

Classi accessorie
DatagramPacket( byte [] buf, // array di byte dati
int offset, // indirizzo inizio
int length, // lunghezza dati
InetAddress address, int port); // numero IP e porta
Classe per preparare e usare datagrammi. Contiene una parte relativa ai dati e una relativa al controllo. Fornisce anche molte funzioni
di utilit come getPort, getData o getAddress.
Parte dati -> specifica un array di byte da/su cui scrivere e non indicazioni di comunicazione con diversi costruttori
Parte di controllo -> InetAddress e interi per la porta
InetAddress una classe che serve a rappresentare gli indirizzi IP (presenta solo metodi pubblici statici):
public static InetAddress getByName (String hostname);
fornisce un oggetto InetAddress per lhost specificato (null def. locale)
public static InetAddress[] getAllByName(String hostname);
fornisce un arra di oggetti InetAddress per pi indirizzi IP sullo stesso nome logico
public static InetAddress getLocalHost();
fornisce InetAddress per macchina locale
sock.send(DatagramPacket p) in invio bisogna preparare tutte le opportune strutture dati che servono a contenere la parte
dati del datagramma e larea relativa alle informazioni di controllo sul ricevente (fornite dal mittente del pacchetto.
sock.receive(DatagramPacket p) in ricezione si deve avere preparato tutto ci che serve a ricevere tutte le informazioni (sia
dati che controllo). Uno stesso pacchetto pu essere riutilizzato.

Esempio
Creazione socket
DatagramSocket socket = new DatagramSocket();
Parte mittente di invio...
Preparazione informazione da inviare e invio
byte[] buf = {'C','i','a','o'};
InetAddress addr = InetAddress.getByName("137.204.59.72"); int port = 1900;
DatagramPacket packet = new DatagramPacket(buf, buf.length, addr, port);
socket.send(packet); // invio immediato
In ricezione
Creazione socket
DatagramSocket socket = new DatagramSocket();
Parte ricevente di comunicazione: Preparazione, attesa, e ricezione
int recport; InetAddress recaddress; byte[] res = new byte[200];
DatagramPacket packet = new DatagramPacket(res, res.length, recaddress, recport);
packet.setData(res); // riaggancio della struttura dati
socket.receive(packet); // ricezione con attesa sincrona
// estrazione delle informazione dal datagramma
recport = packet.getPort();
recaddress = packet.getAddress();
res = packet.getData();
// uso delle informazioni ...

Comunicazione Multicast
MulticastSocket(int multicastport);
Socket legate a indirizzi IP di gruppo di classe D (necessario per riferimento) attraverso un gruppo di multicast su cui ricevere messaggi
(IP e porta). I nodi che devono ricevere devono prepararsi alla ricezione considerato che la comunicazione non pi punto-punto.
Il gruppo viene creato ed alimentato da ingressi, come registrazione o manifestazione di interesse, fino alluscita (join e leave). In java si
pu essere pi selettivi usando le porte: il gruppo composto solo da chi ha usato la stessa porta -> Si possono avere pi gruppi sullo
stesso indirizzo IP di classe D, distinti dalla porta.
Preparazione gruppo: IP classe D e porta libera
InetAddress gruppo = InetAddress.getByName("229.5.6.7");
MulticastSocket s = new MulticastSocket(6666);
Operazioni di ingresso/uscita dal gruppo (per ricevere)
// unisciti al gruppo ... e esci dal gruppo
s.joinGroup(gruppo); s.leaveGroup(gruppo);
// il sistema operativo pu tenere conto della porta per selezionare i messaggi

Opzioni Socket
La ricezione da socket (es., receive()) sincrona bloccante
SetSoTimeout (int timeout) throws
Questa opzione definisce un timeout in msec, dopo il quale la operazione termina (e viene lanciata una eccezione da gestire). Se
timeout a zero, nessuna sospensione.
SetSendBufferSize (int size) throws
Il buffer di invio e ricezione della driver pu essere variato
SetReceiveBufferSize (int size) throws
SetReuseAddress()
Si possono collegare pi processi ad un certo indirizzo fisico. Sono previste le get corrispondenti.

Socket a Stream
Nel caso delle socket Stream tra cliente e servitore di interpone una terza entit: la Connessione. La comunicazione avviene con
semantica at-most-once: comunicazione bidirezionale, affidabile (garanzie forti di QoS), con dati (byte) consegnati in sequenza una sola
volta.
La connessione tra processi client e server definita univocamente da una quadrupla e dal protocollo (non dai processi)
<indirizzo IP Client; porta Client; indirizzo IP Server; porta Server>
In questo modo basta cambiare anche solo una porta per ottenere una nuova connessione.
Protocollo utilizzato TCP+IP. TCP protocollo di trasporto (livello 4 OSI) che fornisce lastrazione della porta e IP, protocollo di rete
(Livello 3 OSI) per lidentificazione del nodo.
In Java per Client e Server esistono due tipi distinti di Socket (classi distinte per ruoli di Cliente e Servitore) e sono necessarie entrambe
per realizzare una comunicazione.
Le classi java.net.Socket e java.net.ServerSocket. Si nascondono i dettagli realizzativi dei protocolli, ad esempio nei
costruttori delle classi.
La classe Socket consente di creare una socket attiva connessa stream (TCP) per il collegamento di un client a un server.
I costruttori della classe creano la socket, la legano a una porta locale e la connettono a una porta di una macchina remota su cui sta il
server. La connessione permette poi una comunicazione bidirezionale (full duplex).
La creazione della socket produce in modo atomico anche la connessione al server corrispondente (deve essere presente).

Socket Stream Client


Costruttori

public Socket(InetAddress remoteHost, int remotePort) throws IOException;


Crea una socket stream cliente e la collega alla porta specificata della macchina allindirizzo IP dato
(equivale in Unix a: socket, bind, connect)
public Socket (String remoteHost, int remotePort)throws
Crea una socket stream cliente e la collega alla porta specificata della macchina di nome logico remoteHost
public Socket(InetAddress remoteHost, int remotePort, InetAddress localHost, int
localPort)throws
Crea una socket stream cliente e la collega sia a una porta della macchina locale (se localPort vale zero, il numero di porta
scelto automaticamente dal sistema) sia a una porta della macchina remota.

Gestione
APERTURA ottenuta con il costruttore in modo implicito. La creazione con successo di una socket a stream produce una
connessione bidirezionale a byte (stream) tra i due processi interagenti e impegna risorse sui nodi e tra i processi. Ha un costo anche
per il destinatario.
CHIUSURA come operazione necessaria per non impegnare troppe risorse di sistema. Le risorse sono le connessioni: costa definirle e
crearle, cos si devono gestirle al meglio, mantenerle e distruggerle. Si devono mantenere le sole connessioni necessarie e limitare le
aperture contemporanee di sessioni chiudendo quelle non utilizzate.
Il metodo close() chiude loggetto socket e disconnette il Client dal Server
public synchronized void close() throws SocketException;
Viene eseguita in modo atomico (in mutua esclusione) perch possono esserci pi thread che condividono una stessa socket.

Supporto
Per informazioni sulle socket si possono utilizzare i metodi aggiuntivi
public InetAddress getInetAddress(); // remote
Restituisce lindirizzo del nodo remoto a cui socket connessa
public InetAddress getLocalAddress(); // local
Restituisce lindirizzo della macchina locale
public int getPort(); // remote port
Restituisce il numero di porta sul nodo remoto cui socket connessa
public int getLocalPort(); // local
Restituisce il numero di porta locale a cui la socket legata
Esempio:
int porta = oggettoSocket.getPort();
Si possono ottenere dinamicamente (runtime) informazioni sulle connessioni correnti delle socket usate.
Quando si apre una connessione si aprono sempre due flussi di byte (leggere/scrivere dalla/sulla socket). Lettura o scrittura da/su una
socket dopo avere qualificato le risorse stream della socket come Java stream
public InputStream getInputStream()
public OutputStream getOutputStream()
I due metodi restituiscono un oggetto stream che incapsula il canale di comunicazione (di classi InputStream e OutputStream)
Attraverso gli stream (generici di byte) si possono spedire/ricevere solo byte, senza nessuna formattazione in messaggi (vedi classi)
Naturalmente, i byte arrivano ordinati e non duplicati (non possono arrivare byte successivi, senza che arrivino i precedenti); i dati
arrivano al pi una volta (at-most-once). In caso di errore? Nessuna conoscenza.
Altri oggetti stream Java possono incapsulare gli stream socket, per fornire funzionalit di pi alto livello (ad es., DataInputStream).
DataOutputStream e DataInputStream offrono una serie di metodi per linvio e la ricezione di tipi primitivi Java.
Uso tipico: realizzazione di protocolli fra Client e Server scritti in linguaggio Java (con scambio di oggetti Java): nel corso vengono usati
per la realizzazione di applicazioni C/S in Java.
DataOutputStream
DataInputStream
String void writeUTF(String s)
String readUTF()
char void writeChar(char c)
char readCHar()
int void writeInt(int i)
int readInt()
float void writeFloat(float f) float readFloat()

Esempio
Client di echo (il Server Unix sulla porta nota 7) progetto di filtro
try { oggSocket = new Socket(hostname, 7);
/* input ed output sugli endpoint della connessione via socket */
out = new PrintWriter (oggSocket.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(oggSocket.getIntputStream());
userInput = new BufferedReader(new InputStreamReader(System.in));
/* ciclo lettura fino a fine file */
while((oggLine = userInput.readLine()) != null)
{
out.println(oggLine); System.out.println(in.readLine());
}
oggSocket.close();
} catch (IOException e) { System.err.println(e);}
Per ogni ciclo si legge da standard input, si scrive sulla socket out e si attende da socket in la risposta di echo.

Socket Stream Server


Il Server ha un ruolo diverso: deve avere la possibilit di accodare le richieste (fase iniziale) e questo viene realizzato attraverso la
ServerSocket che definisce un tipo diverso di Socket capace di accettare richieste di connessione provenienti da diversi Client.
pi richieste di connessione pendenti allo stesso tempo e pi connessioni aperte contemporaneamente.
Si deve definire anche la lunghezza della coda in cui vengono messe le richieste di connessione non ancora accettate dal server.
Al momento della creazione si effettuano implicitamente le operazioni pi elementari visibili in UNIX, come socket, bind e listen
La connessione richiede di essere stabilita su iniziativa del server (ottenuta tramite primitiva di comunicazione accept).
Obiettivo della accept, lato server, restituire un normale oggetto Socket nel server per la specifica connessione e trasmissione dati.

Costruttori
Sulle socket dalla parte server:
public ServerSocket(int localPort) throws IOException, BindException;
Crea una socket in ascolto sulla porta specificata
public ServerSocket(int localPort, int count)
Crea una socket in ascolto sulla porta specificata con una coda di lunghezza count
Il server gioca un ruolo passivo: deve attivare la coda delle possibili richieste ed aspettare i clienti (attivi: effettuano la richiesta). Il
server comincia a decidere con la introduzione volontaria della primitiva di accettazione esplicita. Le richieste accodate non sono servite
automaticamente ed necessaria una API che esprima la volont di servizio.

Accept
Il Server si deve mettere in attesa di nuove richieste di connessione chiamando la primitiva accept()
public Socket accept() throws IOException;
Linvocazione di accept blocca il Server fino allarrivo di almeno una richiesta di connessione.
La accept restituisce un oggetto della classe Socket su cui avviene la comunicazione vera di byte tra Client e Server. Client e Server dopo
la connessione sono omogenei: si comportano esattamente allo stesso modo.
Quando arriva una richiesta, la accept crea una nuova socket per la connessione di trasporto gi creata con il Client: la nuova Socket
restituita dalla accept rappresenta lo stream reale con il cliente.
La chiamata di accept sospensiva, in attesa di richieste di connessione:
Se non ci sono ulteriori richieste, il servitore si blocca in attesa
Se c almeno una richiesta, si sblocca la primitiva e si crea la connessione per questa (la richiesta consumata)
NB: Tutte le socket su un server insistono sulla stessa (unica) porta.

Supporto
La trasmissione dei dati avviene con i metodi visti per il lato Client in modo del tutto indifferente in uno o l'altro verso della connessione
i due endpoint sono del tutto omogenei (come nel protocollo TCP)
Informazioni sulle socket connesse come nel cliente:
public InetAddress getInetAddress(); // remote
Restituisce lindirizzo del nodo remoto a cui socket connessa
public InetAddress getLocalAddress(); // local
Restituisce lindirizzo della macchina locale
public int getPort(); // remote port
Restituisce il numero di porta sul nodo remoto cui socket connessa
public int getLocalPort(); // local
Restituisce il numero di porta locale a cui la socket legata

Esempio
Server daytime (Server Unix su porta 13) progetto di demone
try { oggServer = new ServerSocket(portaDaytime);
while (true) /* il server alla connessione invia la data al cliente */
{ oggConnessione = oggServer.accept(); //attesa di connessioni
out = new PrintWriter(oggConnessione.getOutputStream(), true);
Date now = new Date(); // produce la data e la invia
out.write(now.toString()+ "\r\n");
oggConnessione.close(); // chiude la connessione e il servizio } }
catch (IOException e)
{ oggServer.close(); oggConnessione.close(); System.err.println(e);}
Ad ogni cliente il server sequenziale manda la data e chiude tutto

Server Parallelo
Alla accettazione delle richieste si genera un nuovo thread
responsabile del servizio (eredita la connessione nuova e la chiude al
termine delloperazione). Il servitore in questo modo pu tornare
immediatamente ad aspettare nuove richieste e servire nuove
richieste.
Quindi di tratta di un server parallelo multiprocesso con
connessione.
Limite al numero di socket: La socket come un file, ad ogni apertura
-> nuovo file descriptor -> Tabella dei file aperti, quindi un limite
abbastanza largo.

Chiusura di una Socket


Le socket in Java impegnano non solo il loro livello applicativo, ma anche una serie di risorse di sistema che sono collegate e necessarie
per la operativit fino alla close(). La chiusura quindi necessaria sempre per dichiarare al sistema la non necessit di mantenere
risorse non pi in uso.
Tipicamente la close() molto veloce (passante) a livello applicativo. Ai livelli sottostanti non la stessa cosa.
In caso di socket connessa chiusa, la memoria di out viene mantenuta per continuare a spedire informazioni da inviare al pari mentre
quella in ingresso viene buttata via. Questo potrebbe richiedere del tempo (anche molto).
La chiusura fatta su iniziativa di uno dei processi affacciati quando vuole ed ha impatto anche sullaltro.
Si hanno anche primitive differenziate per la chiusura per un verso solo, shutdownInput() e shutdownOutput()
La primitiva pi usata per chiusure responsabili la shutdownOutput() per cui si chiude la direzione di responsabilit.
In caso di socket connessa in shutdown, la memoria di out viene mantenuta per spedire informazioni al pari, la in soggetta allaltro.
Non si faranno mai di shutdown di input perch praticamente in una connessione bidirezionale ognuno padrone della propria uscita
ma non dellingresso (che dipende dallaltro responsabile della chiusura).

Opzioni
Opzioni delle Socket per cambiare il comportamento
SetSoLinger (boolean on, int linger) //Linger = stare intorno
Dopo la close, il sistema tenta di consegnare i pacchetti ancora in attesa di spedizione. Questa opzione permette di scartare i
pacchetti in attesa dopo un intervallo di linger in sec. La parte di out deve durare linger secondi dopo la close che, quindi,
durer massimo linger secondi.
SetTcpNoDelay (boolean on) throws ...
Il pacchetto inviato immediatamente, senza bufferizzare
SetKeepAlive (boolean on) throws...
Abilita, disabilita la opzione di keepalive. Vengono mandati dei messaggi di keepalive quando non succede niente nella
connessione.
Le opzioni sono disponibili nella interfaccia SocketOptions che prevede anche tutte le get corrispondenti.

RMI
(Remote Method Invocation)
RMI introduce la possibilit di richiedere esecuzione di metodi remoti in JAVA integrando il tutto con il paradigma Object Oriented.
un insieme di strumenti, politiche e meccanismi che permettono ad unapplicazione Java in esecuzione su una macchina di invocare i
metodi di un oggetto di una applicazione Java in esecuzione su una macchina remota.
Localmente viene creato solo il riferimento ad un oggetto remoto, che effettivamente attivo su un nodo remoto.
Un programma cliente invoca i metodi attraverso questo riferimento locale mantenuto in una variabile interfaccia.
La variabile locale, essendo di una certa, definita, interfaccia pu contenere istanze di classi che la implementano (anche diverse) ->
CAST per recuperare listanza giusta. Semantica per riferimento tipica dei linguaggi ad oggetti: una classe pu contenere riferimenti ad
altre classi (oltre a tipi primitivi). Questa, quando viene riferita, viene considerato tutto il grafo di oggetti legati alla classe. Quindi
quando, ad esempio, bisogna esternalizzare la classe si deve considerare tutto il grafo e non solo il primo livello.
Linterfaccia rappresenta un contratto di interazione (astratto) esponendo i metodi verranno implementati. Essendo interfacce possono
realizzare anche ereditariet multipla (impossibile tra classi). Grazie alla portabilit del codice java (via BYTECODE) si risolve il problema
delleterogeneit (JVM).

Architettura di RMI
Per realizzare laccesso ad un oggetto remoto tramite un riferimento remoto, in RMI (Java) si utilizzano due entit proxy (delegati):
Stub dalla parte del Cliente
Skeleton dalla parte del Servitore
Questi componenti nascondono al livello applicativo la natura distribuita dellapplicazione (pattern Proxy). Non possibile riferire
direttamente loggetto remoto -> necessit di una infrastruttura attiva e distribuita. Si definisce prima il contratto e successivamente di
definiscono, in modo quasi automatico, le entit proxy. Sono
classi gi pronte. In questo modo lutente si occupa solo della
parte applicativa. Solo interazioni SINCRONE BLOCCANTI.
Client e Server sono scritti dallutente, Stub e Skeleton sono
generati in modo quasi automatico a partire dal contratto
definito. Remote Reference Layer e Transport Layer fanno
parte della JVM. Il RRL, quando trasferisce variabili per
riferimento, trasferisce lintero grafo.
Server SEMPRE Parallelo -> metodi synchronized
Il trasporto SEMPRE connesso (TCP) -> perch si prevede una
necessit di banda molto elevata e con semantica at-most-once.
rmiregistry sistema di nomi in cui i servitori si devono registrare.
I Clienti per ottenere e raggiungere fanno una richiesta al rmiregistry in cui il servitore si registrato.
In tutto 3 entit (JVM): Cliente, Servitore, Registry. Schematizzando:
Stub e skeleton (sotto il controllo utente):
o Stub: proxy locale su cui vengono fatte le invocazioni destinate alloggetto remoto
o Skeleton: entit remota che riceve le invocazioni fatte sullo stub e le realizza effettuando le corrispondenti chiamate
sul server
Il livello Remote Reference Layer (RRL):
o Responsabile della gestione dei riferimenti agli oggetti remoti, dei parametri e delle astrazioni di stream-oriented
connection
Il livello di Trasporto connesso, Transport Layer
o Responsabile della gestione delle connessioni fra i diversi spazi di indirizzamento (JVM diverse)
o Gestisce il ciclo di vita delle connessioni e le attivazioni integrate in JVM
o Pu utilizzare protocolli applicativi diversi, purch siano connection oriented -> TCP a livello di trasporto
o Utilizza un protocollo proprietario
Il sistema di nomi, Registry: servizio di nomi che consente al server di pubblicare un servizio e al client di recuperarne il proxy

Caratteristiche RMI
Il cliente invoca un metodo di un oggetto remoto attraverso un riferimento remoto (variabile interfaccia). Rispetto al locale:
Sintassi: uguale -> trasparenza per il cliente. Chiamata sempre sincrona e bloccante con attesa.
Semantica: diversa
Chiamate locali -> affidabilit massima
Chiamate remote: comunicazione con possibilit di fallimento -> semantica at-most-once con uso TCP

Server remoto come locale: ogni chiamata esegue in modo indipendente e parallelo
I componenti remoti sono riferiti tramite variabili interfaccia (che possono contenere solo istanze di classi che implementano la
interfaccia)
Definizione del comportamento, con
o Interfaccia deve estendere java.rmi.Remote (segnala che deve essere visibile da remoto)
o Ogni metodo deve propagare java.rmi.RemoteException (eccezioni da remoto)
Implementazione comportamento, classe del Server
o Deve implementare linterfaccia definita
o Deve estendere java.rmi.UnicastRemoteObject
Passi per lutilizzo di RMI
1. Definire interfacce e implementazioni (server) dei componenti utilizzabili in remoto
2. Compilare le classi (con javac) e generare, successivamente, stub e skeleton (con rmic) delle classi utilizzabili in remoto
3. Pubblicare il servizio nel sistema di nomi, registry
a. Attivare il registry
b. Registrare il servizio (il server deve fare una bind sul registry)
4. Ottenere (lato client) il riferimento alloggetto remoto tramite il name service (facendo una lookup sul registry)
A questo punto linterazione tra il cliente e il server pu procedere

Esempio Echo
Intefaccia
public interface EchoInterface extends java.rmi.Remote {
String getEcho(String echo) throws java.rmi.RemoteException;
}

Deve obbligatoriamente estendere Remote. I metodi sono normali con un solo risultato, nessuno, uno o pi parametri di ingresso. I
parametri devono essere passati per valore (dati primitivi o oggetti Serializable) o per riferimento remoto (oggetti Remote).

Server

Client

public class EchoRMIServer


extends java.rmi.server.UnicastRemoteObject
implements EchoInterface{

public class EchoRMIClient


{
public static void main(String[] args)
{
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));

// Costruttore
public EchoRMIServer()
throws java.rmi.RemoteException
{ super(); }

try
{
// Connessione al servizio RMI remoto
EchoInterface serverRMI =
(EchoInterface)java.rmi.Naming.lookup(
"//localhost:1099/EchoService");

// Implementazione del metodo remoto


public String getEcho(String echo)
throws java.rmi.RemoteException
{ return echo; }
public static void main(String[] args){
// Registrazione del servizio
try
{
EchoRMIServer serverRMI = new EchoRMIServer();
Naming.rebind(
"//localhost:1099/EchoService", serverRMI);
}
catch (Exception e)
{e.printStackTrace(); System.exit(1); }
}

// Interazione con l'utente


String message, echo;
System.out.print("Messaggio? ");
message = stdIn.readLine();
// Richiesta del servizio remoto
echo = serverRMI.getEcho(message);
System.out.println("Echo: "+echo+"\n");
}
catch (Exception e)
{ e.printStackTrace(); System.exit(1); }

}
}

Deve implementare tutti i metodi definiti nellinterfaccia.


Entit attiva che prepara e registra il servitore sul registry creando
una nuova istanza (serverRMI).
Invoca tante operazioni di bind/rebind (se esiste lo sovrascrive)
quanti sono gli oggetti server da registrare ciascuno con un nome
logico. Rimane attivo finch c qualcosa che lo riferisce (anche se
finisce il main). In questo caso registry locale (default porta 1099)
al server.

Obiettivo del cliente poter invocare i metodi remoti. Per fare le


invocazioni remote si avvale della variabile interfaccia
(correttamente riempita con il riferimento remoto recuperato
con una lookup nel registry).
getEcho() Chiamata sincrona bloccante con i parametri
specificati in interfaccia.

RMI Registry
Localizzazione del servizio: un client in esecuzione su una macchina ha bisogno di
localizzare un server a cui connettersi, che in esecuzione su unaltra macchina ->
Servizio standard (naming service) in una locazione ben nota, che il client
conosce, funziona come punto di indirezione.
Sistema di nomi realizzato da un utente. Processo che ha lobiettivo di gestire una
tabella costituita da coppie nome del servizio e riferimento delloggetto che fornisce il
servizio. Lavora con una logica di unicit di nomi. un Server RMI.
RMI pensato per sistemi piccoli perch i riferimenti, rimanendo attivi, possono riempire rapidamente (e a lungo) la memoria visto che
possono essere anche remoti.

Classe Naming
Metodi della classe java.rmi.Naming:
public static void bind(String name, Remote obj)
public static void rebind(String name, Remote obj)
public static void unbind(String name)
public static String[] list(String name)
public static Remote lookup(String name)
Ognuno di questi metodi richiede la informazione al RMI registry identificato con host e porta come locazione name -> combina la
locazione del registry e il nome logico del servizio, nel formato: //registryHost:port/logical_name
registryHost = macchina su cui eseguono il registry e i servitori
port = 1099 a default
logical_name = il nome del servizio che vogliamo accedere
Attivazione registry (sullhost del server): usare il programma rmiregistry di Sun lanciato in una shell a parte specificando o meno la
porta (default 1099): rmiregistry oppure rmiregistry 10345.
N.B.: il registry attivato cos in una nuova istanza separata della JVM. possibile avviare il registry anche nella stessa JVM del Server.

Compilazione ed Esecuzione
Lato server
1. Compilazione interfaccia e implementazione parte server
javac EchoInterface.java
EchoRMIServer.java
Hash generato utile alla generazione di Stub e Skeleton.
2.

Generazione eseguibili Stub e Skeleton


rmic [-vcompat] EchoRMIServer
Genera:
EchoRMIServer_Stub.class (Client)
EchoRMIServer_Skel.class (Server)
Nota: vcompat in Java 1.5 e seguenti
Prodotti come eseguibili (non modificabili) perch molto legati ai livelli inferiori della JVM.

3.

Esecuzione lato server (registry e server)


a. Avviamento del registry: rmiregistry
b. Avviamento del server: java EchoRMIServer

Lato client
1. Compilazione: javac EchoRMIClient.java
2. Esecuzione: java EchoRMIClient

Stub e Skeleton
Rendono possibile la chiamata di un servizio remoto come se fosse locale (agiscono da proxy). Sono generati dal compilatore RMI.
Procedura di comunicazione
1. Il client ottiene un riferimento remoto con una richiesta (lookup) al registry (default porta 1099)
2. Il client chiama metodi sullo stub e aspetta il risultato (sincrono bloccante) da questo
3. Lo Stub:
Effettua la serializzazione delle informazioni per la chiamata (id del metodo identificazione - e argomenti)
Invia le informazioni allo skeleton utilizzando le astrazioni messe a disposizione dal RRL
4. Lo Skeleton:
Effettua la de-serializzazione dei dati ricevuti
Invoca la chiamata sulloggetto che implementa il server (dispatching)
Effettua la serializzazione del valore di ritorno e invio allo allo stub
5. Lo Stub:
Effettua la de-serializzazione del valore di ritorno
Restituisce il risultato al client

Passaggio dei parametri


Tipo
Tipi primitivi
Oggetti

Oggetti Remoti

Metodo Locale
Per valore
Per riferimento

Metodo Remoto
Per valore
Per valore (Serializable Object)
-> mandare il contenuto.
Deep Copy: viene copiato lintero grafo
associato alla classe.
Per riferimento remoto (Remote Object)

In Remoto: (problemi nel riferire entit e contenuti non locali)


Passaggio per valore => tipi primitivi e Serializable Object
Oggetti la cui locazione non rilevante per lo stato sono passati per valore: ne viene serializzata listanza che sar
deserializzata a destinazione per crearne una copia locale.
Passaggio per riferimento remoto => Remote Object
Oggetti la cui funzione strettamente legata alla localit in cui eseguono (server) sono passati per riferimento remoto: ne
viene serializzato lo stub (riferimento), creato automaticamente a partire dalla classe dello stub. Ogni istanza di stub identifica
loggetto remoto al quale si riferisce attraverso un identificativo (ObjID) che univoco rispetto alla JVM dove loggetto remoto
si trova.
Quindi gli oggetti remoti non vengono serializzati ma ne viene serializzato il riferimento -> stub orientato sulloggetto remoto
che contiene quindi solamente il riferimento remoto (leggero).
Lo stub contiene un riferimento remoto.
Il problema serializzazione dei parametri (sistemi eterogenei), grazie alluso di BYTECODE, in Java non si presenta visto che i dati
vengono semplicemente serializzati/deserializzati utilizzando le funzionalit offerte direttamente a livello di linguaggio => non ci sono
operazioni di marshalling e unmarshalling da gestire.
Serializzazione (o Linearizzazione): trasformazione di oggetti complessi in semplici sequenze di byte
Metodo writeObject() su uno stream di output
NON viene trasferito loggetto vero e proprio ma solo le informazioni contenute che caratterizzano listanza.
no metodi, no costanti, no variabili static, no variabili transient -> SOLO Dati, no codice. La classe rappresenta la parte
descrittiva dellentit trasferita.
Al momento della deserializzazione sar ricreata una copia dellistanza trasmessa usando il .class (che deve quindi
essere accessibile) delloggetto e le informazioni ricevute.
Deserializzazione: decodifica di una sequenza di byte e costruzione di una copia delloggetto originale
Metodo readObject() da uno stream di input
Controllo con versioning/ID che consente di verificare la correttezza dei dati ricevuti.
LID tipicamente un hash della classe.
Stub e Skeleton utilizzano queste funzionalit per lo scambio dei parametri di ingresso e uscita con lhost remoto.

Implementazione del Registry


Il Registry in realt un server RMI (quindi Parallelo)
Interfaccia: java.rmi.registry.Registry
Classe dimplementazione: sun.rmi.registry.RegistryImpl
public interface Registry extends Remote {
public static final int REGISTRY_PORT = 1099;
public Remote lookup(String name)
throws RemoteException, NotBoundException, AccessException;
public void bind(String name, Remote obj)
throws RemoteException, AlreadyBoundException, AccessException;
public static void rebind(String name, Remote obj)
throws RemoteException, AccessException;
public static void unbind(String name)
throws RemoteException, NotBoundException, AccessException;
public static String[] list(String name)
throws RemoteException, AccessException;
}

possibile anche creare allinterno del codice (del server) un proprio registry:
public static Registry createRegistry(int port)
che un metodo della classe LocateRegistry. In questo caso, il registry viene creato nella stessa istanza della JVM.

Implementazione dello Stub


Lo stub effettua linvocazione, gestisce la de/serializzazione, espedisce/riceve gli argomenti e il risultato
Si appoggia sul Remote Reference Layer (RRL)
Estende java.rmi.server.RemoteStub
Implementa java.rmi.Remote e linterfaccia remota del server (es. EchoInterface)
Contiene al suo interno unistanza del riferimento alloggetto remoto (super.ref di classe java.rmi.server.RemoteRef)

// creazione della chiamata


java.rmi.server.RemoteCall remotecall =
super.ref.newCall(this, operations,
0, 6658547101130801417L);

// de-serializzazione del valore di ritorno


String message1;
try{
ObjectInput objectinput =
remotecall.getInputStream();
message1 = (String)objectinput.readObject();
}

// 0 indica loperazione richiesta


// serializzazione dei parametri
try{
ObjectOutput objectoutput =
remotecall.getOutputStream();
objectoutput.writeObject(message);
}

// invocazione della chiamata, sul RRL


super.ref.invoke(remotecall);

//segnalazione chiamata andata a buon fine al RRL


finally{
super.ref.done(remotecall); //a cosa serve?!?
}
// restituzione del risultato
// al livello applicativo
return message1;

invoke va alla super-classe, la super-classe fa il codice per


portare il tutto dallaltra parte (ricevuto dallo skeleton)

Quando si riceve il risultato si sblocca lesecuzione del cliente, si


deserializza loggetto ricevuto sullo stream locale e viene
restituito. done: serve perch nella superclasse stato creato lo
stream.

Implementazione dello Skeleton


Lo skeleton gestisce la de/serializzazione, spedisce/riceve i dati appoggiandosi sul RRL, ed invoca il metodo richiesto (dispatching).
Metodo dispatch invocato dal RRL, con parametri dingresso
Riferimento al server (java.rmi.server.Remote)
Chiamata remota, numero operazione, e hash dellinterfaccia
public void dispatch(Remote remote,
RemoteCall remotecall,
int opnum, long hash)throws Exception{

EchoRMIServer echormiserver =
(EchoRMIServer)remote;
switch(opnum){
case 0: // operazione 0
String message;
try{ // de-serializzazione parametri
ObjectInput objectinput =
remotecall.getInputStream();
message =
(String)objectinput.readObject();
}
catch(){}
finally{ // libera il canale di input
remotecall.releaseInputStream();
}

dispatch perch lo skeleton riceve le


richieste da vari client -> possono
richiedere diversi metodi.
Ha lobiettivo di ricevere la richiesta
(unmarshalling dei parametri), portarla
verso lalto e restituire la risposta.
Tipicamente funziona in parallelo.
Grosso switch: in base al metodo
richiesto esegue loperazione locale.

// invocazione metodo
String message1 =
echormiserver.getEcho(message);
try{ // serializzazione del valore di ritorno
ObjectOutput objectoutput =
remotecall.getResultStream(true);
objectoutput.writeObject(message1);
}
catch(){}
break;
// gestione di eventuali altri metodi
default:
throw new UnmarshalException("invalid ...");
} //switch
} // dispatch

Alla fine invia la risposta ( con


marshalling) nello stream in uscita.
Non c threading. Parallelismo? nella
JVM che implementer in modo
parallelo il servizio che sta eseguendo.

Livello di trasporto: La concorrenza


Implementazione -> Server parallelo che deve essere thread-safe cio al livello applicativo dobbiamo comunque tenere in conto
problematiche di sincronizzazione => uso di lock: synchronized
In RMI si usano i thread di Java => Generazione (poco costosa) di un thread per ogni richiesta che arriva. Non nello skeleton ma nella
JVM.

Livello di trasporto: La comunicazione


In Java RMI trasposto connesso => Per motivi di utilizzo di banda maggiore e di qualit. Impegna risorse.
Allarrivo di una richiesta RMI si potrebbe:
1. Aprire (ingressi, uscite) e chiudere una sola connessione per ogni richiesta. (Costo elevato)
2. Condivisione di una connessione gi aperta.
3. Unica connessione tenuta aperta tra due JVM persistente per un tempo indefinito per servire richieste diverse. (Scelta di RMI)

Deployment Distribuzione della classi


In una applicazione RMI necessario che siano disponibili gli opportuni file .class nelle localit che lo richiedono (per lesecuzione o
per la de/serializzazione)
Il Server deve poter accedere a:
Interfacce che definiscono il servizio -> a tempo di compilazione

Il Client deve poter accedere a:


Interfacce che definiscono il servizio -> a tempo di compilazione

Implementazione del servizio -> a tempo di compilazione

Stub delle classi di implementazione del servizio -> a tempo di


esecuzione

stub e skeleton delle classi di implementazione -> a tempo di esecuzione


Classi del server usate dal client (es. valori di ritorno) -> a tempo di
compilazione o esecuzione
Altre classi utilizzate dal client -> a tempo di compilazione o esecuzione

Altre classi utilizzate dal server -> a tempo di compilazione o esecuzione

CLASSPATH ed esecuzione
Come la variabile dambiente PATH di Unix esiste per java la variabile CLASSPATH che dice a RMI dove cercare le cose di cui ha bisogno.
Sotto Linux: ci possibile aggiungendo nella propria directory HOME il file ".profile" (creandolo se non esiste). In particolare, il file
.profile deve contenere le seguenti linee per aggiungere il direttorio corrente al CLASSPATH:
CLASSPATH=.:$CLASSPATH
export CLASSPATH
(export -> passa la variabile ai processi figli della shell relativa)

RMI Class Loading


Tutte le classi e gli oggetti non sono caricati staticamente. Il ClassLoader quellentit capace di risolvere i problemi di caricamento
dinamico delle classi (a tempo di esecuzione, quando ce n bisogno).
Le classi possono essere caricate da locale come da remoto (peculiarit di Java).
In Java si definisce una gerarchia di ClassLoader, ciascuno responsabile del caricamento di classi diverse, anche definibili dallutente.
I ClassLoader costituiscono ciascuno una localit diversa luno dallaltro e non interferiscono uno con laltro: possono avere anche
visioni non consistenti.
Classloader: risolve i nomi delle classi nelle definizioni delle classi (codice bytecode).
Codebase Classloader (di Java RMI): Responsabili del caricamento di classi raggiungibili con un qualsiasi URL standard (codebase) ->
anche da remoto
Esempio Applet: Se si usasse lo stesso classloader che si usa per i caricamenti locali (quindi con la stessa fiducia) con classi remote ->
problemi evidenti di sicurezza e correttezza. Java ha stabilito che ne possono esistere diversi. Ciascuno riferisce una propria parte di
Heap -> pi affidabilit -> codice locale e codice remoto gestiti da classloader diversi. Si separa lambiente di esecuzione. Per ogni
classloader si pu definire uno scope di sicurezza.
Il Security Manager unentit attiva, un controllore di correttezza e sicurezza di ogni singola operazione
effettuata durante lesecuzione. Se le operazioni vanno contro le regole stabilite da un classloader le
operazioni vengono fermate (eccezione). Ogni ClassLoader pu avere un Security Manager.
Sia il client che il server devono essere lanciati specificando il file con le autorizzazioni (file di policy)
consultato dal security manager (per il controllo dinamico della sicurezza).
RMIClassLoader un Codebase ClassLoader. Ad esempio, se un cliente non ha lo stub, lo pu caricare dal
server tramite codebase. Serve quindi a indicare una specie di repository remoto in cui viene salvato tutto il
codice necessario allesecuzione.
Estrae il campo codebase dal riferimento delloggetto remoto
Usa i codebase classloader per caricare le classi necessarie dalla locazione remota
Ogni JVM pu specificare il codebase in modo diverso.
Nel caso sia necessario ottenere dinamicamente del codice (stub o classi). necessario:
1. Localizzare il codice (in locale o in remoto)
2. Effettuare il download (se in remoto)
3. Eseguire in modo sicuro il codice scaricato
Client e server di una applicazione RMI possono accedere una variabile codebase (annotata nel RemoteRef) in cui contenuto
lindirizzo remoto (URL) che indica dove possibile trovare tutto il codice necessario a tempo di esecuzione. LURL puo essere http, ftp
o locale (file://).
Per lesecuzione sicura del codice in RMI si richiede lutilizzo del RMISecurityManager
RMISecurityManager effettua il controllo degli accessi (specificati nel file di policy) alle risorse di sistema e blocca gli accessi
non autorizzati
Il security manager viene creato allinterno dellapplicazione RMI (sia lato client, sia lato server), se non ce n gi uno
istanziato
if (System.getSecurityManager() == null)
{System.setSecurityManager(new RMISecurityManager()); }

Esempio
Client: java -Djava.security.policy=echo.policy EchoRMIClient
Server: java -Djava.security.policy=echo.policy EchoRMIServer

Struttura del file di policy:


grant {
permission java.net.SocketPermission "*:1024-65535", "connect, accept";
permission java.net.SocketPermission "*:80", "connect";
permission java.io.File Permission "c:\\home\\RMIdir\\-", "read";
};

RMI Registry: il problema del bootstrap


Come avviene lavvio del sistema (bootstrap) e ritrovare il riferimento remoto?
Java mette a disposizione la classe Naming, che realizza dei metodi statici per effettuare le operazioni di de/registrazione e
reperimento del riferimento del server
I metodi per agire sul registry hanno bisogno dello stub del registry
Come ottenere unistanza dello stub del registry senza consultare un registry?
Costruzione locale dellistanza dello stub a partire da:
Indirizzo server e porta contenuti nel nome delloggetto remoto
Identificatore (locale alla macchina server) delloggetto registry fissato a priori dalla specifica RMI della SUN -> costante fissa
Domanda: assolutamente necessario un RMIRegistry per una interazione cliente/servitore in RMI?
NO perch si pu passare il riferimento remoto attraverso i parametri.
Problema di sicurezza: accedendo al registry (individuabile interrogando tutte le porte di un host) possibile ridirigere per scopi
maliziosi le chiamate ai server RMI registrati (es. list()+rebind())
Soluzione:
I metodi bind(), rebind() e unbind() sono invocabili solo dallhost su cui in esecuzione il registry -> non si accettano modifiche della
struttura client/server da nodi esterni
N.B.: da ci segue che sullhost in cui vengono effettuate le chiamate al registry deve essercene sempre almeno uno in esecuzione.

Universit degli Studi di Bologna


Facolt di Ingegneria

Corso di
Reti di Calcolatori T
Progetto C/S con Socket in C
Antonio Corradi
Anno accademico 2012/2013
Socket in C 1

COMUNICAZIONE e SOCKET
Necessit di Strumenti di Comunicazione per supportare
scambio di messaggi
Necessit di definire e di diffondere l'uso di strumenti
standard di comunicazione
Scenario con strumenti diversi, applicativi e di livello diverso
Livelli

Interfacce di comunicazione
Named Pipe

Applicazione

Presentazione

Sessione

Mail Slot

SPX

Sockets

APPC

NetIPC

Specifiche di protocollo
Directory

Applicazione

Presentazione

X.400
FTAM

TCP / UDP

Trasporto
IPX

RPC

Livelli
NetBIOS

TLI

Sessione

Trasporto

Presentazione

Rete
IP

Dati

Fisico

Sessione
Trasporto

socket come endpoint per comunicare in modo flessibile,


differenziato ed efficiente
Socket in C 2

UNIX: STRUMENTI di COMUNICAZIONE


UNIX modello e strumenti per comunicazione/sincronizzazione
Si definisce e si regola la comunicazione/sincronizzazione locale
Uso di segnali
processo invia un evento senza indicazione del mittente

Uso di file
solo tra processi che condividono il file system sullo stesso nodo

Poi, solo tra processi coresidenti sullo stesso nodo


pipe (solo tra processi con un avo in comune)
pipe con nome (per processi su una stessa macchina)
shared memory (stessa macchina)
Comunicazione e sincronizzazione remota
SOCKET Unix BSD (Berkeley Software Distribution)
Socket in C 3

UNIX: MODELLO di USO


In UNIX ogni sessione aperta sui file viene mantenuta attraverso un file
descriptor (fd) privato di ogni processo mantenuto in una tabella di kernel
Tabella dei
(tabella dei file aperti del processo)
descrittori
Paradigma di uso: open-read-write-close
apertura della sessione

Processo
Processo

operazioni della sessione (read / write)


chiusura della sessione

fd 0
fd 1

File

pipe

rete
Tabella dei file
aperti del processo

Socket descriptor
dominio
servizio

Le socket conformi a questo paradigma con


trasparenza rispetto alle azioni sul file system
Ovviamente, nella comunicazione si devono specificare
pi parametri per definire un collegamento con connessione:

protocollo
indirizzo locale
porta locale
connessione remota

Socket Connessa

protocollo di trasporto;
e quadrupla
< indirizzo locale; processo locale; indirizzo remoto; processo remoto>
Socket in C 4

pipe = socket locali in BSD

UNIX: PRIMITIVE
UNIX deve fornire funzioni primitive di comunicazione
UNIX Berkeley introduce il meccanismo di socket standard,
strumenti di comunicazione locali o remote con politiche differenziate, in
alternativa ai problemi degli strumenti concentrati, trasparente e ben
integrata con processi e file
SOCKET su cui i processi possono scrivere/leggere messaggi e
stream, con molte opzioni e requisiti

eterogeneit: comunicazione fra processi su architetture diverse


trasparenza: la comunicazione fra processi indipendentemente dalla
localizzazione fisica
efficienza: l'applicabilit delle socket limitata dalla sola performance
compatibilit: i naive process (filtri) devono potere lavorare in ambienti
distribuiti senza subire alcuna modifica
completezza: protocolli di comunicazione diversi e differenziati
Socket in C 5

UNIX: TRASPARENZA
Le socket come strumento con interfaccia omogenea a quella usuale
UNIX per i servizi da invocare in modo trasparente
Socket
endpoint della comunicazione
Socket descriptor integrato con i file descriptor
con protocolli di trasporto diversi e default TCP/IP (sia UDP sia TCP)
Chiamata
open( )
close( )
read( )
write( )
lseek( )
fctl( )
ioctl( )

Significato
Prepara un dispositivo o un file ad operazioni di
input/output
Termina l'uso di un dispositivo o un file
precedentemente aperto
Ottiene i dati da un dispositivo di input o da un file, e li
mette nella memoria del programma applicativo
Trasmette i dati dalla memoria applicativa a un
dispositivo di output o un file
Muove I/O pointer ad una specifica posizione in file
/dispositivo
Controlla le propriet di un file descriptor e le funzioni
di accesso
Controlla i dispositivi o il software usato per accedervi

Processo utente

Socket system call interface


Protocolli di trasporto e di rete
(es. TCP/IP)

Kernel

Gestore di data link


(es. Ethernet)

Socket in C 6

SOCKET: DOMINIO di COMUNICAZIONE


Dominio di comunicazione per socket come specifica del modello:
semantica di comunicazione + standard di nomi relativi
Esempi di domini: UNIX, Internet, etc.
Semantica di comunicazione include
- affidabilit di una trasmissione
- possibilit di lavorare in multicast non solo punto punto
Naming modo per indicare i punti terminali di comunicazione
Il dominio pi appropriato scelto tramite un'interfaccia standard
La prima scelta di esempio tra comunicazione con connessione e
senza connessione tipica di ogni dominio
DOMINI

descrizione

PF_UNIX

comunicazione locale tramite pipe

PF_INET

comunicazione mediante i protocolli


ARPA internet (TCP/IP)
................

...........

Socket in C 7

SCELTE di COMUNICAZIONE
Tipi di servizio e socket
datagram: scambio di messaggi senza garanzie (best effort)
stream: scambio bidirezionale di messaggi in ordine, senza errori, non
duplicati, nessun confine di messaggio, out-of-band flusso (stream virtuale
e non reale) semantica at-most-once

seqpacket: messaggi con numero di ordine (XNS)


raw: messaggi non trattati ma solo scambiati (per debug protocolli)
Protocolli diversi in ogni dominio di comunicazione
UNIX
(AF_UNIX)
Internet (AF_INET)
XEROX (AF_NS)
CCITT
(AF_CCITT) X.25

Socket in C 8

Ancora SCELTE di COMUNICAZIONE


Combinazioni possibili fra dominio e tipo con indicazione del
protocollo
Tipo socket
AF_UNIX AF_INET AF_NS
Stream socket
Datagram socket
Raw socket
Seq-pack socket

Possibile
Possibile
No
No

TCP
UDP
ICMP
No

SPP
IDP
Possibile
SPP

Protocolli pi probabili nello standard Berkeley


prefisso AF
Address Family
PF_UNIX, PF_INET, PF_NS,
prefisso PF Protocol Family
cio address family
PF_SNA, PF_DECnet e
PF_APPLETALK

AF_INET
AF_INET
AF_INET
AF_INET
AF_NS
AF_NS
AF_NS
AF_NS
AF_UNIX
AF_UNIX

Stream
Datagram
Raw
Raw
Stream
Seq-pack
Raw
Raw
Datagram
Stream

IPPROTO_TCP
IPPROTO_UDP
IPPROTO_ICMP
IPPROTO_RAW
NSRPROTO_SPP
NSRPROTO_SPP
NSRPROTO_ERROR
NSRPROTO_RAW
IPPROTO_UDP
IPPROTO_TCP

TCP
UDP
ICMP
(raw)
SPP
SPP
Error Protocol
(raw)
UDP
TCP
Socket in C 9

(Inizio registrazione)

Dominio es Internet

Un end-point viene identificato, in generale da una tripla { Dominio, IP, Porta }

SISTEMA di NOMI per le SOCKET


Nomi logici delle socket (nomi LOCALI) indirizzo di socket nel dominio
Nomi fisici da associare (nomi GLOBALI) una porta sul nodo
una socket deve essere collegata al sistema fisico e richiede binding, cio
il legame tra socket logica ed entit fisica corrispondente

Half-association come coppia di nomi logica e fisica


dominio Internet: socket collegata a porta locale al nodo
{ famiglia indirizzo, indirizzo Internet, numero di porta}
dominio UNIX: socket legata al file system locale
{famiglia indirizzo, path nel filesystem, file associato}
dominio CCITT: indirizzamento legato al protocollo di rete X.25

In Internet
Nodi nomi IP
{identificatore_rete, identificatore_host}
Porta numeri distintivi sul nodo (1-1023 di sistema, 1024-65535 liberi)
Socket in C 10

(2:50)

Porta s.sin_port
Indirizzo s.sin_addr.s_addr

TIPI per INDIRIZZI e NOMI SOCKET


Per le variabili che rappresentano i nomi delle socket si deve
considerare la necessit di flessibilit degli indirizzi
Struttura Completa 16 byte
Socket address in due tipi di strutture
sockaddr (indirizzo generico)
sockaddr_in (famiglia AF_INET)
struct sockaddr { u_short sa_family; char sa_data[14];}
struct sockaddr_in
{u_short sin_family; u_short sin_port;
struct in_addr sin_addr; /* char sin_zero [8]; non usata */}
struct in_addr
{u_long
s_addr};
struct sockaddr_in mioindirizzosocket; /* variabile per il nome*/
sin_family famiglia di indirizzamento
sin_port
sin_addr

sempre AF_INET

numero di porta
indirizzo Internet del nodo remoto (numero IP)
Socket in C 11

(9:05)

INDIRIZZI e NOMI SOCKET


Si usano strutture dati per i nomi fisici che servono alla applicazione
RAPPRESENTAZIONE dei NOMI in C
struct sockaddr
sa_family
2 BYTE

sa_data
14 BYTE

struct sockaddr_in
Sin_family
(AF_INET)

sin_port sin_addr

2 BYTE

2 BYTE

sin_zero
000000000000

4 BYTE

8 BYTE

14 BYTE

I programmi usano di solito un puntatore generico ad una locazione di


memoria del tipo necessario
char * in C
void * in ANSI C
Si vedano i file di inclusione tipici
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

Indirizzo generico che pu puntare a qualunque


cosa in memoria (diverso da java in cui gli indirizzi
sono solo "logici")
Non ha la definizione del puntato -> CAST
Socket in C 12

(16:50)

FUNZIONI di SUPPORTO ai NOMI


Un utente conosce il nome logico Internet di un Host remoto come
stringa e non conosce il nome fisico corrispondente
corrispondenza tra nome logico e nome fisico per le primitive
primitiva gethostbyname() restituisce l'indirizzo Internet e dettagli
prendendo in ingresso una stringa es nome logico e

#include <netdb.h>
ritorna un nome fisico
struct hostent * gethostbyname (name)
char * name;
gethostbyname restituisce un puntatore alla struttura hostent oppure NULL
se fallisce; il parametro name ricercato nel file /etc/hosts che si comporta
come una tabella di corrispondenze, ad esempio
137.204.56.11
137.204.56.12
137.204.56.13

didahp1
didahp2
didahp3

hp1
hp2
hp3

La ricerca avviene localmente, poi integrata anche con strumenti


come sistemi di nomi (DNS)
Socket in C

(20:20)

P
primo

char ** P;
4 byte

a
b
c

13

punta al primo elemento

0 bin

FUNZIONE GETHOSTBYNAME
Struttura hostent (intesa come descrizione completa di host)
struct hostent {
/* nome ufficiale dell'host */
char * h_name;
char ** h_aliases;
/* lista degli aliases */ lista di stringhe
int
h_addrtype; /* tipo dell'indirizzo host */
int
h_length;
/* lunghezza del'indirizzo */
char ** h_addr_list; /* lista indirizzi dai nomi host */ lista dei possibili ip della macchina
#define h_addr h_addr_list[0] /* indirizzo nome host */
indirizzo canonico -> il primo della lista
}

La struttura hostent permette di avere informazioni del tutto complete


di un nodo di cui abbiamo un nome logico
Le informazioni pi rilevanti sono il nome fisico primario (primo nella
lista, cio h_addr) e la sua lunghezza (in Internet fissa), ma anche
lista di nomi logici e fisici
Ogni indirizzo caratterizzato da contenuto e lunghezza (variabile)

Socket in C 14

(27:58)

USO GETHOSTBYNAME
Esempio di utilizzo della gehostbyname per risolvere lindirizzo
logico: si usa una variabile di appoggio riferita tramite puntatore che
ha valore in caso di successo per dare valore a peeraddr
#include <netdb.h>

struct hostent * hp;


struct sockaddr_in
peeraddr;
peeraddr.sin_family = AF_INET;
peeraddr.sin_port
= 22375;
if (hp = gethostbyname (argv[1]) ) /* in caso di successo */
peeraddr.sin_addr.s_addr = /* assegnamento dei 4 byte IP */
((struct in_addr *) /* casting */
(hp->h_addr)) -> s_addr;
else /* errore o azione alternativa */

In ogni caso, si cerca di ottenere il valore di IP nel campo corretto

Socket in C 15

(33:42)

FUNZIONE GETSERVBYNAME
In modo simile, per consentire ad un utente di usare dei nomi logici
di servizio senza ricordare la porta, la funzione getservbyname()
di utilit restituisce il numero di porta relativo ad un servizio
Anche se non ci sono corrispondenze obbligatorie, la pratica di uso ha
portato ad una serie di porte note (well-known port) associate stabilmente
a servizi noti, per consentire una pi facile richiesta

file /etc/services come tabella di corrispondenze fra servizi e porte su


cui si cerca la corrspondenza {nome servizio, protocollo, porta}
echo
systat
daytime
daytime
qotd
ftp-data
ftp

7/tcp
11/tcp users
13/tcp
13/udp
17/tcp quote
20/tcp
21/tcp

# Echo
# Active Users
# Daytime
#
# Quote of the Day
# File Transfer Protocol (Data)
# File Transfer Protocol (Control)
Socket in C 16

(36:25)

USO GETSERVBYNAME
Esempio di utilizzo della getservbyname per trovare numero di porta
usando una variabile di appoggio riferita tramite puntatore che
permette di ritrovare il numero di porta nel campo s_port
#include <netdb.h>
struct servent * getservbyname (name, proto)
char *name, *proto;

/* se TCP l'unico servizio registrato con quel nome, allora 0 */


Si utilizza prima di usare lindirizzo del servizio (tipo sockaddress_in), per
dare valore alla parte di numero di porta
#include <netdb.h>
/* vedi formato del record struct servent */
struct servent *sp;
struct sockaddr_in peeraddr;
sp = getservbyname("echo","tcp");
peeraddr.sin_port = sp->s_port; /* assegnamento della porta */
Socket in C 17

(37:50)

Primitive locali e passanti.

PRIMITIVE PRELIMINARI
Per lavorare sulle socket sono preliminari due primitive di nome
Per il nome logico LOCALE, si deve creare socket in ogni processo
risultato positivo o nullo
s = socket (dominio, tipo, protocollo)
negativo se errori nei parametri
int s,
/* file descriptor associato alla socket */
crea un fd nella tabella dei file aperti
dominio,
/* UNIX, Internet, etc. */
tipo,
/* datagram, stream, etc. */
protocollo;
/* quale protocollo */

Si introdotta una nuova azione per limpegno dei nomi fisici


GLOBALI, attuando laggancio al sistema 'fisico di nodi e porte
rok = bind (s, nome, lungnome) collega la socket a un indirizzo fisico
int rok, s;
/* le primitive restituiscono valore positivo se ok */
struct sockaddr *nome; /* indirizzo locale per la socket */ inizio
lunghezza dell'area
int lungnome;
/* lunghezza indirizzo locale */
Le primitive di nome sono significative ed essenziali entrambe

Socket in C 18
Se risultato negativo es porta occupata o altri errori del genere tipo ip non locale o
un socket descriptor non valido
Per lavorare senza connessione queste due primitive bastano come intro.

SOCKET DATAGRAM
Le socket datagram sono dei veri end-point di comunicazione e
permettono di formare half-association (relative ad un solo
processo), ma usabili per comunicare con chiunque del dominio
Si possono scambiare messaggi (datagrammi) sapendo/avendo:
processo Mittente o Cliente
* dichiarazione delle variabili di riferimento a una socket
* conoscenza dell'indirizzo Internet del nodo remoto
* conoscenza della porta del servizio da usare

processo Ricevente o Server


* dichiarazione delle variabili di riferimento a una socket
* conoscenza della porta per il servizio da offrire
* ricezione su qualunque indirizzo IP locale (wildcard address)
utile per server con pi connessioni, detti multiporta
Socket in C 19

SOCKET DATAGRAM
Le socket datagram sono degli end-point per comunicazione
con chiunque del dominio
processo Mittente o Cliente
processo Ricevente o Server
Socket A
(bound)

- il client ha creato la socket


- il client ha collegato la socket ad
un indirizzo

Socket B (bound)

- il server ha creato la socket


- il server ha collegato la socket ad
un indirizzo

Le socket datagram permettono direttamente di fare delle azioni di


invio/ricezione a chiunque rispetti il protocollo
Socket in C 20

PROTOCOLLO DATAGRAM
Le socket datagram sono usate con un protocollo che si basa
sulla sequenza di primitive qui sotto (alcune opzionali, quali?)

Client
Dichiarazione argomenti delle chiamate

Creazione socket

Collegamento socket

bind()

sendto() o write()

Invio dati

Ricezione dati

Chiusura

socket()

recvfrom() o read()

close() o shutdown()

Server
Dichiarazione argomenti delle chiamate

Creazione socket

socket()

Collegamento socket

bind()

Ricezione dati recvfrom()

Invio dati

Chiusura

Azioni
simmetriche

o read()

sendto() o write()

Azioni
simmetriche

close() o shutdown()

Socket in C 21

PRIMITIVE di COMUNICAZIONE
Per comunicare ci sono due primitive, di invio e ricezione datagrammi
nbytes = sendto (s, msg, len, flags, to, tolen)
int s, nbytes; char *msg; /* area che contiene i dati */
int len, flags; /* indirizzo, lunghezza e flag di operazione */
struct sockaddr_in *to; int tolen; /* indirizzo e lunghezza*/
nbytes = recvfrom (s, buf, len, flags, from, fromlen)
int s, nbytes; char *buf; /* area per contenere dati */
int len,flags; /* indirizzo, lunghezza e flag di operazione */
struct sockaddr_in *from; int * fromlen; /* ind e lung. ind.*/

restituiscono il numero dei byte trasmessi/ricevuti


nbytes lunghezza messaggio inviato/ricevuto
s socket descriptor
buf, len puntatore al messaggio o area e sua lunghezza
flags flag (MSG_PEEK lascia il messaggio sulla socket)
to/from/tolen/fromlen puntatore alla socket partner e sua lunghezza
Socket in C 22

USO delle SOCKET DATAGRAM


I mittenti/riceventi preparano sia le socket, sia le aree di memoria da
scambiare, tramite messaggi (sendto e recvfrom)
I datagrammi scambiati sono messaggi di lunghezza limitata su
cui si opera con una unica azione, in invio e ricezione (in modo unico)
senza affidabilit alcuna
Lunghezza massima del messaggio (spesso 9K byte o 16K byte)
Uso del protocollo UDP e IP, non affidabili intrinsecamente

NON tutti i datagrammi inviati arrivano effettivamente al ricevente


recvfrom restituisce solo un datagramma per volta
per prevenire situazioni di perdita di parti di messaggio massima area
possibile

A livello utente si pu ottenere maggiore affidabilit prevedendo


invio di molti dati insieme (mai mandare 2 datagrammi, se basta 1)
ritrasmissione dei messaggi e richiesta di datagramma di conferma
Socket in C 23

ESEMPIO di C/S con DATAGRAM


CLIENTE (MITTENTE) /* assumiamo che siano state invocate le socket e

bind corrette e che in msg ci siano valori da trasmettere */


struct sockaddr_in * servaddr; char msg[2000]; int count;
count = sendto (s, msg, strlen(msg), 0,
servaddr, sizeof(struct sockaddr_in));
close (s); /* se non si usa la socket, si deve chiuderla */

/* anche qui sono state fatte le socket e bind, e si


definito il buffer per contenere le informazioni ricevute */
SERVITORE (RICEVENTE)

struct sockaddr_in * clientaddr;


char buffer[BUFFERSIZE]; int count, addrlen;
addrlen = sizeof(sockaddr_in); /* valore di ritorno */
count = recvfrom(s, buffer,BUFFERSIZE,0, clientaddr,&addrlen);
close (s);

/* la ricezione legge il datagramma sullo spazio riservato:


e se non ci sta? */

Socket in C 24

PROTOCOLLO C/S con DATAGRAM


I datagrammi sono semplici messaggi che spesso permettono di
realizzare interazioni Cliente/Servitore
Server Process
socket()

Client Process

bind()

socket()

recvfrom()

<attesa
richiesta>

sendto()
2
recvfrom()
<attesa risp>

<elaborazione>

sendto()
close()

close()
Socket in C 25

PROPRIET dei DATAGRAM


In caso di scambi con datagrammi - e socket relative, ossia Client e
Server realizzati con socket UDP
UDP non affidabile
in caso di perdita del messaggio del Client o della risposta del Server, il
Client si blocca in attesa indefinita della risposta (utilizzo di timeout?)

possibile blocco del Client in attesa di risposta che non arriva


anche nel caso di invio di una richiesta a un Server non attivo non
segnalati errori (errori notificati solo su socket connesse)

UDP non ha alcun controllo di flusso (flow control)


se il Server riceve troppi datagrammi per le sue capacit di elaborazione,
questi vengono scartati, senza nessuna notifica ai Client
la coda (area di memoria per accodare messaggi in IN/OUT per ogni
socket) si pu modificare in dimensione con l'uso di opzioni
SO_RCVBUF/ SO_SENDBUF
Socket in C 26

PRIMITIVE SOCKET PASSO PASSO


Uso di alcune costanti molto utili e comode
Per esempio, per denominare tutti gli indirizzi Internet locali

Uso di wildcard address


Viene riconosciuto INADDR_ANY un indirizzo di socket locale
interpretato come qualunque indirizzo valido per il nodo corrente
Particolarmente utile per server in caso di residenza su workstation con
pi indirizzi Internet per accettare le connessioni da ogni indirizzo
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
struct sockaddr_in sin;
sin.sin_addr.s_addr= INADDR_ANY; /* qualunque indirizzo IP */

<<identificazione della socket>>


Socket in C 27

ESEMPIO di C/S con SOCKET


Usiamo come esempio il caso di Echo, parte server (porta 7), ossia
un servizio che rimanda al mittente ogni datagramma che arriva
Per migliore leggibilit si ipotizzi di avere creato delle semplici funzioni
Bind, Socket, Sendto, etc. che incapsulano le rispettive primitive bind,
socket, sendto, etc. e gestiscano gli errori

Parte dichiarativa iniziale e uso di funzioni per azzerare aree (bzero)


int sockfd, n, len;
char mesg[MAXLINE];
/* due socket, una locale e una remota */
struct sockaddr_in server_address, client_address;
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
bzero(&server_address, sizeof(server_address);
server_address.sin_family
= AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port
= 7;
Socket in C 28

ESEMPIO di SERVER DATAGRAM


Abbiamo considerato incapsulate le primitive in una libreria C (altro
file) che racchiude il tutto con una funzione omonima ma che tratta il
caso di errore
Bind(sockfd, &server_address, sizeof(server_address));
/* il server si sviluppa in un ciclo infinito, non termina mai */
for (;;)
{
len = sizeof (client_address);
n = Recvfrom(sockfd, mesg, MAXLINE, 0,
&client_address, &len);
m = Sendto(sockfd, mesg, n, 0,
&client_address, len);
}
Come sono le nuove funzioni che incapsulano le primitive?
Socket in C 29

ESEMPIO di LIBRERIA in C (repetita )


Una libreria C si sviluppa sempre su due file,
uno dichiarativo (file.h) che contiene solo dichiarazioni di
procedure/funzioni (solo firme),
uno operativo che contiene il reale codice ed esprime le reali
operazioni (file.c)
Nel nostro caso i due file sono socketDatagram.h, che contiene
int Bind(int sockfd,
struct sockaddr_in sock, int socklen);
Il primo file va incluso in ogni programma che ne abbia bisogno

Nel file socketDatagram.c abbiamo il vero e proprio codice (con


eventuali variabili, ecc.) da linkare con i programmi che lo usano
int Bind(int sockfd, struct sockaddr_in sock, int socklen)

{ int res = bind(sockfd, sock, socklen);


if (res>=0)return res;
else /* gestisci uscita con exit */ ; }

Socket in C 30

SOCKET STREAM
Le socket stream prevedono una risorsa che rappresenta la

connessione virtuale tra le entit interagenti


PROTOCOLLO e RUOLI differenziati CLIENTE/SERVITORE
una entit (cliente) richiede il servizio
una entit (server) accetta il servizio e risponde

ruolo attivo/passivo nello stabilire la connessione


entit attiva richiede la connessione, la entit passiva accetta
primitive diverse e comportamento differenziato allinizio
coda d'ascolto
Socket A (bound)

- il client ha fatto una richiesta


di connessione

Socket B
in ascolto

(bound)

- il server ha ricevuto una richiesta


nella coda d'ascolto

Socket in C 31

SOCKET STREAM: CONNESSIONE


Una volta stabilita la connessione la comunicazione tra le
entit interagenti del tutto simmetrica
coda d'ascolto
Socket A (bound)

Socket B
(bound)
Socket C
(bound)

Connessione

- il server ha accettato la richiesta


di connessione
- il server ha stabilito una connessione
con il client mediante una nuova socket
con le stesse caratteristiche della originale
- la socket originale continua ad ascoltare le
eventuali richieste di connessione

ruolo attivo/passivo di entrambi che possono inviare/ricevere


informazioni
naturale ruolo attivo del client che comincia la comunicazione
primitive diverse e comportamento differenziato allinizio
Socket in C 32

PROTOCOLLO SOCKET STREAM


Le socket stream sono usate con un protocollo a sequenza
differenziata di primitive e con ruoli diversi, per poi arrivare alla
omogeneit dopo avere stabilito la connessione
Client

Dichiarazione argomenti delle chiamate

Creazione socket

Collegamento socket

parte
asimmetrica

socket()
bind()

Richiesta di connessione

opzionale

connect()

ruolo attivo

Dichiarazione argomenti delle chiamate

Creazione socket

socket()

Collegamento socket

bind()

Attesa richieste

listen()

Accettazione connessione

parte
simmetrica

send() o write()

Invio dati

Ricezione dati

Chiusura

recv() o read()

close() o shutdown()

Ricezione dati

recv() o read()

send() o write()

Invio dati

Chiusura

accept()

Server

parte
asimmetrica
ruolo passivo
parte
simmetrica

close() o shutdown()

Socket in C 33

SOCKET STREAM CONNESSE


La CONNESSIONE, una volta stabilita, permane fino alla chiusura
di una delle due half-association, ossia alla decisione di uno due
entit interagenti (ancora scelta omogenea)
Sulla connessione i due interagenti possono sia mandare/ricevere
byte (come messaggi utente) send / recv, ma anche possono fare
azioni semplificate, e uniformi alle semplici sui file, read / write
recnum =
sentnum =

read (s, buff, length);


write(s, buff, length);

Processi naive possono sfruttare le socket stream, una volta stabilita


la connessione, per lavorare in modo trasparente in remoto
come fanno i filtri (o) che leggono da input e scrivono su output (vedi
ridirezione, piping, ecc.) per nel distribuito

Processi pi intelligenti possono sfruttano la piena potenzialit delle


primitive delle socket
Socket in C 34

PRIMITIVE SOCKET: SOCKET()


Sia il cliente, sia il servitore devono per prima cosa dichiarare la
risorsa di comunicazione a livello locale
Creazione di una socket specificando: {famiglia d'indirizzamento,
tipo, protocollo di trasporto} ossia il nome logico locale
socket() fa solo creazione locale
#include <sys/types.h>
#include <sys/socket.h>

int socket (af, type, protocol)


int af, type, protocol; /* parametri tutti costanti intere*/
protocollo di trasporto default 0, oppure uno specifico

socket() restituisce un socket descriptor o -1 se la creazione fallisce


int s; /* il valore intero >= 0 corretto, negativo errore*/
s = socket (AF_INET,SOCK_STREAM,0);

socket deve poi legarsi al nome globale e visibile

Socket in C 35

PRIMITIVE SOCKET: BIND()


Una socket deve essere legata al livello di nomi globali ossia visibili
La bind() collega la socket creata localmente alla porta e nodo globali
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int bind (s, addr, addrlen) int s;


struct sockaddr_in *addr; int addrlen;
s
socket descriptor che identifica la socket a livello locale
addr
struttura con indirizzo di porta nome nodo stesso
addrlen la lunghezza di addr

La bind crea half-association protocollo: < IP locale; porta locale;> per


protocollo: <IP locale; porta locale; IP remoto; porta remota>
Ogni nodo che vede essere contattato e visibile deve fare la bind
Socket in C 36

USO PRIMITIVE SOCKET: BIND()


Ogni server che deve essere raggiunto dai clienti deve fare la bind
I clienti possono fare la bind o meno, perch non hanno necessit di
essere visibili in modo esterno, ma solo con meccanismo di risposta
il cliente pu anche farsi assegnare una porta dal sistema
Spesso i clienti non fanno bind ma viene invocata solo in modo implicito
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int s, addrlen = sizeof(struc sockaddr_in);


struct sockaddr_in *addr; /* impostazione dei valori locali, con
possibili assegnamenti di nodo e porta per lindirizzo locale */
/* addr con sin_port a 0 richiede una assegnazione di un numero di porta
libero in alcuni sistemi (come fare se non disponibile?)*/
s = socket (AF_INET,SOCK_STREAM,0);
res = bind (s, addr, addrlen);
if (res<0) /* errore e exit */

else /* procedi */

Socket in C 37

SOCKET CLIENT: CONNECT()


Il client deve creare una connessione prima di comunicare
#include
#include
#include
#include

<sys/types.h>
<netinet/in.h>
<sys/socket.h>
<errno.h>

int connect (s, addr, addrlen)


int s;
struct sockaddr_in *addr;
int addrlen;
s
socket descriptor
addr
puntatore al socket address remoto
addrlen
lunghezza di questa struttura
risultato
se negativo errore, se positivo restituisce il file descriptor

La primitiva connect() una primitiva di comunicazione, sincrona,


e termina quando la richiesta accodata o in caso di errore rilevato
Al termine della connect la connessione creata (almeno lato cliente)
protocollo: <IP locale; porta locale; IP remoto; porta remota>

Socket in C 38

SOCKET CLIENT: CONNECT()


La connessione il veicolo per ogni comunicazione fatta attraverso il
canale virtuale di comunicazione
La primitiva connect() la controparte per il coordinamento iniziale
del cliente che ha la iniziativa e si attiva per preparare le risorse
La primitiva pu avere tempi di completamento anche elevati
La primitiva una reale primitiva di comunicazione remota
Al completamento, in caso di errore (risultato <0), la motivazione del
problema nel valore nella variabile errno (file /usr/include/errno.h)
EISCONN - una socket non pu essere connessa pi volte per non
duplicare connessioni e produrre ambiguit
ETIMEDOUT - tentativo di connessione in time-out: la coda d'ascolto del
server piena o non creata
ECONNREFUSED - impossibilit di connessione

In caso di successo, il client considera la connessione stabilita (?)


Socket in C 39

USO SOCKET CLIENT: CONNECT()


La primitiva connect() anche capace di fare eseguire la bind
il sistema assegna al cliente la prima porta libera facendo una bind
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int s, addrlen = sizeof(struc sockaddr_in);


struct sockaddr_in *peeraddr; /* impostazione dei valori del server,
con uso di gethostbyname e gestservbyname eventualmente */
s = socket (AF_INET,SOCK_STREAM,0);
res = connect (s, addr, addrlen);
if (res<0) /* errore e exit */
else /* procedi avendo realizzato la connessione */

La connect() deposita la richiesta di connessione nella coda del


servitore e non attua la connessione con il server (sopra TX)
Azioni successive potrebbero fallire a causa di questa potenziale
dissincronicit

Socket in C 40

SOCKET SERVER: LISTEN()


Il server deve creare una coda per possibili richieste di servizio
int listen (s, backlog)
int s, backlog;
s
socket descriptor
backlog
numero di posizioni sulla coda di richieste
(1-10, tipicamente 5)
risultato
se negativo errore, se positivo restituisce il file descriptor

La primitiva listen() una primitiva locale, senza attesa e fallisce


solo se attuata su socket non adatte (no socket(), no bind(), )
Al termine della listen, la coda disponibile per accettare richieste di
connessione (connect()) nel numero specificato
Una richiesta accodata fa terminare con successo la connect()
Le richieste oltre la coda sono semplicemente scartate, la connect()
fallisce dalla parte cliente; nessuna indicazione di nessun tipo al server
Socket in C 41

C
s=socket()
[bind()]
(2) connect()
send/receive
read/write

S
(inizio registrazione 29.10)
s=socket()
bind()
(1) listen()
(3) ns = accept() nuova socket

SOCKET SERVER: ACCEPT()

Il server deve trattare ogni singola richiesta accodata con

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int accept (ls, addr, addrlen)


int ls, *addrlen; struct sockaddr_in *addr;
ls
socket descriptor
si ottengono informazioni sulla connessione tramite *addr e *addrlen
addr
indirizzo del socket address connesso
addrlen
la lunghezza espressa in byte
risultato
se negativo errore,
se positivo restituisce una nuova socket connessa al cliente
La primitiva accept() una primitiva locale, con attesa, e correlata

alla comunicazione con il cliente: se ha successo produce la vera


connessione, se fallisce, in caso di socket non adatte (no socket(),
no bind(), no listen(), ), non consente di proseguire
Socket in C

42

(6:34)

SOCKET SERVER: ACCEPT()


La connessione il veicolo per ogni comunicazione
La primitiva accept() la controparte per il coordinamento iniziale
del server che non ha la iniziativa ma deve decidere autonomamente
quando e se attivare la reale connessione
La primitiva pu avere tempi di completamento anche elevati
La primitiva lavora in locale recuperando dati da comunicazione remota
Al completamento, in caso di successo, la nuova socket:
ha una semantica di comunicazione come la vecchia
ha la stessa porta della vecchia socket
connessa alla socket del client
La vecchia socket di listen() per ricevere richieste inalterata listen non da
sospensione
La accept() non offre la possibilit di filtrare le richieste che devono perch chiamata
essere accettate tutte in ordine, una da ogni invocazione di accept() locale
accept si.
accept() e connect() realizzano una sorta di rendez-vous
non un reale rendez-vous
accept sospensiva fino all'arrivo di una richiesta.

Socket in C 43

(10:38)

USO SOCKET CLIENT: ACCEPT()


La primitiva accept() usata dal server per ogni nuova connessione
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int s, res, addrlen = sizeof(struc sockaddr_in);


struct sockaddr_in *myaddr; /* impostazione dei valori del server,
con uso di gethostbyname e gestservbyname eventualmente */
struct sockaddr_in *peeraddr; int peeraddrlen;
s = socket (AF_INET,SOCK_STREAM,0);
res = bind (s, myaddr, addrlen);
res = listen (s, backlog);
ns = accept (s, peeraddr, &peeraddrlen); /* per riferimento */
if (ns<0) /* errore e exit */
else /* procedi avendo la nuova socket ns */

La accept() ottiene la nuova connessione visibile tramite ns


I parametri permettono di conoscere il cliente collegato
Socket in C

44

(12:12)

ACCEPT() e nuova SOCKET


La accept() attua la reale connessione dalla parte server e
crea la nuova socket connessa
nodo: indirizzo IP

nodo: indirizzo IP

Processo
Client

Processo
Server
socket
server
(sd)
listen() +
accept()

socket
client

porta
client

unica
porta
server

rete (TCP/IP)

socket
connessa
(nuovo_sd)
read() e write()

La nuova socket insiste sulla stessa porta della socket di bind() e si


differenzia da questa per la funzione (non di listen() e accept()) e
per il collegamento ad un cliente specifico
Lato server, la connessione rappresentata da questa socket
Socket in C 45

(14:04)

SERVER SOCKET e PROCESSI


La nuova socket connessa permette di disaccoppiare le funzionalit
del server, tra accettazione dei servizi e connessioni in atto
Ogni nuova socket rappresenta un servizio separato e separabile:
in caso di server parallelo multiprocesso, la decomposizione aiutata
Server concorrente

multi-processo

connection-oriented

Richiesta di connessione

processi pesanti -> condivisione

ss
Processo
Server
(padre)

ns = accept (ss , ind, lun);


if (fork()==0)

Comunicazione
Client/Server

ns

< servizio della richiesta prima cosa che fa chiudere


uso di socket ns >
la socket di servizio ss
Figlio

utilizza ns che vede


Socket in C 46

(16:10)

COMUNICAZIONE sulla CONNESSIONE


La connessione pu essere usata con send() e recv() per inviare e
ricevere dati (byte) da ognuno dei due pari connessi
#include <sys/types.h>
#include <sys/socket.h>

int send
int
recv ritorna
il numero int recv
di byte realmente
int
ricevuti
s
buf /msg
len
flags
risultato

(s,
s;
(s,
s;

la connessione gi stata stabilita


send potrebbe avere dei momenti di sospensione se
len, flags) per esempio i buffer sono pieni

msg,
char *msg;
int len,flags;
nessun rendez vous
buf, len, flags)
la recv viene sbloccata al primo dato ricevuto
char *buf;
int len,flags;
socket descriptor
puntatore allarea che contiene il messaggio (IN/OUT)
lunghezza del messaggio
opzioni di comunicazione
numero di byte realmente inviato/ricevuto
1 byte che pu essere mandato

flag send() / recv(): 0 normale / MSG_OOB per un messaggio out-of-band separatamente


flusso appl
flag recv(): MSG_PEEK per una lettura non distruttiva dallo streamSocketdal
in C 47

(23:23)

COMUNICAZIONE sulla CONNESSIONE


La connessione pu essere usata con read() e write() per inviare
e ricevere dati (byte) da ognuno dei due pari connessi: le primitive
usuali sono del tutto usabili per socket connesse e la semantica
quella delle precedenti omologhe
#include <sys/types.h>
#include <sys/socket.h>

usando read/write -> funzionano con tutto

int write (s, msg, len)


int read (s, msg, len)
int s; char * msg; int len;
s
socket descriptor
msg
puntatore allarea che contiene il messaggio (IN/OUT)
len
lunghezza del messaggio
risultato
numero di byte realmente inviato/ricevuto

La scrittura/send tende a consegnare alla driver i byte della primitiva


La lettura/read attende e legge almeno 1 byte disponibile, cercando di
trasferire in spazio utente i byte arrivati sulla connessione Socket in C 48

(25:58)

COMUNICAZIONE A STREAM
I messaggi sono comunicati ad ogni primitiva? NO
i dati sono bufferizzati dal protocollo TCP: non detto che siano inviati
subito ma raggruppati e inviati poi alla prima comunicazione 'vera'
decisa dalla driver TCP
Soluzione messaggi di lunghezza pari al buffer
o comandi espliciti di flush del buffer
Come preservare i messaggi in ricezione?
ogni receive restituisce i dati preparati dalla driver locali: TCP a stream
di byte non implementa marcatori di fine messaggio
Soluzioni messaggi a lunghezza fissa
Per messaggi a lunghezza variabile, si alternano un messaggio a
lunghezza fissa e uno variabile in lunghezza, il primo contiene la
lunghezza del secondo, ossia uso di messaggi con indicatori espliciti
di lunghezza letti con due receive in successione
Socket in C 49

32:00

USO di STREAM
Ogni stream viene creato con successo tra due endpoint (e solo
due per non avere interferenze) tipicamente su nodi diversi
i dati viaggiano nelle due direzioni e ogni endpoint li invia e li riceve
dopo che hanno impegnato la comunicazione (banda e risorse)
Ogni endpoint ha una sorgente di input e un sink di output
Come sfruttare al meglio la rete?
ogni dato che sia stato inviato deve essere ricevuto evitando di dovere
scartare dati che sono arrivati ad un endpoint e non vengono accettati
Soluzione segnali di fine flusso
Su ogni flusso viaggiano dati fino alla fine del file che segnala che non
ci si devono aspettare pi dati
Ogni endpoint deve osservare un protocollo: deve leggere tutto
linput fino alla fine del flusso, e dalla sua direzione di flusso, deve
inviare una fine del flusso quando vuole terminare i dati in uscita
Socket in C 50

35:10

CHIUSURA SOCKET: CLOSE()


Per non impegnare risorse non necessarie, si deve rilasciare ogni
risorsa non usata con la primitiva close()
int close (s) int s;
La chiamata close() decrementa il contatore dei processi referenti al
socket descriptor e restituisce il controllo subito
il chiamante non lavora pi con quel descrittore
Il processo segnala al sistema operativo di rilasciare le risorse locali
alla driver di rilasciare le risorse remote
dopo un intervallo di tempo controllato da un'opzione avanzata
(SO_LINGER) tempo per inviare i dati in uscita (out) -> durata della close
int sd;
sd=socket(AF_INET,SOCK_STREAM,0);
...
close(sd); /* spesso non si controlla la eccezione ? */
passante: viene fatta e poi se la vede il kernel

Socket in C 51

input chiuso anche se c' ancora roba dentro. out viene preservata.
jump

EFFETTI della CLOSE()


La close una primitiva a durata limitata (locale) per il chiamante e
con un forte impatto sulla comunicazione e sul pari
Si registra un (forte) ritardo tra la chiusura applicativa e la reale
deallocazione della memoria di supporto

Ogni socket a stream associata ad un buffer di memoria sia per


contenere i dati in uscita sia per i dati di ingresso
Alla chiusura, ogni messaggio nel buffer associato alla socket in uscita
sulla connessione deve essere spedito, mentre ogni dato in ingresso
ancora non ricevuto viene perduto
Solo dopo si pu deallocare la memoria del buffer

Dopo la close (e la notifica), se il pari connesso alla socket chiusa


legge dalla socket, ottiene finefile, se scrive ottiene un segnale di
connessione non pi esistente
La durata della close per la driver poco controllata e pu
impegnare le risorse anche per molto tempo (minuti)

Socket in C 52

40:50

ALTERNATIVA alla CLOSE()


La primitiva shutdown() permette di terminare la connessione con una
migliore gestione delle risorse
La primitiva shutdown produce una chiusura dolce direzionale
e tipicamente si chiude solo il verso di uscita della connessione
int shutdown (s,how) int s, how;
s

socket descriptor della socket


how
verso di chiusura
how = 0, SHUT_RD
non si ricevono pi dati, ma si pu trasmettere
send() del pari ritorna con -1 ed il processo riceve SIGPIPE
how = 1, SHUT_WR
si possono solo ricevere dati dalla socket senza ulteriori trasmissioni
Laltro pari collegato alla connessione alla lettura riceve end-of-file
how = 2, SHUT_RDWR entrambi gli effetti

Socket in C 53

41:58

USO SHUTDOWN()
La primitiva shutdown() viene tipicamente usata per una buona
gestione delle azioni tra i due pari
Ognuno dei due gestisce il proprio verso di uscita e lo controlla
Se decide di finire usa una shutdown delloutput e segnala di non
volere pi trasmettere
Il pari legge fino alla fine del file e poi sa che non deve pi occuparsi di
input

Un pari con shutdown(fd,1) segnala la intenzione di non fare


pi invii nel suo verso
il pari, avvertito con una fine del file, pu fare ancora uso del suo verso
per molti invii, fino alla sua decisione di shutdown si attua una chiusura
dolce

In modo del tutto simile, in Java esistono shutdownInput() e


shutdownOutput() per le chiusure dolci direzionali
Socket in C 54

->>>

PROCESSI NAIVE
I processi molto semplici, processi naive, si comportano da filtri e
leggono dallo standard input e scrivono sullo standard output
possono essere utilizzati in modo quasi trasparente nella
comunicazione (comandi UNIX sort, find, ecc)
Se il processo naif, usa write() e read() al posto delle send() e
recv()allora pu leggere da socket e scrivere su socket
Si deve preparare la attivazione secondo il protocollo usuale:
- Uso di fork() di un comando locale
dopo aver creato tre socket che devono avere file descriptor stdin, stdout
e stderr (0, 1, 2)

- Uso di exec() mantenendo i file descriptor


Il processo locale naif cos connesso automaticamente a dei
canali di comunicazione e tramite questi a processi remoti
Socket in C 55

42:53

PRESENTAZIONE dei DATI


Gli interi sono composti da pi byte e possono essere rappresentati
in memoria secondo due modalit diverse di ordinamento.
2 byte per gli interi a 16 bit, 4 byte per interi a 32 bit

Little-endian Byte Order byte di ordine pi basso nellindirizzo iniziale


Big-endian Byte Order byte di ordine pi alto nellindirizzo iniziale
Little-endian

Network Byte Order (NBO) H


ordinamento di byte per la rete
Protocolli Internet Big-endian
H

address A+1

High-order byte

MSB
High-order byte

address A

Low-order byte

LSB
Low-order byte

address A

address A+1
Host Byte Order (HBO)
Big-endian
non un unico ordinamento
Es. Intel Little-endian, Solaris Big-endian
Socket in C 56

46:50

FUNZIONI ACCESSORIE SOCKET


Funzioni accessorie da usare con socket con obiettivo di portabilit
htons() e htonl() conversione da HBO a NBO valori host to network short/long
network to host short/long
(per word short 16 bit / e double word long 32 bit)
ntohs() e ntohl() convertono valori da NBO a HBO

Funzioni ausiliarie di Manipolazione interi


Quattro funzioni di libreria per convertire da formato di rete in
formato interno per interi (lunghi o corti)
/* trasforma un intero da formato esterno in interno net to host */
shortlocale =
ntohs(shortrete);
longlocale =
ntohl(longrete);
/* trasforma un intero da formato interno in esterno host to net */
shortrete
=
htons(shortlocale);
longrete
=
htonl(longlocale);
Socket in C 57

50:00

ALTRE FUNZIONI ACCESSORIE SOCKET


Manipolazione indirizzi IP per comodit
Funzioni per traslare da IP binario a 32 bit a stringa decimale a byte
separato da punti (ascii: "123.34.56.78")
Conversione da notazione col punto a indirizzi IP a 32 bit
inet_addr() converte l'indirizzo dalla forma con punto decimale
indirizzo = inet_addr(stringa);
Prende una stringa con l'indirizzo in formato punto decimale e d come
risultato lindirizzo IP a 32 bit da utilizzare nelle primitive

Conversione da indirizzi IP a 32 bit a da notazione col punto


inet_ntoa() esegue la funzione inversa
stringa = inet_ntoa(indirizzo);
Prende un indirizzo indirizzo IP a 32 bit (cio un long integer) e fornisce
come risultato una stringa di caratteri con indirizzo in forma con punto
Socket in C 58

50:57

ALTRE FUNZIONI ACCESSORIE


In C tendiamo a lavorare con stringhe, ossia con funzioni che
assumono aree di memoria (stringhe) con il terminatore zero binario
(tutti 0 in un byte) o fine stringa
Per fare operazioni di confronto, di copia e di set
Gli indirizzi internet non sono stringhe (non hanno terminatore), ma le
driver spesso assumono di avere zeri binari

FUNZIONI che non richiedono fine stringa (ma assumono solo


blocchi di byte senza terminatore) per lavorare su indirizzi e fare
operazioni di set, copia, confronto
bcmp (addr1, addr2, length)
/* funzioni BSD */
bcopy (addr1, addr2, length)
bzero (addr1, length)
memset (addr1, char, length) /* funzioni System V */
memcpy (addr1, addr2, length)
memcmp (addr1, addr2, length)
Socket in C

59

53:09

API SOCKET
Molte sono le primitive per le socket, e sono tutte SINCRONE
Chiamata

socket( )
connect( )
write( )
read( )

se linger si

close( )
bind( )

Significato
Crea un descrittore da usare nelle comunicazione di rete
Connette la socket a una remota
Spedisce i dati attraverso la connessione
Riceve i dati dalla connessione
Termina la comunicazione e dealloca la socket
Lega la socket con l'endpoint locale

listen( )

Socket in modo passivo e predispone la lunghezza della coda per le connessioni

accept( )

Accetta le connessioni in arrivo

recv( )
recvmes( )
recvfrom( )
send( )
sendmsg( )
sendto( )

Riceve i dati in arrivo dalla connessione


Riceve i messaggi in arrivo dalla connessione
Riceve i datagrammi in arrivo da una destinazione specificata
Spedisce i dati attraverso la connessione
Spedisce messaggi attraverso la connessione
Spedisce i datagrammi verso una destinazione specificata

Quali primitive possono avere una elevata durata? In bold

Socket in C 60

54:53

API SOCKET
Seguono ancora primitive per le socket
Chiamata

shutdown( )

Significato
Termina una connessione TCP in una o in entrambe le direzioni

getsockname( )

Permette di ottenere la socket locale legata dal kernel (vedi parametri


socket, sockaddr, length)

getpeername( )

Permette di ottenere l'indirizzo del pari remoto una volta stabilita la


connessione (vedi parametri socket, sockaddr, length)

getsockopt( )

Ottiene le opzioni settate per la socket

setsockopt( )

Cambia le opzioni per una socket

perror()

Invia un messaggio di errore in base a

syslog()

Invia un messaggio di errore sul file di log

Si sperimentino le primitive non note (e note)


(sono tipicamente locali e non costose)

Socket in C 61

55:54

ESEMPIO SOCKET STREAM


In unapplicazione distribuita Client/Server per una rete di
workstation UNIX (BSD oppure System V)
il Client presenta linterfaccia: rcp
nodoserver nomefile
dove nodoserver specifica lindirizzo del nodo contenente il processo
Server e nomefile il nome assoluto di un file presente nel file system
della macchina Client

Il processo Client deve inviare il file nomefile al Server


Il processo Server deve copiare il file nomefile nel direttorio /ricevuti
(si supponga di avere tutti i diritti necessari per eseguire tale operazione)
La scrittura del file nel direttorio specificato deve essere eseguita solo se
in tale direttorio non presente un file di nome nomefile, per evitare di
sovrascriverlo
Il Server risponde al Client il carattere S per indicare che il file non
presente, il carattere N altrimenti
Si supponga inoltre che il Server sia gi legato alla porta 12345
Socket in C 62

57:25

RCP: LATO CLIENT - INIZIO e SET

/* Prepara indirizzo remoto connessione */


server_address.sin_family = AF_INET;
host = gethostbyname(argv[1]);
if (host == NULL) {printf("%s non trovato", argv[1]);
exit(2);} /* if ok, big endian */
server_address.sin_addr.s_addr= ((struct in_addr *)
(host->h_addr))->s_addr; /* set indirizzo server */
server_address.sin_port = htons(12345);
sd=socket(AF_INET, SOCK_STREAM, 0);
/* non facciamo la bind, ma la richiediamo tramite la connect */
if(connect(sd, (struct sockaddr *)&server_address,
sizeof(struct sockaddr))<0)
{perror("Errore in connect"); exit(1);}
/* abbiamo il collegamento con il server tramite la connessione (?) */

Socket in C 63

01:05:52

RCP: LATO CLIENT - PROTOCOLLO


if (write(sd, argv[2], strlen(argv[2])+1)<0)
{ perror("write"); exit(1);} /* invio nome del file */
if ((nread=read(sd, buff, 1))<0)
{ perror("read"); exit(1);} /* ricezione risposta server */
if(buff[0]=='S') /* se il file non esiste, si copia */
{if((fd=open(argv[2],O_RDONLY))<0){perror("open");exit(1);
}

while((nread=read(fd, buff, DIM_BUFF))>0)


write(sd,buff,nread);
/* ciclo letture e scritture su socket */
close(sd); /* ho spedito il file */ printf("File spedito\n");
}
else /* non si sovrascrive il file */
{printf("File esiste, termino\n"); close(sd);}

Socket in C

64

01:11:00

RCP: LATO SERVER - INIZIO e SET


Nel server osserviamo la sequenza regolare di primitive

sd=socket(AF_INET, SOCK_STREAM, 0);


if(sd<0) {perror("apertura socket"); exit(1);}
mio_indirizzo.sin_family=AF_INET;
mio_indirizzo.sin_port=htons(12345);
mio_indirizzo.sin_addr=INADDR_ANY; /* non htonl: simmetrico*/
if(bind(sd,(struct sockaddr*)&mio_indirizzo,
sizeof(struct sockaddr_in))<0) {perror("bind"); exit(1); }
listen(sd,5);
/* trasforma la socket in socket passiva d'ascolto e di servizio */
chdir("/ricevuti");

A questo punto sono possibili progetti differenziati, non visibili al cliente


server sequenziali o server concorrenti
Socket in C

65

01:13:09

RCP: SERVER SEQUENZIALE

/* per la read vedi anche esempi successivi */


for(;;) { /* ciclo di servizio */
ns=accept(sd,(struct sockaddr *)&client_address, &fromlen);
read(ns, buff, DIM_BUFF); printf("server legge %s \n", buff);
if((fd=open(buff, O_WRONLY|O_CREAT|O_EXCL))<0)
{printf("file esiste, non opero\n"); write(ns,"N", 1);}
stringa -> non mando il terminatore
else /* ciclo di lettura dalla socket e scrittura su file */
no 'N' carattere perch prenderebbe
{printf("file non esiste, copia\n"); write(ns,"S", 1);
ci che sta all'indirizzo della
while((nread=read(ns, buff, DIM_BUFF))>0) codifica esadecimale del carattere
N
{write(fd,buff,nread); cont+=nread;}
printf("Copia eseguita di %d byte\n", cont);
}
close(ns); close (fd); /* chiusura di file e connessione */
} exit(0); /* il server di nuovo disponibile ad un servizio */
Socket in C 66

01:17:10

RCP: SERVER MULTIPROCESSO


for(;;) {
ns=accept(sd,(struct sockaddr *)&client_address,&fromlen);
if (fork()==0) /* figlio */
{close(sd);read(ns, buff, DIM_BUFF); /* chiude socket servizio */
printf("il server ha letto %s \n", buff);

if((fd=open(buff,O_WRONLY|O_CREAT|O_EXCL))<0)
{printf("file esiste, non opero\n"); write(ns,"N", 1);}
else
/* facciamo la copia del file, leggendo dalla connessione */
{printf("file non esiste, copia\n"); write(ns,"S", 1);
while((nread=read(ns, buff, DIM_BUFF))>0)
{ write(fd,buff,nread); cont+=nread;}
printf("Copia eseguita di %d byte\n",cont); }
close(ns); close(fd); exit(0); }
close(ns); wait(&status); } /* padre */ chiude per non interferire con il figlio
/* attenzione: si sequenzializza ... Cosa bisognerebbe fare? */
Socket in C 67
dovrebbe tornare a fare accept. Qui si mette in wait a gestire il valore del figlio
Servitore diventa sequenziale. Se non facciamo la wait figlio -> zombie -> va gestito -> handler
01:24:51

(inizio registrazione 05.11.2012)

ESEMPIO SERVIZIO REALE


Si vuole realizzare un server parallelo che sia attivato solo col suo nome e
produca un demone di servizio che attiva una connessione per ogni cliente
e che risponde ai messaggi del cliente sulla connessione (echo) fino alla fine
delle richieste del cliente
Processo SERVER (padre):
accettazione richieste di connessione
coda

NODO CLIENTE

Socket d'ascolto collegata alla


porta 22375

Richiesta
Processo CLIENT: invio e
ricezione messaggi di 10 byte
Stream
Socket connessa

.....messag

Processo SERVER (figlio)


eco messaggi di 10 byte

gio3............

Connessione

Processo SERVER init


esce immediatamente

Socket connessa
collegata alla
porta 22375

NODO SERVER
Socket in C 68

(5:00)

ECHO: LATO CLIENT - INIZIO


#include
#include
#include
#include
#include

<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<stdio.h>
<netdb.h>

char *ctime();
int ricevi ();

/* dichiarazione per formattazione dell'orario */


/* dichiarazione routine di ricezione di un messaggio*/

int s;
/* socket descriptor del cliente */; char * nomeprog;
struct hostent *hp; /* puntatore alle informazioni host remoto */ non istanziato
long timevar;
/* contiene il risultato dalla time() */
struct sockaddr_in myaddr_in;
/* socket address locale */
struct sockaddr_in peeraddr_in; /* socket address peer */ destinatario
main(argc, argv) int argc; char *argv[];
{ int addrlen, i; char buf[10]; /* messaggi di 10 bytes */
if (argc != 3)
{ fprintf(stderr, "Uso: %s <host remoto> <nric>\n", argv[0]); exit(1)}
Socket in C 69

7:30

ECHO: LATO CLIENT - SET


anche bzero

/* azzera le strutture degli indirizzi */


memset ((char *)&myaddr_in, 0, sizeof(struct sockaddr_in));
memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
/* assegnazioni per il peer address da connettere */
peeraddr_in.sin_family = AF_INET;
/* richiede informazioni a proposito del nome dell'host */
hp = gethostbyname (argv[1]);
/* il risultato gi big endian e pronto per la TX */
if (hp == NULL) {
fprintf(stderr, "%s: %s non trovato in /etc/hosts\n", argv[0],
argv[1]);
exit(1); }

/* trovato il nome IP fisico */

esce se non ha l'indirizzo del server

peeraddr_in.sin_addr.s_addr =
((struct in_addr *)(hp->h_addr))->s_addr;
/* non si usa la htonl dopo la gethostbyname: la si provi in diversi ambienti */
Socket in C 70

10:40

LATO CLIENT - ANCORA SET


/* definisce il numero di porta senza la chiamata getservbyname()
Se fosse registrato nel nodo cliente avremmo:
struct servent *sp; /* puntatore alle informazioni del servizio */
sp = getservbyname ("example", "tcp");
if (sp == NULL)
{fprintf(stderr,"%s: non trovato in /etc/services\n",argv[0]);
exit(1); }
peeraddr_in.sin_port = htons (sp->s_port);*/ /* invece */

peeraddr_in.sin_port = htons(22375);
/* numero di porta trasformato nel formato network via htons(). In
architetture in cui i due formati coincidono si ottiene maggiore efficienza */
s = socket (AF_INET,SOCK_STREAM,0); /* creazione della socket */
if (s == -1) { perror(argv[0]); /* controllo errore */
fprintf(stderr, "%s: non posso creare la socket\n", argv[0]); exit(1); }
nomeprog = argv[0]; /* per gestire condizioni derrore in procedure */
Socket in C 71

12:50

LATO CLIENT - PRIMITIVE


bind implicita

/* No bind: la porta del client assegnato dal sistema. Il server lo vede alla
richiesta di connessione; il processo client lo ricava con getsocketname() */
if(connect (s, &peeraddr_in, sizeof(struct sockaddr_in))== -1)
{ perror(argv[0]); /* tentativo di connessione al server remoto */
fprintf(stderr,"%s: impossibile connettersi con server\n", argv[0]);

/* altrimenti lo stream stato ottenuto (!?) */


addrlen = sizeof(struct sockaddr_in); /* dati connessione locale */
if (getsockname (s, &myaddr_in, &addrlen) == -1) dice l'indirizzo locale
exit(1);

e la porta

{perror(argv[0]); fprintf(stderr, "%s: impossibile leggere il


socket address\n", argv[0]); exit(1); }

/* scrive un messaggio iniziale per l'utente */


time(&timevar); unix no real-time -> fornisce per funzioni per la gestione dei tempi (tick da 1970)
printf("Connessione a %s sulla porta %u alle %s",
argv[1], myaddr_in.sin_port, ctime(&timevar));
/* Il numero di porta espresso in byte senza bisogno di conversione */
Socket in C
sleep(5); /* attesa che simula un'elaborazione al client */

72

18:12

CLIENT - INVIO DATI CONNESSIONE


/* NON C' PRESENTAZIONE DEI DATI
Invio di messaggi al processo server mandando un insieme di interi successivi
*buf=i pone i primi 4 byte di buf uguali alla codifica dell'intero in memoria
Il server rispedisce gli stessi messaggi al client (senza usarli)
Aumentando il numero e la dimensione dei messaggi, potremmo anche occupare
troppa memoria dei gestori di trasporto sia il server che il client stabiliscono un
limite alla memoria associata alla coda delle socket */

for (i=1; i<= atoi(argv[2]); i++) atoi non brava -> se incontra un carattere si ferma
{/* invio di tutti i messaggi nel numero specificato dal secondo argomento */
*buf = htonl(i); /* i messaggi sono solo gli interi successivi */
if ( send (s, buf, 10, 0) != 10) send non bloccante -> se ne occupa la driver
{fprintf(stderr, "%s: Connessione terminata per errore", argv[0]); semantica locale
fprintf(stderr, "sul messaggio n. %d\n", i); exit(1);

}
}

buf -> variabile locale del main -> viene allocata dalla
stack non inizializzata -> per inizializzarla : variabile
globale -> tutto inizializzato a zero

/* i messaggi sono mandati senza aspettare alcuna risposta !!!! */

Socket in C 73

27:00

CLIENT - RICEZIONE DATI


/* Shutdown() della connessione per successivi invii (modo 1): Il server
riceve un end-of-file dopo le richieste e riconosce che non vi saranno altri
invii di messaggi */
if(shutdown (s, 1) == -1) {perror(argv[0]);
fprintf(stderr, "%s: Impossibile eseguire lo shutdown\
della socket\n", argv[0]); exit(1); }

/*Ricezione delle risposte dal server


Il loop termina quando la recv() fornisce zero, cio la terminazione end-offile. Il server la provoca quando chiude il suo lato della connessione*/
/* Per ogni messaggio ricevuto, diamo un'indicazione locale */
while (ricevi (s, buf, 10)) no recv per affidabilit nei dati ricevuti
printf("Ricevuta la risposta n. %d\n", ntohl( *buf));
/* Messaggio per indicare il completamento del programma */
time(&timevar); printf("Terminato alle %s", ctime(&timevar));
}
Socket in C 74

29:20

FUNZIONE DI RICEZIONE MESSAGGI


int ricevi (s, buf, n) int s; char * buf; int n;
{int i, j; /* ricezione di un messaggio di specificata lunghezza */
if ((i = recv (s, buf, n, 0)) != n && != 0) { la recv si sblocca anche con
chiusa

1 byte -> va gestita


if (i == -1) { perror(nomeprog);
fprintf(stderr,"%s: errore in lettura\n, nomeprog); exit(1); }

while (i < n) { j = recv (s, &buf[i], n-i, 0);

se ne possono ricevere di
meno -> rileggo.
Ma non di pi

if (j == -1) { perror(nomeprog);
fprintf(stderr,"%s: errore in lettura\n, nomeprog); exit(1); }

i += j; if (j == 0) break; }
} /* si assume che tutti i byte arrivino se si verifica il fine file si esce */
return i; }
/* Il ciclo interno verifica che la recv() non ritorni un messaggio pi corto di
quello atteso (n byte)
La recv ritorna appena vi sono dati e non attende tutti i dati richiesti

Il loop interno di recv garantisce la ricezione fino al byte richiesto e permette


alla recv successiva di partire sempre dall'inizio di una risposta */
Socket in C 75

RICEZIONE MESSAGGI
Nelle applicazioni Internet molto comune trovare funzioni come
quella appena vista di ricezione
Dobbiamo ricordare che la ricezione considera un successo un
qualunque numero di byte ricevuto (anche 1) e ne segnala il numero
nel risultato (a meno di opzioni: vedi low watermark)
Per evitare tutti i problemi, dobbiamo fare ricezioni / letture ripetute
Esiste il modo di cambiare il comportamento della receive intervenendo
sui low-watermark (vedi opzioni socket)

In ogni caso, in ricezione dobbiamo sempre verificare la dimensione


del messaggio, se nota, o attuare un protocollo per conoscerla
durante la esecuzione, per aspettare l'intero messaggio significativo
Per messaggi di piccola dimensione la frammentazione
improbabile, ma con dimensioni superiori (qualche Kbyte), il pacchetto
pu venire suddiviso dai livelli sottostanti, e una ricezione parziale
diventa pi probabile
Socket in C 76

41:51

LATO SERVER - INIZIO


#include
#include
#include
#include
#include
#include

<sys/types.h>
<sys/socket.h>
<netinet/in.h>
<signal.h>
<stdio.h>
<netdb.h>

long timevar; /* contiene il valore fornito da time() */


int s;
/* socket descriptor */
int ls;
/* socket per ricevere richieste e la listen()*/
struct hostent *hp;
/* puntatore all' host remoto */
struct sockaddr_in myaddr_in; /* socket address locale */
struct sockaddr_in peeraddr_in; /* socket address peer */ client
char * nomeprog;
main(argc, argv) int argc; char *argv[];
{int addrlen; nomeprog=argv[0]; /* si azzerano gli indirizzi */;
memset ((char *)&myaddr_in, 0, sizeof(structsockaddr_in));
memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
Socket in C 77

43:30

LATO SERVER - SET


/* Assegna la struttura d'indirizzo per la listen socket */
myaddr_in.sin_family = AF_INET;
/* Il server ascolta su un qualunque suo indirizzo (wildcard address), invece
che s uno specifico indirizzo di rete maggiore portabilit del codice
Convenzione per considerare server su nodi connessi a pi reti,
consentendo di attendere richieste da ogni rete (e indirizzo relativo) */
/* assegna IP generico e numero di porta */
myaddr_in.sin_addr.s_addr = INADDR_ANY;
myaddr_in.sin_port = htons(22375);

Il server deve sempre garantirsi un assegnamento di porta e IP che


siano quelli con cui conosciuto ai clienti
Deve quindi seguire la sequenza intera delle primitive
Socket in C 78

44:15

SERVER - PRIMITIVE di CONNESSIONE


/* Crea la socket d'ascolto delle richieste */
ls = socket (AF_INET, SOCK_STREAM, 0);
if (ls == -1) { perror(argv[0]); fprintf(stderr, "%s: impossibile\
creare la socket.\n", argv[0]); exit(1); }

/* Collega la socket all'indirizzo fissato */


if(bind(ls,&myaddr_in,sizeof(struct sockaddr_in)) == -1)
{perror(argv[0]); fprintf(stderr, "%s: impossibile eseguire il\
collegamento.\n", argv[0]);exit(1); }

/* Inizializza la coda d'ascolto richieste (tipicamente al massimo 5 pendenti)


*/
if (listen (ls, 5) == -1) 5 richieste in coda: standard
{perror(argv[0]); fprintf(stderr, "%s: impossibile l'ascolto sulla\
socket\n", argv[0]);exit(1); }

/* Inizializzazione della socket principale completata

Il programma deve creare un processo daemon ed uscire dopo


avere lasciato il processo a garantire il servizio */

Socket in C 79

45:40

SERVER - DAEMON di SERVIZIO


Il processo prima di uscire deve preparare le condizioni per il figlio
daemon
La chiamata setsid() sgancia il processo dal terminale di controllo e lo stacca dal
gruppo del processo padre (il processo diventa leader di una nuova sessione
non collegata a nessun terminale)

Poi si genera un figlio che deve lavorare (il daemon) e si termina


Il daemon genera un figlio per ogni richiesta di connessione
setsid();
/* Unix System V: nuovo gruppo processi */
switch (fork()) {
case -1: /* Impossibilit di creazione di un processo figlio */
perror(argv[0]); fprintf(stderr, "%s: impossibile creare un
daemon.\n", argv[0]); exit(1);

case 0: /* FIGLIO e schema di processo DEMONE: dopo */


default: exit(0); /* processo INIZIALE */
} /* Il processo iniziale esce e lascia libera la console utente */
Socket in C 80
}

48:08

DAEMON di SERVIZIO
case 0:

/* FIGLIO e schema di processo DEMONE: qui */

/* Il daemon chiude lo stdin e lo stderr, mentre lo stdout assunto come


ridiretto ad un file di log per registrare gli eventi di esecuzione */
close(stdin); close(stderr);
/* si ignora il segnale SIGCLD (SIG_IGN) per non mantenere processi
zombi per ogni servizio eseguito */
signal(SIGCLD, SIG_IGN);
/* Il demone entra in un loop e, ad ogni richiesta, crea un processo figlio per
servire la chiamata */
for (;;) { addrlen = sizeof(struct sockaddr_in);
/* accept() bloccante in attesa di richieste di connessione
Dopo la accept, il daemon ottiene dalla accept l'indirizzo del chiamante e la
sua lunghezza, oltre che un nuovo socket descriptor per la connessione */
s = accept (ls, &peeraddr_in, &addrlen);
if ( s == -1) exit(1);
Socket in C 81

50:35

DAEMON - SERVIZIO
switch (fork()) {
case -1: /* Non possibile generare un figlio ed allora esce */
exit(1);
case 0: /* Esecuzione del processo figlio che gestisce il servizio */
server();
/* ulteriore figlio per il servizio */
exit(0);
default: /* successo in generazione demone */
close(s);
/* Il processo daemon chiude il socket descriptor e torna ad accettare
ulteriori richieste. Questa operazione consente al daemon di non superare il
massimo dei file descriptor ed al processo figlio fare una close() effettiva sui
file */
} /* fine switch */
} /* for fine ciclo del daemon*/

Resta il comportamento del figlio del daemon in server()

Socket in C 82

51:44

PROCESSO di SERVIZIO
procedura SERVER: routine eseguita dal processo figlio del daemon
qui che si gestisce la connessione: si ricevono i pacchetti dal
processo client, si elaborano, e si ritornano i risultati al mittente;
inoltre si scrivono alcuni dati sullo stdout locale
char *inet_ntoa(); /* routine formato indirizzo Internet */
char *ctime();
/* routine di formato dell'orario ottenuto da time () */
int ricevi ();
server()
{ int reqcnt = 0;
/* conta il numero di messaggi */
char buf[10];
char *hostname;
int len, len1;
necessaria
per diverse
responsabilitIl

/* l'esempio usa messaggi di 10 bytes */


/* nome dell'host richiedente */

close (ls); /* Chiude la socket d'ascolto ereditata dal daemon */

server vero deve leggere tutti i dati secondo il formato predefinito


e rispondere dopo averli elaborati
Socket in C 83

53:20

PROCESSO di SERVIZIO
/* Cerca le informazioni relative all'host connesso mediante il suo indirizzo
Internet usando la gethostbyaddr() per rendere leggibili gli indirizzi */
hp = gethostbyaddr ((char *)&(ntohl(peeraddr_in.sin_addr) ,
sizeof (struct in_addr), peeraddr_in.sin_family);
if (hp == NULL) hostname =
qui hostname = "137.0.89.1"
inet_ntoa(ntohl(peeraddr_in.sin_addr));
/* Non trova host ed allora assegna l'indirizzo formato Internet */
else
{ hostname =(hp->h_name); /* punta al nome dell'host */ }
/*stampa un messaggio d'avvio*/
time (&timevar);
printf("Inizio dal nodo %s porta %u alle %s",
hostname, ntohs(peeraddr_in.sin_port),
ctime(&timevar));
Socket in C 84

55:00

CICLO di SERVIZIO
/* Loop di ricezione messaggi del cliente
Uscita alla ricezione dell'evento di shutdown, cio alla fine del file */
while (ricevi (s, buf, 10) )
{reqcnt++; /* Incrementa il contatore di messaggi */
sleep(1); /* Attesa per simulare l'elaborazione dei dati */
if(send(s,buf,10,0)!=10) /* Invio risposta per ogni messaggio*/
{printf("Connessione a %s abortita in send\n", hostname);exit(1);}

/* sui dati mandati e ricevuti non facciamo nessuna trasformazione */


} /* Il loop termina se non vi sono pi richieste da servire */
close (s);
/* Stampa un messaggio di fine. */
time (&timevar);
printf("Terminato %s porta %u, con %d messaggi, alle %s\n,
hostname, ntohs(peeraddr_in.sin_port), reqcnt,
ctime(&timevar)); }
Socket in C

85

56:16

ADDENDUM PRIMITIVE
In alcuni kernel, le primitive sospensive hanno un qualche problema
in caso di interruzione con segnali, dovuto a interferenza tra spazio
kernel e utente
Una primitiva sospensiva interrotta da un segnale deve essere riattivata
dall'inizio usando uno schema come il seguente
(errno == EINTR verifica che si sia stata una interruzione da segnale)

for (;;)
{ int g, len = sizeof (from);
g= accept (f, (struct sockaddr *)&from, &len);
if (g < 0) { if (errno == EINTR) /* ripetizione primitiva */
syslog(LOG_ERR, ..."p); continue; }
/* altro codice in caso di successo e uscita dal ciclo for*/
}

interrupt sbloccherebbe la accept facendolo andare avanti. In questo modo, se arriva


un'interrupt riprende dal punto corretto senza andare avanti
Socket in C 86

59:55
(torna un po' indietro)
01:09:00 (select)

ATTESE MULTIPLE
Le primitive su socket bloccano il processo che le esegue
In caso di possibile ricezione da sorgenti multiple (eventi multipli che
possono sbloccare un processo) necessaria la possibilit di
attendere contemporaneamente su pi eventi di I/O legati a pi
socket (o file)
La gestione delle socket ha portato ad una primitiva legata alla gestione
di pi eventi all'interno di uno stesso processo e al blocco imposto dalle
primitive sincrone
Le operazioni bloccanti (lettura) o con attese pregiudicano il servizio di
altre ad un processo server (con molti servizi da svolgere) che
potrebbe sospendersi su una primitiva e non potere servire altre
richieste su socket diverse

Risposta in C con PRIMITIVA select()


blocca il processo in attesa di almeno un evento fra pi eventi attesi
possibili (range da 0 a soglia intera) solo per un definito intervallo timeout
Socket in C 87

01:16:15

SELECT()
Primitiva per attesa multipla globale sincrona o con durata massima
select() primitiva con time-out intrinseco
Azioni di comunicazione potenzialmente sospensive
Lettura accept, receive (in tutte le forme), eventi di chiusura
Scrittura connect, send (in tutte le forme), eventi di chiusura
Eventi anomali dati out-of-band, eventi di chiusura

La select permette di accorgersi di eventi relativi a socket rilevanti


#include <time.h>

int select (nfds, readfds, writefds, exceptfds, timeout)


size_t nfds ; /* numero massimo di eventi attesi, inteso come limite 15 -> nfds=16
superiore al numero delle socket e per indicare quali bit considerare*/ partendo da 0
int *readfds, *writefds, *exceptfds; zeri e uni per i fd o eventi che interessano
/* tre maschere per gli eventi o anche null per indicare non interesse */
const struct timeval * timeout;
/* time out massimo o anche null se attesa indefinita */

Socket in C 88

(inizio registrazione 06.11.12)

EVENTI per la SELECT()


La select() invocata sospende il processo fino al primo
evento o al timeout (se si specifica il timeout) o attende il primo
evento (sincrona con il primo)
Eventi di lettura: rendono possibile e non bloccante unoperazione
- in una socket sono presenti dati da leggere recv()
- in una socket passiva c' una richiesta (OK accept())
- in una socket connessa si verificato un end of file o errore

Eventi di scrittura: segnalano unoperazione completata


- in una socket la connessione completata connect()
- in una socket si possono spedire altri dati con send()
- in una socket connessa il pari ha chiuso (SIGPIPE) o errore

Eventi e condizioni eccezionali, segnalano errore o urgenza


- arrivo di dati out-of-band,
- inutilizzabilit della socket, close() o shutdown()
Socket in C 89

1:54

dimensione delle maschere statica

INVOCAZIONE della SELECT()


num max di fd

int select (nfds, readfds, writefds, exceptfds, timeout)


size_t nfds ;
int *readfds, *writefds, *exceptfds;
const struct timeval * timeout;

La select() invocata richiede al sistema operativo di passare delle


informazioni sullo stato interno di comunicazione
Allinvocazione segnala nelle maschere gli eventi di interesse
Al completamento, restituisce il numero di eventi occorsi e indica quali
con le maschere (parametri di ingresso/uscita) maschere
Timeout

struct timeval {long tv_sec; long tv_usec;}; perch select bloccante


/* secondi e microsecondi */
Con azione sospensiva bloccante sincrona, il massimo intervallo di attesa 31
giorni
Con timeout quanto specificato nel parametro
Con azione non bloccante, si specifica zero come valore nel timeout e si
lavora a polling dei canali
Socket in C 90

7:24

MASCHERE per la SELECT()


La chiamata esamina gli eventi per i file descriptor specificati nelle tre
maschere (valore ingresso bit ad 1) relative ai tre tipi
I bit della maschera corrispondono ai file descriptor a partire dal fd 0 fino al fd
dato come primo parametro

Prendendo come maschera la seguente


9
1
0

8
0
0

7
1
1

6
0
0

5
1
1

4
1
0

3
0
0

2
0
0

1
0
0

0
0
0

eventi

posizione file descriptor


maschera ingresso
maschera uscita -> restituisce 2

si esaminano solo i file descriptor il cui bit ad 1, ossia per socket 4,5,7,9

fds[(f / BITS_PER_INT)] & (1<<(f % BITS_PER_INT))


Al ritorno della chiamata le tre maschere sono modificate in relazione agli
eventi per i corrispondenti file descriptor
1 se evento verificato, 0 altrimenti, ossia gli eventi 4,5,7 si sono verificati

Anche un solo evento di lettura/scrittura/anomalo termina la


primitiva select, dopo cui si possono o trattare tutti o uno solo,
anche selezionando un qualunque ordine del servizio
Socket in C

91

9:50

OPERAZIONI sulle MASCHERE


Per facilitare la usabilit si introducono operazioni sulle
maschere, che sono array di bit, di dimensione diversa per le
diverse architetture

file descriptor
MASCHERA

9 8 7 6 5 4 3 2 1 0
0 0 1 0 1 1 0 0 0 0
void FD_SET(int fd, fd_set &fdset);

setta i file descriptor

FD_SET include la posizione particolare fd in fdset ad 1

void FD_CLR(int fd, fd_set &fdset);

riporta a 0 fd

FD_CLR rimuove fd dal set fdset (reset della posizione)

int

FD_ISSET(int fd, fd_set &fdset);

FD_ISSET restituisce un predicato che determina se la posizione di fd


fa parte del set fdset, o non ne fa parte (0 ed 1)

void FD_ZERO(fd_set &fdset);

mette a zero tutti i bit della maschera

FD_ZERO inizializza linsieme di descrittori a zero

Socket in C 92

11:56

MACRO sulle MASCHERE


Le operazioni sono macro C definite in /usr/include/stdio.h
typedef long fd_mask; /* un certo numero di fd_mask */
#define NFDBITS (sizeof(fd_mask)*8) /* 8 bit in un byte */
#define howmany(x,y)
(((x)+((y)-1))/(y))
typedef struct fd_set /* definizione della maschera */
{fd_mask fds_bits[howmany(FD_SETSIZE,NFDBITS)];}fd_set;
/* la dimensione dellarray dipende dal sistema operativo: da cosa? */
#define FD_SET(n,p)
((p)->fds_bits[(n)/NFDBITS] |= (1<<((n)% NFDBITS)))
#define FD_CLR(n,p)
((p)->fds_bits[(n)/NFDBITS] &=~(1<<((n)% NFDBITS)))
#define FD_ISSET(n,p)
((p)->fds_bits[(n)/NFDBITS]&(1<<((n)% NFDBITS)))
#define FD_ZERO(p)
memset((char *) (p), (char) 0,sizeof(*(p))) Socket in C 93

13:23

ESEMPIO di SELECT()
Gestione di socket e select (maschere) #include <stdio.h>
do_select(s) int s; /* socket descriptor di interesse */
{struct fd_set read_mask, write_mask; int nfds, nfd;
for (;;) {/* ciclo infinito */
/* azzera le maschere e set posizione*/
FD_ZERO(&read_mask); FD_SET(s,&read_mask);
FD_ZERO(&write_mask); FD_SET(s,&write_mask); nfds=s+1;
nfd=select(nfds,&read_mask,&write_mask, NULL,
(struct timeval*)0); sblocco -> evento
if (nfd==-1) /* -1 per errore, anche 0 per timeout*/
{perror("select: condizione inattesa"); exit(1);}
/* ricerca successiva del file descriptor nella maschera e trattamento */
if (FD_ISSET(s,&read_mask)) do_read(s); non bloccante perch l'evento c' gi
if (FD_ISSET(s,&write_mask)) do_write(s);
}}
Socket in C 94

17:41

SERVER CONCORRENTE a CONNESSIONE


Si vuole progettare un server concorrent monoprocesso che
possa accettare servizi molteplici tutti con necessit di una
connessione con il cliente
senza incorrere nei ritardi di un server sequenziale
Il server deve potere portare avanti le attivit disponibili senza
attese non necessarie dovute agli strumenti o primitive
necessario considerare che tutte le socket sono legate alla stessa
porta, ed avendo un unico processo, i numeri delle socket sono
facilmente prevedibili
Tipicamente 0,1,2 sono impegnati per standard poi si sale
Alla chiusura, i file descriptor liberati sono occupati in sequenza dal basso
Il server comincia ad occupare il primo file descriptor per la socket di
listen (ricezione richieste connessione), poi cresce con le altre ad ogni
richiesta
Toglie un file descriptor per ogni chiusura e rioccupa dai valori bassi

Socket in C 95

20:50

SERVER CONCORRENTE - supporto


#define LEN 100
typedef struct { long len; char name[LEN]; } Request ;
typedef int HANDLE;

/* funzione di ricezione di una intera richiesta: ciclo letture fino ad ottenere


lintera richiesta */
int recv_request (HANDLE h, Request *req)
{ int r_bytes, n; int len = sizeof * req;
for (r_bytes = 0; r_bytes < len; r_bytes += n)
{ n = recv (h, ((char *) req) + r_bytes,
len - r_bytes, 0);
if (n <= 0) return n; }
req->len = ntohl (req->len); /* Decodifica len */
return r_bytes;
}
Socket in C 96

23:46

SERVER CONCORRENTE - supporto


typedef struct { long value, errno; /* 0 successo */ } Response ;

/* funzione di invio di una intera richiesta: ciclo di scritture fino ad ottenere


linvio dellintera richiesta */
int send_response (HANDLE h, long value)
{Response res; size_t w_bytes;
size_t len = sizeof res;
/* il risultato prevede i campi errore e valore */
res.errno = value == -1 ? htonl (errno) : 0;
res.value = htonl (value);
for (w_bytes = 0; w_bytes < len; w_bytes += n)
{ n = send (h, ((char *) &res) + w_bytes,
len - w_bytes, 0);
if (n <= 0) return n; }
return w_bytes;
}

Socket in C 97

25:09

SERVER - PREPARAZIONE
int main
{

(int argc, char *argv[])

/* porta di listen per connessioni */


u_short port = argc > 1 ? atoi(argv[1]) : 10000;
/* trattamento iniziale della socket */
HANDLE listener = create_server_endpoint(port);
/* numero corrente di possibili socket da verificare */
HANDLE maxhp1 = listener + 1;
fd_set read_hs, temp_hs;
/* due maschere, 1 di stato stabile e 1 di supporto che si possa usare */
FD_ZERO(&read_hs);
FD_SET(listener, &read_hs); richiesta di connessione
temp_hs = read_hs;
/* ciclo di select per il processo servitore*/
}
Socket in C

98

27:54

SERVER - CICLO
for (;;) /* ciclo di select per il processo servitore*/
{ HANDLE h; /* verifica delle richieste presenti */
select (maxhp1, &temp_hs, 0, 0, 0); Bloccante
for (h = listener + 1; h < maxhp1; h++)
{ if (FD_ISSET(h, &temp_hs)) /* richieste sulle connessioni */
/* per ogni dato su connessione, trattamento in handle() */
if (handle (h) == 0)
/* se il caso di chiusura della connessione da parte del cliente */
{ FD_CLR(h, &read_hs); close(h); }
}
if (FD_ISSET(listener, &temp_hs)){ /* nuova connessione */
h = accept (listener, 0, 0); FD_SET(h, &read_hs);
if (maxhp1 < = h) maxhp1 = h + 1;
}
temp_hs=read_hs; }
}
Socket in C

99

32:23

SERVER - INIT
/* funzione di preparazione della socket di listen sulla porta */
HANDLE create_server_endpoint (u_short port)
{struct sockaddr_in addr;
HANDLE h; /* file desriptor della socket iniziale */
h = socket (PF_INET, SOCK_STREAM, 0);
/* set di indirizzo per il server */
memset ((void *) &addr, 0, sizeof addr);
addr.sin_family = AF_INET;
addr.sin_port = ntohs(port);
addr.sin_addr.s_addr = INADDR_ANY;
/* usuali primitive da parte server */
bind (h, (struct sockaddr *) &addr, sizeof addr);
listen (h, 5);
return h;
}
Socket in C

100

SERVER AZIONI SPECIFICHE


/* funzione di preparazione della socket di listen sulla porta */
long action (Request *req); /* azione qualunque di servizio */
{ ... }
/* per ogni possibile evento da parte di un cliente connesso, si esegue la
funzione handle
questa funzione riceve la richiesta (letture senza sospensione)
attua l'azione e invia la risposta
a richiesta nulla, il cliente ha chiuso la connessione si chiude*/
long handle (HANDLE h)
{ struct Request req; long value;
if (recv_request (h, &req) <= 0)
return 0;
value = action (&req); /* azione */ Se richiede molto tempo il server si blocca e le richieste
return send_response (h, value);si accodano
}
Socket in C 101

inizio registrazione 09.11.12

SERVER MULTIFUNZIONE
Spesso significativo avere un unico servitore per pi servizi come
un unico collettore attivo che si incarica di smistare le richieste
Il servitore multiplo pu
portare a termine completamente i servizi per richiesta
incaricare altri processi del servizio (specie in caso di connessione e
stato) e tornare al servizio di altre richieste
Unico processo master per molti servizi deve riconoscere le richieste ed
anche attivare il servizio stesso
Problemi:
Un unico servizio che fa il dispatching
Il server pu diventare il collo di bottiglia del sistema
-> servizi semplici fatti dal demone
Necessit di decisioni rapide e leggere

inetd e tutti gli altri delegati (magari


ad altri indirizzi) -> grossa select
Intrusione limitata

Vedi BSD UNIX inetd Internet daemon (/etc/services)


inetd svolge alcuni servizi sono svolti in modo diretto (servizi interni) ed
altri li delega a processi creati su richiesta
definito un linguaggio di configurazione per specificare comportamento
Socket in C 102

7:15

CONFIGURAZIONE

INETD

#
#
#
#
#

@(#)inetd.conf 1.24 SMI Configuration file for inetd(8).


To re-configure the running inetd process, edit this file,
then send the inetd process a SIGHUP.
Internet services syntax:
<service_name> <socket_type> <proto> <flags> <user>
<server_pathname> <args>
# Ftp and telnet are standard Internet services. nowait -> genera un processo
ftp stream
tcp nowait root /usr/etc/in.ftpd
in.ftpd
telnet stream tcp nowait root /usr/etc/in.telnetd in.telnetd
# Shell, login, exec, comsat and talk are BSD protocols.
Shell stream tcp nowait
root /usr/etc/in.rshd in.rshd
talk dgram udp wait
root /usr/etc/in.talkd in.talkd
# Finger, systat and netstat are usually disabled for security
# Time service is used for clock syncronization.
time stream tcp nowait
root
internal
time dgram udp wait
root
internal
Socket in C 103

CONFIGURAZIONE INETD
# Echo, discard, daytime, and chargen are used for testing.
echo
stream tcp
nowait root internal
echo
dgram udp
wait
root internal
discard
stream tcp
nowait root internal
discard
dgram udp
wait
root internal
daytime
stream tcp
nowait root internal
daytime
dgram udp
wait
root internal
# RPC services syntax:
# <rpc_prog>/<vers> <socket_type> rpc/<proto> <flags> <user>
<pathname> <args>
# The rusers service gives out user information.
rusersd/1-2
dgram
rpc/udp
wait
root
/usr/etc/rpc.rusersd rpc.rusersd
# The spray server is used primarily for testing.
sprayd/1
dgram
rpc/udp
wait
root
/usr/etc/rpc.sprayd
rpc.sprayd
Socket in C 104

13:15

Anche il client potrebbe usare una select


gestendo le socket nel modo opportuno
-> select su una serie di connessioni aperte
POSSIBILITA'

CLIENTE sequenziale o parallelo


Si pu gestire la concorrenza anche dalla parte del cliente
a) soluzione concorrente
possibilit che il cliente unico gestisca pi interazioni con necessit di
gestione dellasincronismo
uso di select e politiche di servizio opportune

b) soluzione parallela
possibilit di generare pi processi (slave) che gestiscono ciascuno
una diversa interazione con un server
Questo permette anche di interagire con pi server contemporaneamente ad esempio con multicast
client
master

client

processi di
applicazione
client

socket TCP una socket per ogni


di input
connessione

sistema
operativo

slave

slave slave

socket usate per servire una


connessione ciascuna

Socket in C 105

18:54

OPZIONI per le SOCKET


getsockopt() setsockopt()
funzioni di utilit per configurare socket, cio leggere e variare le
modalit di utilizzo delle socket
#include <sys/types.h>
#include <sys/socket.h>

char optval = 1; /* tipicamente il valore del campo vale o 1 o 0 */


int getsockopt (s, level, optname, &optval, optlen)
int s, level, optname, optval, *optlen;
int setsockopt (s, level, optname, &optval, optlen)
int s, level, optname, optval, optlen;
s

socket descriptor legato alla socket


level

livello di protocollo per socket: SOL_SOCKET


optname
nome dell'opzione costante -> label
optval

puntatore ad un'area di memoria per valore


optlen

lunghezza del quarto argomento

Socket in C 106

23:26
26

POSSIBILI OPZIONI per le SOCKET


Si riescono a cambiare molti comportamenti anche in modo molto
granulare e con molto controllo

linger =
stare intorno

Opzioni
SO_DEBUG
SO_REUSEADDR
SO_DONTROUTE
SO_LINGER
SO_BROADCAST
SO_OOBINLINE
SO_SNDBUF
SO_RCVBUF
SO_SNDLOWAT
SO_RCVLOWAT
SO_SNDTIMEO
SO_RCVTIMEO
SO_USELOOPBACK
SO_PROTOTYPE

Descrizione
abilita il debugging (valore diverso da zero)
riuso dell'indirizzo locale
abilita il routing dei messaggi uscenti
ritarda la chiusura per messaggi pendenti
abilita la trasmissione broadcast
messaggi prioritari pari a quelli ordinari
setta dimensioni dell'output buffer
setta dimensioni dell'input buffer
setta limite inferiore di controllo di flusso out
limite inferiore di controllo di flusso in input
setta il timeout dell'output
setta il timeout dell'input
abilita network bypass
setta tipo di protocollo
Socket in C 107

28:45

POSSIBILI OPZIONI per le SOCKET


Timeout per operazioni Opzioni SO_SNDTIMEO e SO_RCVTIMEO
Tempo massimo di durata di una primitiva di send / receive, dopo cui il
processo viene sbloccato
int result; int waittime=10;
result = setsockopt (s, SOL_SOCKET, SO_RCVTIMEO,
&waittime, sizeof(waittime));
Dimensioni buffer di trasmissione/ricezione SO_SNDBUF e SO_RCVBUF
Intervento sulla dimensione del buffer di trasmissione o ricezione di
socket Si interviene sulle comunicazioni, eliminando attese anche per
messaggi di dimensioni elevate (massima dimensione possibile 65535 byte)
int result; int buffersize=10000;
result = setsockopt (s, SOL_SOCKET, SO_RCVBUF,
&buffersize, sizeof(buffersize));
Controllo periodico della connessione
Il protocollo di trasporto pu inviare messaggi di controllo periodici per
Socket in C
analizzare lo stato di una connessione (SO_KEEPALIVE)

108

31:05

RIUTILIZZO INDIRIZZI SOCKET


Opzione SO_REUSEADDR modifica comportamento della bind()
Il sistema tende a non ammettere pi di un utilizzo di un indirizzo locale e uno
successivo viene bloccato (con fallimento)

con l'opzione, si convalida l'indirizzo di una socket senza controllo della


unicit di associazione
In particolare utile in caso di server che devono potere essere riavviati e
che devono essere operativi immediatamente
Si ricordi che la porta rimane impegnata dopo una close per anche molte decine
di secondi ce senza lopzione dovremmo aspettare per il riavvio

Il processo che deve eventualmente agganciarsi alla porta per il riavvio,


senza la opzione potrebbe incorrere in un fallimento fino alla liberazione
della porta (e della memoria corrispondente)
int optval=1;
setsockopt (s, SOL_SOCKET, SO_REUSEADDR,
&optval, sizeof(optval));
bind(s,&sin,sizeof(sin));

Socket in C 109

31:41

DURATA CLOSE su SOCKET


Opzione SO_LINGER modifica comportamento della close()
Il sistema tende a mantenere la memoria in uscita dopo la close anche per un
lungo intervallo

Con lopzione, si prevede la struttura linger da /usr/include/sys/socket.h:


struct linger { int l_onoff; int l_linger;

/* attesa in sec */ }

A default, disconnessione impegnativa in risorse, l_onoff == 0

default

l_onoff

l_linger

0
1
1

don't care
0
valore > 0

Graceful/Hard Chiusura Con/


Close
Senza attesa
G
Senza
H
Senza
G
Con

chiusura hard della connessione


l_linger a 0 ogni dato non inviato perso

chiusura graceful della connessione


l_onoff ad 1 e l_linger valore positivo la close() completa dopo il tempo in
secondi specificato dal linger e (si spera) dopo la trasmissione di tutti i dati nel
specifica la durata massima
buffer
Socket in C 110
-> close() sospende

default passante ma non si perdono tutti i dati in uscita

39:46

MODALIT
MODALIT
PRIMITIVE SOCKET
Sono di molto interesse modi che non siano sincroni ma lavorino senza
nessuna attesa correlata alla comunicazione
Socket asincrone con uso di primitive ioctl o fcntl e opzioni
Le socket asincrone permettono operazioni senza attesa, ma al
completamento tipicamente lutente viene avvisato con un segnale ad hoc
SIGIO segnala un cambiamento di stato della socket (per l'arrivo di dati)
SIGIO ignorato dai processi che non hanno definito un gestore

Gestione della socket e del segnale, ad esempio per la consegna dei dati
SIGIO socket asincrona con attributo FIOASYNC con primitiva ioctl()
sincrono non bloccante (tipic. unix: sincrono bloccante)
#include <sys/ioctl.h>
si potrebbe chiedere ad una socket
int ioctl (int filedesc, int request, ... /* args */)
filedescr file descriptor
request tipo di attributo da assegnare
poi
valori da assegnare all'attributo
A chi si deve consegnare il segnale, in un gruppo di processi???

Socket in C 111

52:26
jump

MODALIT
MODALIT
CONSEGNA SEGNALI
Per dare strumenti con la necessaria visibilit a volte si devono tenere
in conto altre caratteristiche
SIGIO a chi deve essere consegnato in un gruppo di processi?
Per la consegna di SIGIO, primitiva ioctl() con attributo SIOCSPGRP
parametro process group del processo alla socket asincrona.
int ioctl (filedescr, SIOCSPGRP, &flag)
flag valore negativo
segnale solo al processo con pid uguale al valore negato
flag valore positivo segnale arriva a tutti i processi del process group
valore positivo

valore negativo
PROCESSO padre:
accetta la connessione generando una
socket connessa.

PROCESSO padre e group leader:


qualifica asincrona della socket connessa e
assegnazione del process group positivo
coda

coda

Socket d'ascolto

PROCESSO figlio:
eredita la socket connessa e la qualifica come
asincrona, indicando un process group negativo

PROCESSO figlio (stesso group):


eredita la socket connessa e asincrona
Stream
dati
Connessione

SIGIO
Socket connessa e
asincrona.
E' condivisa con
il padre.

Socket d'ascolto

Stream
dati
Connessione

SIGIO

Socket connessa e
asincrona.
E' condivisa con
il padre.

Socket in C 112

49:30

ESEMPIO ASINCRONO
int ls; /* socket d'ascolto */
int flag=1;
/* valore per FIOASYNC per socket asincrona */
int handler(); /* gestore delle I/O sulle socket */
signal(SIGIO,handler); /* aggancio del gestore segnale */
-1)
if (ioctl (ls,FIOASYNC,&flag) ==
{ perror("non posso rendere asincrona la socket");
exit(1);
}
flag= - getpid();
/* identificatore di processo negativo */
if (ioctl (ls,SIOCSPGRP,&flag) ==
-1)
{ perror("non si assegna il process group alla socket");
exit(1);
}
In questo caso si consegna il segnale al solo processo che ne ha fatto
richiesta e si attiva lhandler solo per lui alla occorrenza del segnale di
SIGIO

Socket in C 113

56:28

ALTRI ESEMPI ASINCRONO


Le azioni sono fortemente dipendenti dal kernel e poco standard
Per la maggior parte dei sistemi Linux (ma si consulti la doc in linea)

int flag, ret;


#ifdef __linux__
flag = fcntl (s, F_GETFL);
if (fcntl (s, F_SETFL, flag | FASYNC ) == -1)
{ perror("fcntl failed");
exit(-1);}
flag = -getpid();
if (fcntl (s, F_SETOWN, flag) == -1)
{ perror("fcntl F_SETOWN)"); exit (-2);}
#endif
Potreste trovare molte proposte con delle macro condizionali
(ma cosa sono?)

Socket in C 114

58:00

SOCKET NON BLOCCANTI


In uno stesso sistema, modi simili si ottengono con procedimenti e
primitive diverse
Il non blocco si ottiene anche con primitiva ioctl() e parametro FIONBIO
valore 0 modalit default bloccante / valore 1 non bloccante
Si modificano le primitive in caso non bloccante
- accept()
restituisce errore di tipo EWOULDBLOCK
- connect()
condizione d'errore di tipo EINPROGRESS
- recv() e read() condizione d'errore di tipo EWOULDBLOCK
- send() e write() condizione d'errore EWOULDBLOCK
Esempio di assegnazione dell'attributo non bloccante
#include <sys/ioctl.h>
int s;
/* socket descriptor */
int arg=1;
/* valore per la qualifica non blocking */
ioctl(s,FIONBIO,&arg);
ioctl(s,FIOASYNC,&arg);

Socket in C 115

59:45

Non standardizzazione -> Mancata Portabilit

ANCORA SOCKET NON BLOCCANTI


Si pu usare anche la fcntl dedicata al controllo dei file aperti
#include <fcntl.h>

int fcntl (fileds, cmd, .../* argomenti */)


int fileds; /* file descriptor */ int cmd; /* argomenti */
Ad esempio:
if (fcntl

(descr, F_SETFL, FNDELAY) < 0)

{ perror("non si riesce a rendere asincrona la socket"); exit(1);}

Ma anche con attributi diversi O_NDELAY e comandi con significati diversi


in sistemi diversi
- System V: O_NDELAY
read(), recv(), send(), write() senza successo valore 0 immediato

- POSIX.1 standard, System V vers.4:

O_NONBLOCK

Le chiamate senza successo valore -1 e la condizione d'errore EAGAIN

- BSD: FNDELAY, O_NONBLOCK


Le chiamate senza successo valore -1 e la condizione d'errore EWOULDBLOCK
Socket in C 116

01:02:36

PROGETTO SERVER
In UNIX il progetto del server pu essere molto flessibile, sia
concorrente multiprocesso, sia monoprocesso,
e anche con eventuali processi leggeri
e anche il client
Tipo di
Tipo
di comunicazione
comunicazione
con connessione
con
connessione

S
E
R
V

sequenziale
iterativo
iterativo
iterativo
concorrente
singolo
singolo
singolo
processo
processo
processo

E
concorrente

R Tipo di Server
multi
multi

concorrente
concorrente
multi
processo
processo
processo

servizi poco pesanti e


affidabili

senzaconnessione
senza
connessione
Molto diffusi: per servizi
poco pesanti
non affidabili
solitamente stateless

La scelta del tipo

Il singolo processo facilita


Poco usati
condivisione dati
di Server dipende
tra richieste diverse
Servizi poco dalle
pesanti
e
caratteristiche
affidabili

del servizio da fornire

Molto diffusi:
servizi pesanti
e affidabili

es. Server Web

Costo fork non rende questa


classe conveniente (a meno
di pesantissime operazioni
di I/O)

Socket in C 117

Universit degli Studi di Bologna


Facolt di Ingegneria

Corso di
Reti di Calcolatori T
Implementazione RPC
Luca Foschini
Anno accademico 2012/2013
Implementazione RPC 1

RPC: motivazioni e modelli


Possibilit di invocare una procedura non locale
Loperazione interessa un nodo remoto e permette alle
entit non locali di richiederne un servizio
Modello di riferimento CLIENTE/SERVITORE
invocazione di un servizio remoto
con parametri tipati, valore di ritorno
Modello di base: P.B. Hansen (Distributed Processing)
Nelson, Birrel
Implementazione RPC 2

Funzionamento invocazione remota


Invocazione locale
della prodedura p

Invocazione remota
della prodedura p
Host A

Host B
service daemon
listening

callrpc() with
request

Host
main

invoke service

local procedure (p)

client
waiting

dispatch service
procedure

Network

remote
procedure
return() answer
(p)

return() reply

request completed,
reply assembled

Implementazione RPC 3

Requisiti per implementazione RPC


Uso di una infrastruttura di supporto che viene inglobata
nei processi impegnati nella interazione
Il supporto scambia messaggi per consentire
identificazione dei messaggi di chiamata e risposta
identificazione unica della procedura remota

Il supporto gestisce leterogeneit dei dati scambiati


marshalling/unmarshalling argomenti;
serializzazione argomenti;

Il supporto gestisce alcuni errori dovuti alla distribuzione


implementazione errata
errori dell'utente
roll-over (ritorno indietro)

Implementazione RPC 4

Semantica di interazione
A fronte di possibilit di guasto, il cliente pu
controllare o meno il servizio
maybe
at-least-once
at-most-once
exactly-once

(SUN RPC)

Per il parallelismo e la sincronizzazione possibile


operazioni per il SERVITORE
sequenziali (SUN RPC)
paralleli

operazioni per il CLIENTE


sincrone (SUN RPC)
asincrone
Implementazione RPC 5

Architettura
Portmapper
consults
registers

Server

Client

realizza
procedura

invoca la procedura
argument

result
result

argument

Client Stub

Server Stub

realizza
supporto RPC

realizza
supporto RPC

request
message

reply
message

reply
message

request
message

Network
Implementazione RPC 6

Implementazione del supporto


Noi vediamo limplementazione e il supporto RPC di
Sun Microsystems: Open Network Computing (ONC)
ONC una suite di prodotti che include:
eXternal Data Representation (XDR)
rappresentazione e conversione dati
Remote Procedure Call GENerator (RPCGEN)
generazione del client e server stub
Portmapper risoluzione indirizzo del servitore
Network File System (NFS)
file system distribuito di Sun
Implementazione RPC 7

OSI

Layers

SUN RPC e stack OSI


7. Application

User Application

6. Presentation

XDR

5. Session

RPC ritrasmissione

4. Transport

TCP

UDP

3. Network

IP

1-2.Data-link/Physical

Hardware Interface

Network
Implementazione RPC 8

Definizione del programma RPC


Due parti descrittive in linguaggio RPC:
1. definizioni di programmi RPC: specifiche del protocollo
RPC per i servizi offerti, cio l'identificazione dei servizi
ed il tipo dei parametri
2. definizioni XDR: definizioni dei tipi di dati dei parametri.
Presenti solo se il tipo di dato non un tipo noto in RPC
(per i dettagli vedere pi avanti...)

Raggruppate in un unico file con estensione .x


cio in formato XDR, che deve solo descrivere il
contratto di interazione
Ad esempio per il programma stampa tutte le definizioni contenute
in stampa.x
Implementazione RPC 9

Definizione del servizio remoto


Diamo tutte le definizioni delle procedure remote nel file stampa.x
/* stampa.x */
program STAMPAPROG {
version STAMPAVERS {
int PRINTMESSAGE(string) = 1;
} = 1;
} = 0x20000013;

Tralasciando per ora program e version (che vediamo dopo), questo pezzo
di codice definisce la procedura PRINTMESSAGE, con argomento di
tipo string e risultato di tipo int (intero)

Si notino i vincoli per RPC di SUN:


ogni definizione di procedura ha un solo parametro d'ingresso e un
solo parametro d'uscita
gli identificatori (nomi) usano lettere maiuscole
ogni procedura associata ad un numero di procedura unico
allinterno di un programma
Implementazione RPC 10

Implementazione del programma RPC


Il programmatore deve sviluppare:
1. il programma client: implementazione del main() e
della logica necessaria per reperimento e binding del
servizio/i remoto/i file esempio.c
2. il programma server: implementazione di tutte le
procedure (servizi)
file esempio_svc_proc.c
Mancano gli stub cliente e servitore, generati
automaticamente per produrre i programmi client e server

NOTA: lo sviluppatore NON realizza il main()...

Chi invoca la procedura remota (lato server)?


Implementazione RPC 11

RPC: un primo esempio


Servizio di stampa di messaggi su video locale

In locale
# include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{ char *message;
if (argc !=2) {fprintf(stderr,"uso:%s <messaggio>\n", argv[0]); exit(1);}
message = argv[1];
if (! printmessage (message)){ /* chiamata locale servizio di stampa su video */
fprintf(stderr,"%s: errore sulla stampa.\n", argv[0]);
exit(1);
}
printf("Messaggio consegnato.\n");
exit(0);
}
printmessage (msg) /* procedura locale per il servizio di stampa su video. */
char *msg;
{ FILE *f;
f = fopen("/dev/console","w");
if (f == NULL) return(0);
fprintf(f,"%s\n",msg); fclose(f);
return(1);
Implementazione RPC 12
}

In caso remoto si deve


trasformare come segue

Sviluppo della procedura di servizio


Il codice del servizio (quasi) identico alla versione locale
#include <stdio.h>
#include <rpc/rpc.h>
#include "msg.h" /* prodotto da RPCGEN */
int * printmessage_1_svc (msg, rp)
char ** msg; /* argomento passato per indirizzo */
struct svc_req * rp;
{ static int result;
FILE *f; f=open("/dev/console","w");
if (f==NULL) { result=0; return(&result); }
fprintf(f,"%s\n",*msg); fclose(f); result=1;
return(&result); /* restituzione risultato per indirizzo */
}

Differenze rispetto al caso locale (in C)


sia largomento di ingresso che luscita vengono passati per riferimento
il risultato punta ad una variabile statica (allocazione globale, si veda
oltre), per essere presente anche oltre la chiamata della procedura
il nome della procedura cambia leggermente (si aggiunge il carattere
underscore seguito dal numero di versione, tutto in caratteri minuscoli)
Implementazione RPC 13

Sviluppo del programma principale:


CLIENTE
Il cliente viene invocato col nome dellhost remoto e il messaggio da
stampare a video e richiede il servizio di stampa a video remota
#include <stdio.h>
#include <rpc/rpc.h>
#include "msg.h" /* prodotto da RPCGEN */
main(argc,argv) /* programma client */
int argc; char *argv[];
{ CLIENT *cl; int *result;
char *server; char *message;
if(argc<3) {fprintf(stderr,"uso: %s host msg\n", argv[0]); exit(1);}
server = argv[1]; message = argv[2];
cl = clnt_create(server, STAMPAPROG, STAMPAVERS, "udp");
if (cl==NULL) { clnt_pcreateerror (server); exit(1); }
result = printmessage_1(&message,cl); /* invocazione client stub */
/* Controllo esito richiesta, dettagli pi avanti */
if (result==NULL) { clnt_perror (cl,server); exit(1); }
if (* result == 0)
{ fprintf(stderr,"%s: %s problema\n", argv[0], server); exit(1); }
printf("Messaggio consegnato a %s\n",server);
Implementazione RPC 14
}

(inizio registrazione 03.12.12)

Variazioni rispetto al caso locale


Si noti la creazione del gestore di trasporto client (si veda oltre per
ulteriori dettagli): il gestore di trasporto (cl) gestisce la comunicazione col
server, in questo caso utilizzando un trasporto senza connessione (udp)
Il client deve conoscere:
lhost remoto dove in esecuzione il servizio;
alcune informazioni per invocare il servizio stesso (programma, versione e
nome della procedura)

Per linvocazione della procedura remota:


il nome della procedura cambia: si aggiunge il carattere underscore seguito
dal numero di versione (in caratteri minuscoli)
Gli argomenti della procedura server sono due: i) largomento di ingresso
vero e proprio e ii) il gestore di trasporto del client

Il client gestisce gli errori che si possono presentare durante linvocazione


remota usando le funzionalit di stampa degli errori: clnt_pcreateerror
e clnt_perror
Implementazione RPC 15

01:48

Passi di sviluppo di SUN RPC


1. Definire servizi e tipi di dati (se necessario) esempio.x
2. Generare in modo automatico gli stub del client e del server e (se
necessario) le funzioni di conversione XDR uso di RPCGEN
3. Realizzare i programmi client e server (client.c
e
esempio_svc_proc.c), compilare tutti i file sorgente (programmi
client e server, stub, e file per la conversione dei dati), e fare il linking
dei file oggetto
4. Pubblicare i servizi (lato server)
1. attivare il Portmapper
2. registrare i servizi presso il Portmapper (attivando il server)

5. Reperire (lato client) lendpoint del server tramite il Portmapper e


creare il gestore di trasporto per linterazione col server
A questo punto linterazione fra client e server pu procedere
N.B.: questa una descrizione di base, dettagli su RPCGEN, Portmapper
e gestore di trasporto saranno dati nel seguito
Prima di vedere pi in dettaglio il funzionamento del supporto RPC proviamo a fare
un confronto con Java RMI...
Implementazione RPC 16

03:05

RPC e sistemi UNIX


le RPC sfruttano i servizi delle socket:
sia TCP per stream
servizi con connessione
sia UDP per datagrammi (default SUN)
servizi senza connessione
Ap p li c a zio n e d i s tribu ita ba s a ta s u RP C

Defin izion e ed u t ilizzo di ser vizi RP C


Gest ion e a va n za t a del pr ot ocollo RP C

Interfaccia RPC

Ut ilizzo di ser vizi RP C st a n da r d

Diversi livelli di
astrazione
flessibilit

In t er fa ccia socket (BSD)

P r otocolli di tr a spor to (UDP e TCP )

Implementazione RPC 17

05:38

SUN RPC
In caso di RPC SUN
Un programma tipicamente contiene pi procedure
remote
Sono previste anche versioni multiple delle procedure
Un unico argomento in ingresso ed in uscita per ogni
invocazione

Semantica e controllo concorrenza


Mutua esclusione garantita dal programma (e server): non
si prevede alcuna concorrenza a default nell'ambito dello
stesso programma server
Server sequenziale ed una sola invocazione
eseguita per volta
Fino al ritorno al programma cliente, il processo cliente
in modo sincrono bloccante in attesa della risposta
Se server seq e clienti sincroni bloccanti -> se il server richiede qualcosa al client durante Implementazione RPC 18
l'esecuzione della richiesta -> deadlock -> clienti non bloccanti o server paralleli

Rischi e problemi RPC


Considerando servitori sequenziali
Possibilit di deadlock se un server in RPC richiede, a sua
volta, un servizio al programma chiamante
Naturalmente, pi chiamate RPC possono manifestarsi in
parallelo su un nodo servitore... che le serve una alla volta
e SERVIZI PARALLELI??
Potrebbero consentire risparmio e throughput maggiore
si possono realizzare? E come?
Semantica e affidabilit
Uso di protocollo UDP (default SUN)
Semantica at-least-once: a default, si fanno un certo numero
di ritrasmissioni dopo un intervallo di time-out (ad
esempio, 4 secondi)
Implementazione RPC 19

11:30

Identificazione di RPC
Messaggio RPC deve contenere
numero di programma
numero di versione
numero di procedura

per la identificazione globale


Numeri di programma (32 bit)
0 - 1fffffffh predefinito Sun applicazioni d'interesse comune
20000000h - 3fffffffh definibile dall'utente applicazioni debug dei nuovi servizi
generare
dinamicamente
40000000h - 5fffffffh riservato alle applicazioni per
numeri di programma
Altri gruppi riservati per estensioni

notare:

32 bit per il numero di programma


numero delle porte 16 bit

Procedure -> 0 per gestione

soluzione:
AGGANCIO DINAMICO

Programma mappato su una porta

Autenticazione
Sicurezza identificazione del client presso il server e viceversa
sia in chiamata sia in risposta
Implementazione RPC 20

16:46

Livello alto RPC


Utilizzo di servizi RPC standard
Esempi di procedure pronte per essere invocate da un nodo ad un altro
Routine RPC

Descrizione

rnusers()

Fornisce il numero di utenti di un nodo

rusers()

Fornisce informazioni sugli utenti di un nodo

rstat()

Ottiene dati sulle prestazioni verso un nodo

rwall()

Invia al nodo un messaggio

getmaster()

Ottiene il nome del nodo master per NIS

getrpcport()

Ottiene informazioni riguardo agli indirizzi TCP legati ai servizi RPC

Numeri di programma noti


portmap
rstat
rusers
nfs
...

100000
100002
100002
100003

(port mapper)
(demone rstad)
(demone rusersd)
(demone nfsd)
Implementazione RPC 21

19:50

ESEMPIO: invocazione di rnuser()


/* Nota: utilizzare la libreria corretta in fase di linking, ad
esempio rpcsvc */
#include <stdio.h>
int rnusers(); /* dichiarazione di rnusers */ extern -> qualcun'altro la mette a disposizione
procedure static -> visibili solo al file corrente
main(argc,argv)
auto
variabili
int argc; char *argv[];
{ int num;
if (argc<2)
{fprintf(stderr,"uso:%s hostname\n", argv[0]); exit(1);}
if((num=rnusers(argv[1]))<0)
//unico parametro -> hostname remoto
{fprintf(stderr,"errore: rnusers\n"); exit(1);}
printf("%d utenti su %s\n",num,argv[1]);
exit(0);
}

Si possono cos usare direttamente le funzioni remote se sono riconosciute


Viene invocato direttamente il server richiesto
Implementazione RPC 22
In realt, si veda dopo cosa c' sotto...

26:15

Livello intermedio RPC


Definizione ed utilizzo di nuovi servizi RPC
Due primitive: callrpc() e registerrpc()
CLIENT - callrpc() chiamata esplicita al meccanismo RPC e provoca l'esecuzione
della procedura remota
SERVER - registerrpc() associa un identificatore unico alla procedura remota
implementata nell'applicazione
Azioni compiute per ogni
invocazione di procedura
dalla parte del servitore
1. ricerca in tabella
della procedura
2. recapito richiesta al
programma ritrovato

Implementazione RPC 23

29:20

CLIENT: richiesta esecuzione RPC


Primitiva callrpc: due parametri un argomento e un risultato
int callrpc (remotehost, n_prog, n_vers, n_proc,
xdr_arg, arg, xdr_res, res )
char
*remotehost; nome del nodo remoto
u_long
n_prog,n_vers,n_proc; identificazione procedura
Punta a una xdrproc_t xdr_arg; tipo argomento di ingresso
funzione
char
*arg; argomento di ingresso (passaggio per valore)
che trasforma
xdrproc_t xdr_res; tipo risultato (per la funzione XDR)
nel tipo
standard
char
*res; risultato
per la trasmissione
Da locale
Problemi nel passaggio di strutture a lista:
a XDR
struttura dinamica (vedi dettagli uso XDR pi

il ricevente deve ricostruire la


avanti)

La callrpc restituisce successo ( =0) o la causa di insuccesso


Ritorno intero appartenente all'insieme di valori della struttura enum clnt_stat
definita nel file <rpc/clnt.h>
Implementazione RPC 24

problemi... 35:30
Riprende a 41:08

ERRORI o SUCCESSO: esempi


enum clnt_stat {
RPC_SUCCESS=0,
/* call succeeded */
/* local errors */
RPC_CANTENCODEARGS=1,
/* can't encode args */
RPC_CANTDECODERES=2,
/* can't decode results */
RPC_CANTSEND=3,
/* failure in sending call */
RPC_CANTRECV=4,
/* failure in receiving result */
RPC_TIMEDOUT=5,
/* call timed out */
/* remote errors */
RPC_VERSMISMATCH=6,
/* rpc versions not compatible */
RPC_AUTHERROR=7,
/* authentication error */
RPC_PROGUNAVAIL=8,
/* program not available */
RPC_PROGVERSMISMATCH=9, /* program version mismatched */
RPC_PROCUNAVAIL=10,
/* procedure unavailable */
RPC_CANTDECODEARGS=11
,/* decode args error */
RPC_SYSTEMERROR=12,
/* generic "other problem" */
/* callrpc errors */
RPC_UNKNOWNHOST=13,
/* unknown host name */
RPC_UNKNOWNPROTO=17,
/* unkown protocol */
/* create errors */
RPC_PMAPFAILURE=14,
/* pmapper failed in its call */
RPC_PROGNOTREGISTERED=15, /* remote program not registered */
};

Inoltre: possibilit di
terminazione per
timeout

Semantica at-least-once
(default con UDP): prima
di dichiarare time-out, il
supporto RPC esegue
alcune ritrasmissioni in
modo trasparente

Implementazione RPC 25

41:20

Livello intermedio: esempio invocazione


servizio RPC standard lato client
Invocazione di rnusers()
conoscendo l'identificatore del servizio in <rpcsvc/rusers.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <rpcsvc/rusers.h>
main(argc,argv)
int argc; int *argv[];
{ unsigned long nusers;
if(argc<2)
{fprintf(stderr,"uso: %s hostname\n",argv[0]); exit(1);}
if ( callrpc(argv[1], RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM,
xdr_void, 0, xdr_u_long, &nusers) != 0)
{fprintf(stderr,"error: callrpc\n"); exit(1); }
printf("%d users on %s\n", nusers,
argv[1]); exit(0);
Implementazione RPC 26
}

43:27

Livello intermedio: realizzazione


servizio remoto utente lato client
Identificatore del servizio d'esempio scelto fra quelli disponibili per l'utente e noto ad
entrambi i programmi
#include <stdio.h>
#include <rpc/rpc.h>
#define RPC5 (unsigned long) 0x20000015
#define VER5 (unsigned long) 1
#define PRC5 (unsigned long) 1
main(argc,argv)
int argc; char *argv[];
{ unsigned long b; unsigned long a=3;
if (argc<2) { exit(1);}
if (callrpc (argv[1], RPC5, VER5, PRC5, xdr_u_long, &a,
xdr_u_long, &b)!=0)
{fprintf(stderr,"errore:callrpc\n"); exit(1);}
printf("Risultato: %d\n", b); exit(0); }
Semplice operazione aritmetica sull'argomento (incremento di 100): intero in
ingresso e risultato intero in uscita
Implementazione RPC 27

45:17

Livello intermedio: realizzazione


servizio remoto utente lato server
Implementazione procedura remota: le funzioni del protocollo RPC ricevono
l'argomento e lo mettono in un'area di memoria del server passando l'indirizzo al
server
# include <>
#define RPC5 (u_long) 0x20000015
#define VER5 (u_long) 1
#define PRC5 (u_long) 1
u_long * proc5 (a)
u_long *a;
{ static u_long
b;
b = *a + 100; return((u_long *)&b);
}

Il risultato deve essere una variabile di tipo statico alla terminazione della
procedura per non essere deallocato come le variabili automatiche
Inoltre necessario registrare la procedura remota (dettagli dopo)
main(){
registerrpc (RPC5, VER5, PRC5, proc5, xdr_u_long, xdr_u_long);
svc_run();
/* attesa indefinita senza ritorno */ funzione (non primitiva) che mantien
fprintf(stderr,"Errore: svc_run ritornata!\n");
exit(1);
Implementazione RPC 28
}

49:55

Omogeneit dei dati


Per comunicare tra nodi eterogenei due soluzioni
1. Dotare ogni nodo di tutte le funzioni di conversione possibili per ogni
rappresentazione dei dati
alta performance e alto numero di funzioni di conversione N*(N-1)

2. Concordare un formato comune di rappresentazione dei dati: ogni nodo


possiede le funzioni di conversione da/per questo formato
minore performance, ma basso numero di funzioni di conversione 2*N
Nodo 1

Nodo 2

Nodo 1

Nodo 2

XDR

Nodo 3

Nodo 4

Sono necessarie 12 funzioni


di conversione del formato di dati

Nodo 3

Nodo 4

Standard (modello
OSI) porta alla
scelta del secondo
metodo:
XDR (Sun
Microsystems)

Sono necessarie 8 funzioni


di conversione del formato di dati

Implementazione RPC 29

50:46

eXternal Data Representation (XRD)


Come stream che trasforma i dati

Marshalling

XDR procedure built-in di


conversione, relative a:

P r ocesso clien t

P r ocesso ser ver

In t er fa ccia RP C

In t er fa ccia RP C

P r ot ocollo XDR

P r ot ocollo XDR
Serializing

NOTA: la primitiva callrpc accetta


solo un argomento ed un solo
risultato necessit di definire
una struttura che li raggruppa

S e rv e r

Serializing

Tipi atomici predefiniti


Tipi standard (costruttori
riconosciuti)

Cli e n t

Livelli di session e,
t r a spor to, r ete,
da t a lin k e fisico

F or m a t o XDR

Deserializing

che si colloca in OSI al livello


di Presentazione

Deserializing

Funzioni svolte da protocollo XDR

Livelli di session e,
t r a spor t o, r ete,
da ta lin k e fisico

Implementazione RPC 30

52:30

Stream XDR
Per ogni informazione da trasmettere si hanno due
trasformazioni, una al mittente e una al destinatario sulla rete il
solo formato XDR
Client
Server
Ogni nodo deve
provvedere solamente le
proprie funzionalit di
trasformazione
dal formato locale a
quello standard
dal formato standard a
quello locale

Protocollo XDR
Deserializing

RES

Protocollo XDR

Serializing

Deserializing

ARG

ARG

xdr_arg

xdr_arg

RES

XDR1
xdr_res

Le funzioni XDR sono


usate anche per la sola
trasformazione dei dati (e
non associate alla
comunicazione)

Serializing

xdr_res

XDR2
Flussi XDR
Implementazione RPC 31

53:20

Funzioni di conversione
Funzioni built-in

Funzioni per tipi composti

Implementazione RPC 32

54:48

Funzioni di utilit XDR: esempio


Funzioni XDR per la conversione di numeri interi, vedi file rpc/xdr.h
bool_t xdr_int (xdrs,ip)
XDR *xdrs;int *ip;

Le funzioni xdr restituiscono valore vero se la conversione ha


successo

Possono funzionare anche con tipi definiti dall'utente, ad esempio


creazione di una struttura per il passaggio a callrpc()
struct simple {int a;

short b;} simple;

/* procedura XDR mediante descrizione con funzioni built-in */


#include <rpc/rpc.h> /* include a sua volta xdr.h */
bool_t xdr_simple (xdrsp, simplep)
XDR *xdrsp; /* rappresenta il tipo in formato XDR */
struct simple *simplep;
/* rappresenta il formato interno */
{ if (!xdr_int (xdrsp,&simplep->a)) return(FALSE);
if (!xdr_short (xdrsp, &simplep->b)) return (FALSE);
return(TRUE);
Implementazione RPC 33
}

01:00:30

Server: registrazione procedura remota


Un servizio registrato pu essere invocato: al servizio viene
associato un identificatore strutturato secondo il protocollo
RPC

Il server deve registrare la


procedura
nella
tabella
dinamica dei servizi del nodo
Concettualmente una entry per
procedura...
... in realt (come vedremo pi
avanti), la registrazione fisica un
po diversa

Implementazione RPC 34

01:00:45

Primitiva di registrazione: registerrpc


int registerrpc (n_prog, n_vers, n_proc,
proc_name, xdr_arg, xdr_res)
u_long n_prog, n_vers, n_proc;
char *(* proc_name ) ();
xdrproc_t xdr_arg, xdr_res;
n_prog, n_vers, n_proc identificazione della procedura
proc_name
puntatore alla procedura da attivare
xdr_arg
tipo di argomento
xdr_ares
tipo di risultato (per la funzione XDR)
La registerrpc viene eseguita dal server che la vuole rendere nota ed invocabile
da clienti remoti una entry per ogni registrazione
int svc_run()
Il processo del programma corrente si mette in attesa indefinita di una
richiesta per fornire i servizi
Implementazione RPC 35

01:01:00

Primitiva svc_run
Dopo la registrazione della procedura, il processo che ha eseguito la
primitiva registerrpc() deve rimanere in attesa di chiamate
Un server si comporta come un demone mettendosi in attesa di tutte le
possibili richieste attraverso la svc_run() che esprime la attesa infinita
del server e che non termina

Uso
di
processi
servitori
che
contengono i servizi (procedure), anche
pi di uno, e sono in attesa
Le
procedure
registrate
con
registerrpc() sono compatibili con
chiamate realizzate da primitive basate
su meccanismi di trasporto UDP senza
connessione, ma incompatibili con TCP
a stream

Implementazione RPC 36

01:02:30

Corrispondenza dei nomi


In realt, la tabella si basa su una registrazione fisica:
tripla {numero_progr, numero_vers, protocollo_di_trasporto} e
numero di porta
in una tabella detta port map
Manca il numero di procedura dato che tutti i servizi RPC (procedure allinterno di un
programma) condividono lo stesso gestore di trasporto
La tabella strutturata come insieme di elementi:

struct mapping {
unsigned
unsigned
unsigned
unsigned

long prog;
long vers;
int prot; // uso costanti IPPROTO_UDP ed IPPROTO_TCP
int port; / corrispondenza con la porta assegnata

};
/* implementazione a lista dinamica della tabella */
struct *pmaplist { mapping map; pmaplist next;}
Implementazione RPC 37

01:04:46

PORT MAPPER
La gestione della tabella di port_map si basa su un processo unico per ogni
nodo RPC detto port mapper che viene lanciato come demone (cio in
background)

Il port mapper abilita due gestori di trasporto


propri
uno per UDP ed
uno per TCP

con due socket legate allo stesso numero di


porta (111)
il numero di programma e versione del port
mapper: 100000
2

Implementazione RPC 38

01:07:25
Fine della Techno in Aula -.-"

PORT MAPPER: motivazioni e dettagli


PORT MAPPER server di nomi, lui stesso server RPC
Per limitare il numero di porte riservate un solo processo sulla porta 111
Il port mapper identifica il numero di porta associato ad un qualsiasi programma
allocazione dinamica dei servizi sui nodi
Il port mapper registra i servizi sul nodo e offre le seguenti procedure:

Inserimento di un servizio
Eliminazione di un servizio
Corrispondenza associazione astratta e porta
Intera lista di corrispondenza
Supporto all'esecuzione remota

A default utilizza solo il trasporto UDP

Limiti: dal cliente ogni chiamata interroga il port mapper (poi


attua la richiesta)
Per avere la lista di tutti i servizi invocabili su di un host remoto si provi ad invocare
il comando:
rpcinfo -p nomehost
Implementazione RPC 39

01:10:13

Architettura e funzioni RPC: lato client


Nodo CLIENT

Cliente1

Cliente2

Gestore trasporto
Porta A

Creazione ed utilizzo di un
gestore di trasporto lato
client
Una struttura dati di supporto,
detta gestore di trasporto, viene
usata per tenere traccia e potere
comunicare con i potenziali
servitori

Gestore trasporto
Porta B

Implementazione RPC 40

01:11:06

Architettura e funzioni RPC: lato server


Creazione di un gestore di
trasporto
Per mantenere il collegamento
RPC con i potenziali clienti, e in
particolare con il servizio
corrente

Nodo SERVER
porta

prog, vers, prot

Numero di porta
Porta A

Port mapper
porta 111

Gestore trasporto

Programma 1

Porta A

Dispatching

Dispatching (locale) del


messaggio RPC

Servizi

Per inoltrare la richiesta del


client alla procedura corretta:
il messaggio RPC contiene il
numero della procedura

Gestore trasporto
Porta B

Programma 2

Implementazione RPC 41

Architettura e funzioni RPC


Nodo CLIENT
Nodo SERVER
porta

prog, vers, prot

Numero di porta
Porta A

Cliente1

Cliente2
Port mapper
porta 111

Gestore trasporto

Gestore trasporto

Programma 1

Porta A
Porta A

Dispatching
Servizi

Gestore trasporto
Porta B

Gestore trasporto
Porta B

Programma 2

Implementazione RPC 42

(inizio registrazione 07.12.12)

01:13:20

poi alla slide 54

Livello basso RPC


Gestione avanzata
del protocollo RPC
Le chiamate remote
sono gestite tramite
funzioni avanzate per
ottenere massima
capacit espressiva

Flusso di operazioni
per RPC in gestione
avanzata
La chiamata
svc_register() e la
svc_run() possono
essere implementate con
funzioni di pi basso
livello

Client
Creazione di un gestore di protocollo
che utilizza una socket per accedere al
meccanismo di trasporto UDP o TCP:

Server
Creazione di gestore di protocollo
che utilizza una socket per il
meccanismo di trasporto UDP o TCP:

clntudp_create() o
clntcp_create()
Chiamata alla procedura remota:

clnt_call()

svcudp_create() o
svctcp_create

Distruzione di eventuali precedenti


registrazioni con lo stesso numero
di programma e versione:

pmap_unset()

Interpretazione degli eventuali errori:

clnt_perror()
Deallocazione del gestore:

clnt_destroy()

Associazione di una tripla


{n_prog,n_vers,protocollo} ad
una procedura di dispatching che
implementa i vari servizi:

svc_register()

Ingresso nel ciclo infinito di attesa


e servizio della chiamata:

svc_run()

Implementazione RPC 43

01:16:40

SERVER: creazione di un gestore di trasporto


La registerrpc() utilizza
svcudp_create() per ottenere un gestore UDP
svctcp_create() per ottenere un gestore TCP

(default per SUN)


(in caso di protocollo affidabile)

Il gestore di trasporto definito dal tipo SVCXPRT


typedef struct {
#ifdef KERNEL struct socket * xp_sock;
#else int xp_sock;
#endif
u_short
xp_port;
struct xp_ops {
bool_t
(*xp_recv)();
enum xprt_stat (*xp_stat)();
bool_t
(*xp_getargs)();
bool_t
(*xp_reply)();
bool_t
(*xp_freeargs)();
void (*xp_destroy)();
} * xp_ops;
int
xp_addrlen;
struct sockaddr_in xp_raddr;
struct opaque_auth xp_verf;
caddr_t
xp_p1;
caddr_t
xp_p2;
} SVCXPRT;

/* socket associata */
/* numero di porta assoc.*/
/*
/*
/*
/*
/*
/*

ricezione richieste */
stato del trasporto */
legge gli argomenti */
invia una risposta */
libera memoria allocata */
distrugge la struttura */

/*
/*
/*
/*
/*

lunghezza ind. remoto */


indirizzo remoto */
controllore risposta */
privato */
privato */
Implementazione RPC 44

01:18:55

SERVER: gestore di trasporto (ancora)


una struttura astratta che
contiene puntatori alle operazioni sui dati
riferisce due socket e una porta (locale)
una per il protocollo di trasporto del server (xp_sock)
una (se richiesta in atto) a cui inviare i risultati della esecuzione remota (xp_raddr)

SVCXPRT * svcudp_create (sock)


int sock;
SVCXPRT * svctcp_create (sock, send_buf_size, recv_buf_size )
int sock; u_int send_buf_size,recv_buf_size;
svcudp_create(): se sock vale RPC_ANYSOCK si crea un datagram
socket per i risultati
Altrimenti, il parametro un socket descriptor (collegato ad uno specifico numero di porta
o meno). Se la socket associata al gestore non ha un numero di porta e non si tratti di
RPC_ANYSOCK, si genera un numero di porta in modo automatico

svctcp_create() funziona in modo analogo: si devono definire le dimensioni


dei buffer tramite cui si scambiano i dati
In caso di insuccesso, non si crea il gestore

Implementazione RPC 45

01:19:53

SERVER: procedura di dispatching


La procedura di dispatching contiene i riferimenti alle implementazioni dei servizi di
un programma RPC lo stesso gestore e lo stesso protocollo di trasporto
La procedura di dispatching seleziona il servizio da eseguire interpretando il
messaggio RPC consegnato dal gestore (svc_req)
struct svc_req {
u_long rq_prog;
u_long rq_vers;
u_long rq_proc;
struct opaque_auth rq_cred;
caddr_t rq_clntcred;
SVCXPRT * rq_xprt;

/*
/*
/*
/*
/*
/*

numero di programma */
versione */
procedura richiesta */
credenziali */
credenziali di sola lettura */
gestore associato */

};
void

dispatch

(request, xprt)
struct svc_req *request;
SVCXPRT *xprt;

rq_proc identifica la procedura da svolgere


rq_xprt identifica la struttura dati del gestore di trasporto, dalla quale possibile (si
veda struttura SVCXPTR):
ricavare i parametri per l'esecuzione tramite svc_getargs()
spedire la risposta tramite la svc_sendreply()

Implementazione RPC 46

01:20:30

SERVER: procedura di dispatching (ancora)


bool_t svc_getargs (xprt,inproc,in)
SVCXPRT *xprt;
xdrproc_t inproc;
/* routine XDR */
char *in;
/* puntatore a struttura dati */
bool_t svc_sendreply (xprt,outproc,out)
SVCXPRT *xprt;
xdrproc_t outproc;
/* routine XDR */
char *out;
/* puntatore a struttura dati */

Funzioni XDR per conversioni formato argomenti e risultati


I valori di input (getargs) e di output (sendreply) sono in formato locale
Ci sono molte altre funzioni per ottenere informazioni sul gestore di trasporto e
fornire informazioni ulteriori
La funzione di registrazione inserisce i servizi nel dispatching, inoltre:
la NULLPROC (numero di procedura 0) verifica se il server attivo
controllo della correttezza del numero di procedura, in caso contrario svcerr_noproc()
gestisce l'errore
Implementazione RPC 47

01:20:55

SERVER: procedura di dispatching (ancora)


Associa numero programma e versione
Una procedura di dispatching associata ad una tripla {n_prog, n_vers, protocollo}
mediante la primitiva svc_register()
bool_t svc_register (xprt, prognum, versnum, dispatch, protocol)
SVCXPRT *xprt; /* gestore di trasporto */
u_long prognum,versnum;
char (*dispatch());
u_long protocol;

xptr
prognum, versnum
dispatch
protocol

gestore di trasporto
identificazione della procedura
puntatore alla procedura di dispatching
tipo di protocollo

Non ci sono indicazioni di tipi XDR solo all'interno dell'implementazione di


ogni servizio
E se si registra due volte la stessa procedura di dispatching?
Implementazione RPC 48

01:22:30

CLIENT: creazione di un gestore di trasporto


Il client necessita di un gestore di trasporto per RPC
L'applicazione chiamante utilizza clntudp_create() per ottenere un gestore
UDP
Anche clnttcp_create() per protocollo affidabile
La callrpc() ottiene un gestore di trasporto con clntudp_create()
A livello intermedio l'interfaccia RPC si basa su UDP
typedef struct {
AUTH
*cl_auth;
/* autenticazione */
struct clnt_ops {
enum clnt_stat (* cl_call)(); /* chiamata di procedura remota */
void (* cl_abort)();
/* annullamento della chiamata */
void (* cl_geterr)();
/* ottiene uno codice d'errore */
bool_t (* cl_freeres)(); /* libera lo spazio dei risultati */
void (* cl_destroy)(); /* distrugge questa struttura */
bool_t (*cl_control)(); /* funzione controllo I/ORPC */
} * cl_ops;
caddr_t
cl_private;
/* riempimento privato */
Implementazione RPC 49
} CLIENT;

01:23:40

CLIENT: creazione di un gestore di trasporto


(ancora)
CLIENT *clntudp_create(addr, prognum, versnum, wait, sockp)
struct sockaddr_in *addr; u_long prognum,versnum;
struct timeval wait; int *sockp;
CLIENT *clnttcp_create(addr, prognum, versnum, sockp, sendsz,
recvsz)
struct sockaddr_in *addr; u_long prognum,versnum;
int *sockp; u_int sendsz,recvsz;
wait

durata dell'intervallo di time-out


sendsz, recsz

dimensione dei buffer


Non ci sono riferimenti espliciti alla socket di trasporto ed al socket address per la
richiesta di esecuzione remota
Tra i parametri della clntudp_create() il valore del timeout fra le eventuali
ritrasmissioni; se il numero di porta all'interno del socket address remoto vale 0, si lancia
un'interrogazione al port mapper per ottenerlo
clnttcp_create() non prevede timeout e definisce dimensione
output
L'interrogazione iniziale causa una connessione
L'accettazione della connessione, consente la RPC

buffer di input e di

Implementazione RPC 50

01:25:40

CLIENT: chiamata della procedura remota


Creato il gestore di trasporto si raggiunge un'entit {n_prog, n_vers, protocollo}
tramite il numero di porta relativo la procedura di dispatching gi selezionata
la clnt_call() specifica solo gestore di trasporto e numero della procedura
enum clnt_stat clnt_call (clnt, procnum,inproc,in,outproc,out,tout)
CLIENT *clnt; u_long procnum;
xdrproc_t inproc; /* routine XDR */
char *in;
xdrproc_t outproc; /* routine XDR */
char *out;
struct timeval tout;
clnt

gestore di trasporto locale


procnum

identificazione della procedura


inproc

tipo di argomenti
outproc

tipo di risultato
in

argomento unico
out

risultato unico
tout

tempo di attesa della risposta


se UDP, il numero di ritrasmissioni dato dal rapporto fra tout ed il timeout indicato
nella clntudp_create()
se TCP, tout indica il timeout oltre il quale il server considerato irraggiungibile
Implementazione RPC 51

01:27:00

CLIENT: analisi errori e rilascio risorse


Risultato di clnt_call() analizzato con clnt_perror() che stampa sullo
standard error una stringa contenente un messaggio di errore
void

clnt_perror

(clnt,s)

CLIENT * clnt;
char * s;

clnt
s

gestore di trasporto
stringa di output

Distruzione del gestore di trasporto del client


clnt_destroy() dealloca lo spazio associato al gestore CLIENT, senza
chiudere la socket
Pi gestori possono condividere una stessa socket
void clnt_destroy (clnt)
CLIENT *clnt;
Implementazione RPC 52

Uso SUN RPC:


Dettagli

Implementazione RPC 53

9:44 07.12.12

Esempio completo di utilizzo di XDR


Linguaggio dichiarativo di specifica dei dati e della interazione per RPC
due sottoinsiemi di definizioni
1.
2.

definizioni di tipi di dati: definizioni XDR per generare le definizioni in C e le relative


funzioni per la conversione in XDR
definizioni delle specifiche di protocollo RPC: definizioni di programmi RPC per il
protocollo RPC (identificazione del servizio e parametri di chiamata)

Esempio: NFS

Senza stato per non appesantire il servitore

const MAXNAMELEN=256; const MAXSTRLEN=255;


struct r_arg { string filename<MAXNAMELEN>; int start; int length;};
per dire alle funzioni di trasformazione quanto lunga -> per efficienza
struct w_arg
{ string filename <MAXNAMELEN>; opaque block<>; int start;};
struct r_res { int errno; int reads; opaque block<>;};
struct w_res { int errno; int writes;}; blocco passato senza processamento
program ESEMPIO {
/* definizione di programma RPC */
version ESEMPIOV { Ricorda: 0 metodo vuoto che hanno tutti i server rpc per testare il server
int
PING(int)=1; richiesta -> risposta
r_res READ(r_arg)=2;
w_res WRITE(w_arg)=3;
}=1;
Implementazione RPC 54
}=0x20000020;

19:30

Generazione Automatica delle RPC


Maggiore astrazione dell'applicazione uso di procedure stub
Remote Procedure Call Generator (RPCGEN)
compilatore di protocollo RPC genera procedure stub in modo automatico

RPCGEN processa
un insieme di costrutti descrittivi per tipi di dati e per le procedure remote linguaggio XDR
Client

Programma
principale
client

chiamata
locale

Server

comunicazione
attraverso
l'interfaccia RPC

chiamate
locali

Procedura 1
stub
client

stub
server

Procedura 2
Parti sviluppate direttamente dal programmatore

Implementazione RPC 55

Parti fornite da RPCGEN

20:42

Processo di sviluppo
Data una specifica di partenza
file di linguaggio XDR
esempio.x
RPCGEN produce in automatico
file di testata (header)
esempio.x
esempio.h
file stub del client
esempio_clnt.c
file stub del server
esempio_svc.c
file di routine XDR
esempio_xdr.c

client.c

CC

client.o

esempio_clnt.o

esempio_clnt.c

client

CC
CC

esempio.h

esempio_xdr.o

RPCGEN
CC
esempio_xdr.c
esempio_svc.c

esempio_svc.o
CC

CC
server

esempio_proc_svc.c

Lo sviluppatore deve realizzare


programma client client.c
programma server esempio_svc_proc.c

CC

eempio_proc_svc.o

Implementazione RPC 56

27:05

namenode
namelist

name

string

next

altro namenode o niente

ESEMPIO COMPLETO: file .x


Servizio di remote directory list (RLS)
una procedura remota che fornisce la lista dei file di un direttorio di un file
system su nodo remoto strutture ricorsive come le liste
/* file rls.x: definizione del programma RPC */
const MAXNAMELEN = 255;
typedef string nametype <MAXNAMELEN>; /* argomento della chiamata */
typedef struct namenode *namelist;
struct namenode { nametype name; namelist next; };
union readdir_res switch (int errno){ /* risultato del servizio RLS */
case 0:
namelist list; union: due alternative scelte dallo switch sul valore intero
in ingresso.
default:
void;
};
program RLSPROG {
version RLSVERS {
readdir_res READDIR (nametype)=1;
} = 1;
} = 0x20000013;

Implementazione RPC 57

34:58

FILE .x OSSERVAZIONI
Prima parte del file definizioni XDR
delle costanti:
dei tipi di dati dei parametri di ingresso e uscita per cui per tutti i tipi di dato per i quali
non esiste una corrispondente funzione built-in

Seconda parte del file definizioni XDR delle procedure


La procedura READDIR la procedura numero 1 della versione 1 del programma
numero 0x20000013 (espresso come numero esadecimale)
Si noti che per le specifiche del protocollo RPC:
il numero di procedura zero (0) riservato dal protocollo RPC per la NULLPROC
ogni definizione di procedura ha un solo parametro d'ingresso e d'uscita
gli identificatori di programma, versione e procedura usano tutte lettere maiuscole e
uno spazio di nomi che il seguente:
<NOMEPROGRAMMA>PROG per il nome del programma
<NOMEPROGRAMMA>VERS per la versione del programma
<NOMEPROCEDURA> per i nomi delle procedure
Implementazione RPC 58

35:24

File prodotti da RPCGEN: rls.h


Nel seguito vediamo pi nel dettaglio il contenuto dei file prodotti automaticamente da
RPCGEN
/* rls.h */
#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAXNAMELEN 255
typedef char *nametype;
typedef struct namenode *namelist;
struct namenode { nametype name; namelist next; };
typedef struct namenode namenode;
struct readdir_res {int remoteErrno; union{namelist list;} readdir_res_u;};
typedef struct readdir_res readdir_res;
#define RLSPROG 0x20000013
#define RLSVERS 1
#if defined(__STDC__) || defined(__cplusplus)
#define READDIR 1
Implementazione RPC 59

36:32

File prodotti da RPCGEN: rls.h


extern readdir_res * readdir_1(nametype *, CLIENT *);
extern readdir_res * readdir_1_svc(nametype *, struct svc_req *);
extern int rlsprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#else /* K&R C */
#define READDIR 1
extern readdir_res * readdir_1();
extern readdir_res * readdir_1_svc();
extern int rlsprog_1_freeresult ();
#endif /* K&R C */

Il file viene incluso dai due stub


generati client e server
In caso di nuovi tipi di dati si
devono definire le nuove
strutture dati per le quali
saranno
generate
in
automatico le nuove funzioni
di trasformazione

/* the xdr functions */


#if defined(__STDC__) || defined(__cplusplus)
extern bool_t xdr_nametype (XDR *, nametype*);
extern bool_t xdr_namelist (XDR *, namelist*);
extern bool_t xdr_namenode (XDR *, namenode*);
extern bool_t xdr_readdir_res (XDR *, readdir_res*);
#else /* K&R C */
extern bool_t xdr_nametype ();
extern bool_t xdr_namelist ();
extern bool_t xdr_namenode ();
extern bool_t xdr_readdir_res ();
#endif /* K&R C */
#ifdef __cplusplus
}
#endif

Implementazione RPC 60

37:35

File prodotti da RPCGEN: rls_xdr.c


/* rls_xdr.c: routine di conversione XDR */
#include "rls.h"
bool_t xdr_nametype (XDR *xdrs, nametype *objp)
{ register int32_t *buf;
if (!xdr_string (xdrs, objp, MAXNAMELEN)) return FALSE;
return TRUE; }
bool_t xdr_namelist (XDR *xdrs, namelist *objp)
{ register int32_t *buf;
if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct namenode),
(xdrproc_t) xdr_namenode)) return FALSE;
return TRUE; }
bool_t xdr_namenode (XDR *xdrs, namenode *objp)
{ register int32_t *buf;
if (!xdr_nametype (xdrs, &objp->name)) return FALSE;
if (!xdr_namelist (xdrs, &objp->next))
return FALSE;
return TRUE; }
bool_t xdr_readdir_res (XDR *xdrs, readdir_res *objp)
{ register int32_t *buf;
if (!xdr_int (xdrs, &objp->remoteErrno)) return FALSE;
switch (objp->remoteErrno) {
case 0:
if (!xdr_namelist (xdrs, &objp->readdir_res_u.list)) return FALSE; break;
default:
Implementazione RPC 61
break; }
return TRUE; }

38:27

File prodotti da RPCGEN: stub client


/* rls_clnt.c: stub del cliente */
#include <memory.h> /* for memset */
#include "rls.h"
/* Assegnamento time-out per la chiamata */
static struct timeval TIMEOUT = { 25, 0 };
readdir_res * readdir_1(nametype *argp, CLIENT *clnt)
{
static readdir_res clnt_res;
memset((char *)&clnt_res, 0, sizeof(clnt_res));
if (clnt_call(clnt, READDIR, (xdrproc_t) xdr_nametype, (caddr_t) argp,
(xdrproc_t) xdr_readdir_res, (caddr_t) &clnt_res,
TIMEOUT) != RPC_SUCCESS) { return (NULL); }
return (&clnt_res);
}

NOTA: reale chiamata remota nello stub

Implementazione RPC 62

40:14

File prodotti da RPCGEN: stub server


/* rls_svc.c: stub del server */
#include "rls.h"
#include <stdio.h>
...
static void rlsprog_1 ();

/*funzione di dispatching */

int main (int argc, char **argv)


{

register SVCXPRT *transp;


/* de-registrazione di eventuale programma con stesso nome */
pmap_unset (RLSPROG, RLSVERS);
/* creazione gestore trasp. e registrazione servizio con UDP */
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL)
{ fprintf(stderr, "%s", "cannot create udp service."); exit(1); }
if (!svc_register(transp, RLSPROG, RLSVERS, rlsprog_1, IPPROTO_UDP))
{fprintf (stderr, "%s", "unable to register..., udp)."); exit(1); }
/* creazione gestore trasp. e registrazione servizio con TCP */
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL){ fprintf(stderr, "%s", ..."); exit(1); }
if (!svc_register(transp, RLSPROG, RLSVERS, rlsprog_1, IPPROTO_TCP))
{ fprintf (stderr, "%s", "unable to register ..., tcp)."); exit(1); }
svc_run();
/* attivazione dispatcher */
Implementazione RPC 63
fprintf (stderr, "%s", "svc_run returned"); exit (1);

42:42

File prodotti da RPCGEN: stub server


/* rls_svc.c (stub del server): procedura di dispatching */
static void rlsprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union { nametype readdir_1_arg; } argument;
char *result; xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
/* sono diventati generici: local, procedura da invocare, argument e result i
parametri di ingresso e uscita, le funzioni xdr xdr_argument e xdr_result */
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return;
case READDIR:
_xdr_argument = (xdrproc_t) xdr_nametype;
_xdr_result = (xdrproc_t) xdr_readdir_res;
local = (char *(*)(char *, struct svc_req *)) readdir_1_svc; break;
default:
svcerr_noproc (transp); return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, (xdrproc_t) _xdr_argument,
(caddr_t) &argument)) { svcerr_decode (transp); return; }
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result))
{svcerr_systemerr (transp);}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument))
{... exit (1); } return;
Implementazione RPC 64
}

->66

Aspetti implementativi: passaggio


parametri e invocazioni funzioni
Indirettezza della chiamata al servizio locale: si vogliono generare stub dedicati
a pi servizi con diversi tipi di argomenti e risultati
Argomento union
Uso della stessa area di memoria per tutti i possibili tipi di dati (argomenti dei servizi)

La variabile argument dal messaggio di protocollo RPC avviene per indirizzo


Se la variabile argument fosse passata per valore alla procedura locale, la
procedura locale dovrebbe mantenere una union
Variabile result puntatore a carattere
stub rls_clnt.c offre al client la procedura readdir_1()
stub rls_svc.c contiene la registrazione dei servizi in RPC, sia come servizi TCP
che come servizi UDP e la procedura di dispatching rlsprog_1() che chiama il
servizio (procedura) vero e proprio readdir_1_svc()
Implementazione RPC 65

52:10

File sviluppati dal programmatore: client


/* file client.c: il client*/
#include <stdio.h>
#include <rpc/rpc.h>
#include "rls.h"

main(argc,argv)
int argc; char *argv[];
{
CLIENT *cl; namelist nl;
char *server; char *dir; readdir_res *result;
if (argc!=3) {fprintf(stderr,"uso: %s <host> <dir>\n",argv[0]);
exit(1);
}
server = argv[1]; dir = argv[2];
cl = clnt_create(server, RLSPROG, RLSVERS, "tcp");
if (cl==NULL) { clnt_pcreateerror(server); exit(1); }
result= readdir_1(&dir,cl);
if (result==NULL) { clnt_perror(cl,server);exit(1); }
if (result->remoteErrno!=0) {
perror (dir); exit(1);}
/* stampa risultati */
for (nl=result->readdir_res_u.list; nl != NULL; nl = nl->next )
printf("%s\n",nl->name);
Implementazione RPC 66
}

OSSERVAZIONI
Creazione del gestore di trasporto per il client
CLIENT * clnt_create (host, prog, vers, protocol)
char *host; u_long prog,vers; char *protocol;
host
prog
vers
protocol

nome del nodo remoto: server


programma remoto: RLSPROG
versione: RLSVERS
protocollo: "tcp"

E la chiamata di livello basso per la creazione del gestore di trasporto


Simile a clntudp/tcp_create(), ma lascia la definizione di alcuni parametri (es. tempo di wait) al
supporto RPC

Invocazione della procedura


Il nome della procedura cambia: si aggiunge il carattere underscore seguito dal numero di
versione (in caratteri minuscoli)
Gli argomenti della procedura server sono due:

uno quello vero e proprio


Implementazione RPC 67

l'altro il gestore client

01:00:40

File sviluppati dal programmatore: server


/* file rls_svc_proc.c: il programma server */
#include <rpc/rpc.h>
#include <sys/dir.h>

extern int errno;


readdir_res * readdir_1_svc (dirname, rd)
nametype * dirname; struct svc_req * rd;
{ DIR *dirp; struct direct *d; namelist nl;
namelist *nlp;
static readdir_res res;
/* si libera la memoria allocata dalla chiamata precedente */
xdr_free((xdrproc_t) xdr_readdir_res
xdr_free
xdr_readdir_res, (caddr_t) &res
&res);
dirp = opendir(*dirname); /* apertura di una directory */
if( dirp==NULL ) { res.remoteErrno=errno; return &res; }
nlp = &res.readdir_res_u.list;
while (d= readdir (dirp)) /* creazione di una struttura recursiva */
{
nl= *nlp = (namenode*) malloc(sizeof(namenode));
nl->name = malloc(strlen(d->d_name)+1);
strcpy(nl->name,d->d_name); nlp = &nl->next;
}
*nlp=NULL; /* chiusura della lista con un puntatore a NULL */
res.remoteErrno=0; closedir(dirp);
/* chiusura directory */
return &res;
}

A cosa serve rd?


Si riprenda la definizione della struttura svc_req vista sopra

Implementazione RPC 68

01:01:37

Variabili static
Quali effetti produce la keyword static e perch
necessario dichiarare il risultato come variabile static?
Visibilit
sono visibili dove sono state definite: funzioni o moduli (file)
ma non sono visibili allesterno

low memory

Tempo di vita

CODE SEGMENT

allocazione globale
tempo di vita pari al programma

DATA SEGMENT

Una variabile statica interna ad una funzione permane oltre la


singola invocazione della procedura
Ogni invocazione della stessa procedura utilizza il valore
precedente della variabile

res

HEAP

Politica di allocazione attraverso dati statici

Il valore di ritorno deve essere static in modo da essere


disponibile e poter operare marshalling e spedizione del
risultato al client quando la procedura termina

STACK
high memory

Altrimenti res terminata la procedura verrebbe rimosso


dallo stack
E quando allochiamo noi la struttura dati (malloc)?

Implementazione RPC 69

Ancora dettagli su XDR


XDR non un linguaggio di programmazione ma un linguaggio di
descrizione delle procedure ed i dati
- Non viene supportato da un vero compilatore
- Non preciso nella traduzione
- Potrebbe obbligare alla ridefinizione delle strutture in passi per
ottenere la espansione
- In ogni caso, se non ha successo, potrebbe non espandere
niente e lasciare il compito al compilatore vero
- Bisogna sempre controllare lespanso

Implementazione RPC 70

01:03:45

Generalit XDR
Dichiarazioni di tipi atomici del linguaggio C con aggiunte
bool con due valori: TRUE e FALSE tradotto nel tipo bool_t con

string con due utilizzi


con specifica del numero massimo di caratteri <fra angle-brackets>
lunghezza arbitraria con <angle-brackets vuoti>

Ad esempio:

typedef string nome <30>; tradotto in


char *nome;
typedef string nome <>;
tradotto in
char *nome;
Diverse funzioni XDR generate dal compilatore per gestire la conversione
(xdr_string())
Provare!!
Oppure string utilizzato direttamente come tipo di in/output in questo caso
viene generato un file xdr?
opaque una sequenza di bytes senza un tipo di appartenenza (con o senza la
massima lunghezza)
typedef opaque buffer <512>;
tradotto da RPCGEN in
struct { u_int buffer_len; char *buffer_val; } buffer;
typedef opaque file <>;
tradotto da RPCGEN in
struct { u_int file_len; char *file_val; } file;
Differenza nelle funzioni XDR generate (xdr_bytes())
Implementazione RPC 71
void : non si associa il nome della variabile di seguito

Dichiarazioni di tipi semplici


Analoga alla dichiarazione in linguaggio C
simple-declaration: type-ident variable-ident
Identificatore type-ident

o un tipo atomico o un tipo in linguaggio RPC

ATTENZIONE!! RPCGEN NON esegue un controllo di tipo


Se il tipo indicato non appartiene a uno dei due insiemi, il compilatore RPCGEN assume che
sia definito a parte le funzioni di conversione XDR sono assunte esterne
Ad esempio: typedef colortype color;

// tradotto da RPCGEN in colortype color;

Dichiarazione vettori a lunghezza fissa


fixed-array-declaration: type-ident variable-ident "[" value "]"
Ad esempio:
typedef colortype palette[8]; // tradotto da RPCGEN in colortype palette[8];
Implementazione RPC 72

01:06:20

Dichiarazione di matrici
In XDR non possibile definire direttamente strutture innestate, ma
bisogna sempre passare per definizioni di strutture intermedie
Ad esempio, la definizione della seguente struttura dati (matrice) non viene
interpretata correttamente da rpcgen che ritorna errori e non riesce a terminare:
struct MatriceCaratteri{ char matrice [10][20]; };
Mentre passando da una struttura dati intermedia, si come quella qui sotto,
rpcgen termina correttamente:
struct RigaMatrice{ char riga [20]; };
struct MatriceCaratteri{ RigaMatrice riga [10]; };
Si facciano alcune prove scrivendo i file .x e generando i file per le trasformazioni
dati e i file .h con rpcgen ...
Implementazione RPC 73

->

Dichiarazione vettori a lunghezza variabile


variable-array-declaration:
type-ident variable-ident "<" value ">"
type-ident variable-ident "<" ">"

Si pu
specificare la lunghezza massima del vettore, oppure
lasciare la lunghezza arbitraria
Ad esempio:
typedef int heights <12>;
tradotto da RPCGEN in: struct { u_int heights_len; int *heights_val; } heights;
typedef int widths <>;
tradotto da RPCGEN in: struct { u_int widths_len; int *widths_val; } widths;

Stessa struttura con due campi con suffisso _len e _val


il primo contiene il numero di posizioni occupate
il secondo un puntatore ad un vettore con i dati

Cambia la funzione xdr di conversione

Implementazione RPC 74

Dichiarazione di tipi puntatori


pointer-declaration: type-ident "*" variable-ident

Supporto offerto al trasferimento di strutture ricorsive


listitem *next;

tradotto da RPCGEN in:

listitem *next;

RPCGEN fornisce il supporto per il trasferimento


stessa dichiarazione di variabile di tipo puntatore
funzione XDR dedicata a ricostruire il riferimento indicato dal puntatore una volta
trasferito il dato sull'altro nodo

Definizione di tipi struttura


Struttura XDR

struct-definition:
"struct" struct-ident "{"
declaration-list
"}"

struct coordinate {
int x;

Struttura C
struct coordinate {
int x;

int y;

int y;
};

};

declaration-list:
declaration ";"
declaration ";" declaration-list

typedef struct coordinate coordinate;

Implementazione RPC 75

Dichiarazione di tipi unione


union-definition:
"union union-ident "switch"
"(" simple-declaration ")"
"{"
case-list "}"

Unione XDR
union read_result switch (int errno)
{
case 0: opaque data[1024];
default: void;
};

Unione C
struct read_result {
int errno;
union { char data[1024];
};

} read_result_u;

typedef struct read_result read_result;

case-list:
"case" value ":" declaration ";"
"default" ":" declaration ";"
"case" value ":" declaration ";"
case-list

Definizione di tipi enumerazione


enum-definition:
"enum" enum-ident "{"
enum-value-list "}"

Enumerazione XDR
enum colortype {
RED = 0,
GREEN = 1,
BLUE = 2
};

enum-value-list:
enum-value
enum-value "," enum-value-list

Enumerazione C
enum colortype {
RED = 0,
GREEN = 1,
BLUE = 2
};
typedef enum colortype colortype;

enum-value: enum-value-ident enum-value-ident "=" value

Implementazione RPC 76

Dichiarazione di tipi costante


Costanti simboliche

Costante XDR

Costante macro-processore C

const MAXLEN = 12;

#define MAXLEN 12

const-definition:
"const" const-ident "=" integer
Ad esempio, nella specifica di dimensione di un vettore

Definizione di tipi non standard

typedef-definition:
"typedef" declaration

Definizione XDR di tipo

Definizione C di tipo

typedef string fname_type <255>;

typedef char *fname_type;

Implementazione RPC 77

Definizione di Programmi RPC


Specifiche protocollo RPC

Definizione di programma RPC

identificatore
unico
del
servizio offerto
modalit
d'accesso
alla
procedura
mediante
i
parametri di chiamata e di
risposta

program TIMEPROG {

Definizione di protocollo RPC in C


#define TIMEPROG ((u_long) 44)

version TIMEVERS {
usigned int TIMEGET(void) = 1;

#define TIMEVERS ((u_long) 1)


#define TIMEGET ((u_long) 1)

void TIMESET(unsigned int) = 2;


} = 1;

#define TIMESET ((u_long) 2)

} = 44;

program-definition:
"program" program-ident "{"

version-list

"}" "=" value

version-list: version "; version ";" version-list


version: "version" version-ident "{" procedure-list "}" "=" value
procedure-list: procedure ";" procedure ";" procedure-list
procedure: type-ident procedure-ident "(" type-ident ")" "=" value
Il compilatore genera i due stub e i programmi addizionali

Implementazione RPC 78

01:09:40

Ancora RPC: modalit asincrona


A default RPC client sincrono con il server
Possiamo intervenire sul cliente
il cliente usa TCP
se il cliente specifica un time-out nullo pu continuare immediatamente
la esecuzione
il servitore non predeve risposta

Specifica di un time-out nullo


nella clnt_call(clnt,procnum,inproc,in,outproc,out,tout)
per ogni chiamata
nella clnt_control(clnt,CLSET_TIMEOUT, timeout)
CLIENT *clnt;
opzione di time out;
Implementazione RPC
struct timeval timeout;

79

Modalit asincrona (ancora)


timeout.tv_sec = timeout.tv_nsec = 0;
nessun tempo di attesa della risposta
Il servitore non deve inviare alcuna risposta
Nella procedura di risposta si deve dichiarare
xdr-void come funzione XDR e 0 come argomento

IMPORTANZA dell'uso di trasporto affidabile


per evitare di perdere messaggi
Implementazione RPC 80

01:13:50

Modalit asincrona batch


Tutte le richieste di servizio del client vengono poste nel buffer
TCP e gestite dalla driver di trasporto senza bloccare il processo
che le genera
Modalit batch
ogni chiamata non richiede risposta e
ogni servizio non invia risultati
le richieste sono trasportate con un protocollo affidabile
(come TCP)

Implementativamente:
impiego del protocollo TCP
valore nullo del timeout nella primitiva clnt_call()
i due parametri del cliente:
risultato NULL e funzione XDR xdr_void in clnt_call()
manca la chiamata svc_sendreply() al termine del servizio
Implementazione RPC 81
asincrono

Esempio
Una serie di chiamate asincrone per la stampa di stringhe
(procedura PRINTSTRING_BATCHED) sul nodo remoto: si termina
con una chiamata sincrona alla procedura nulla (NULLPROC)
che blocca il client fino alla ricezione dellavvenuta esecuzione della
richiesta di NULLPROC accodata dopo le richieste di
PRINTSTRING_BATCHED.

Client
Invio PRINTSTRING_BATCHED (string1)
Invio PRINTSTRING_BATCHED (string2)

string1
string2

stringN

Invio PRINTSTRING_BATCHED (stringN)


Invio NULLPROC
Buffer TCP:

null stringN string2 string1

Implementazione RPC 82

Client 1/3
#define PROG (unsigned long) 0x20000020
#define VERS (unsigned long) 1
#define PRINTSTRING_BATCHED (unsigned long) 2
#include <stdio.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <time.h>
#include <netdb.h>

main(argc,argv)
int argc; char *argv[];
{ struct hostent *hp;
struct timeval total_timeout;
struct sockaddr_in server_addr;
int sock = RPC_ANYSOCK;
register CLIENT *client;
enum clnt_stat clnt_stat;
char buf[BUFSIZ], *s=buf;
if (argc<2)
{fprintf(stderr,"uso: %s hostname\n",argv[0]);
exit(1);}

Implementazione RPC 83

Client 2/3
if ((hp=gethostbyname(argv[1]))==NULL)
{fprintf(stderr,"non ho informazioni su %s\n", argv[1]);exit(1);}
memcpy((caddr_t)&server_addr.sin_addr, hp->h_addr, hp->h_length);
server_addr.sin_family=AF_INET; server_addr.sin_port=0;
/* gestore TCP */
if((client=clnttcp_create(&server_addr, PROG,VERS, &sock,0,0))==NULL)
{clnt_pcreateerror ("clnttcp_create\n"); exit(1);}
/* il timeout sulla risposta RPC posto a zero */

total_timeout.tv_sec=0;

total_timeout.tv_usec=0;

/* ciclo di lettura di stringhe da tastiera e spedizioni asincrone al


nodo remoto, fino a EOF */
while (scanf("%s",s)!=EOF)
{ clnt_stat = clnt_call(client, PRINTSTRING_BATCHED,
xdr_wrapstring,&s,xdr_void, NULL, total_timeout);
/* risultato e funzione XDR a NULL */
if (clnt_stat != RPC_SUCCESS)
{clnt_perror(client,"RPC asincrona"); exit(1);}
}
Implementazione RPC 84

Client 3/3
3/3
/* Ultima chiamata RPC sincrona per svuotare completamente
il buffer TCP */
total_timeout.tv_sec=20;
/* NB: timeout non nullo!! */
/* Chiamata sincrona di NULLPROC */
clnt_stat = clnt_call(client,NULLPROC, xdr_void, NULL,

xdr_void, NULL, total_timeout);


if (clnt_stat != RPC_SUCCESS)
{ clnt_perror(client,"rpc"); exit(1); }
/* libero le risorse usate */
clnt_destroy(client);
}

Implementazione RPC 85

Server 1/3
#define PROG (unsigned long) 0x20000020
#define VERS (unsigned long) 1
#define PRINTSTRING (unsigned long) 1
#define PRINTSTRING_BATCHED (unsigned long) 2
#include <stdio.h>
#include <rpc/rpc.h>

void printdispatch();
main()
{ SVCXPRT *transp;
transp= svctcp_create(RPC_ANYSOCK,0,0);
/* il gestore TCP */
if (transp==NULL)
{fprintf(stderr,"cannot create an RPC server\n"); exit(1);}
pmap_unset(PROG,VERS);
if (!svc_register(transp, PROG, VERS, printdispatch, IPPROTO_TCP))
{fprintf(stderr,"cannot register PRINT service\n"); exit(1); }
svc_run();
fprintf(stderr,"uscita dal ciclo di attesa di richieste!\n");
Implementazione RPC 86
}

Server 2/3
void printdispatch (rqstp, transp)
struct svc_req *rqstp; SVCXPRT *transp;
{ char *s=NULL;
switch (rqstp->rq_proc) {
case NULLPROC:
if (!svc_sendreply(transp, xdr_void,0))
{ fprintf(stderr,"non posso rispondere.\n"); exit(1);
}
fprintf(stderr,"Fine!\n");
return;
case PRINTSTRING_BATCHED:
if (!svc_getargs(transp, xdr_wrapstring, &s))
{fprintf(stderr, "problemi decodificare argomenti.\n"); break; }
fprintf(stderr,"%s\n",s);
/* questo un servizio asincrono: non c' svc_sendreply() */
break;
default:
svcerr_noproc(transp); return;
}

Implementazione RPC 87

Server 3/3
3/3
svc_freeargs(transp,xdr_wrapstring,&s);
/* funzione di basso livello per deallocare
acquisiti con la chiamata svc_getargs() */
}

gli

argomenti

L'esecuzione dei due programmi permette all'utente di digitare


su di un terminale stringhe senza dover attendere
conferme dal server (interazione asincrona).
Lo svuotamento della buffer TCP avviene sicuramente
allinvocazione della NULLPROC (sincrona).

Implementazione RPC 88

Bibliografia
J. Bloomer, Power Programming with RPC, Ed. OReilly (1992)

Manuale in linea di Linux: man rpc

Implementazione RPC 89

Universit degli Studi di Bologna


Facolt di Ingegneria

Corso di
Reti di Calcolatori T
Sistemi RPC e sistemi di Nomi
Antonio Corradi
Anno accademico 2012/2013
RPC e Sistemi di nomi 1

inizio registrazione 21.12.12

REMOTE PROCEDURE CALL - RPC


REMOTE PROCEDURE CALL (RPC) come estensione del
normale meccanismo di chiamata a procedura locale,
come cliente/servitore nel distribuito
Approccio applicativo di alto livello (livello 7 di OSI)
il cliente invia la richiesta ed attende fino alla risposta fornita dal
servitore stesso

Differenze rispetto alla chiamata a procedura locale


- sono coinvolti processi distinti su nodi diversi
- i processi cliente e servitore hanno vita separata
- i processi non condividono lo spazio di indirizzamento
- sono possibili malfunzionamenti sui nodi o nella
infrastruttura di comunicazione
RPC e Sistemi di nomi 2

1:37

RPC: PROPRIET
PROPRIET
Remote Procedure Call
consente il controllo dinamico del tipo dei parametri e del risultato
include il trattamento dei parametri di ingresso / uscita dal cliente al
servitore (e viceversa) detto marshalling o almeno serializzazione
(livello di presentazione: marshalling)

PROPRIET - uniformit totale impossibile (visibilit guasti)


trasparenza approccio locale e remoto
type checking e parametrizzazione
lo stesso controllo di tipo e dei parametri
controllo concorrenza e eccezioni
binding distribuito
possibile trattamento degli orfani
orfano il processo server che non riesce a fornire risultato
RPC e Sistemi di nomi 3

e anche il cliente senza risposta

3:20

RPC STORIA
Prima sistemazione dovuta a Birrel e Nelson (1984)
partendo da quanto usato in Xerox, Spice, Sun, HP, etc.

Molte implementazioni
Default: cliente sincrono
bloccante

Nodo A
Cliente
call
wait

Nodo B
call
risultato

Server
ricezione
ritorno

Progetto Athena MIT, ITC CMU, ...


RPC usando scambi di messaggi coordinati

CLIENTE
SERVITORE
send
get-request <operazione>
wait
send-reply
si devono anche prevedere trasformazioni di dati, nomi, controllo, ...
RPC e Sistemi di nomi 4

4:03

RPC PRIMITIVE
Ogni sistema usa primitive diverse Nodo A
senza troppe regole standard
Cliente
call
servizio
(param...)

Nodo B
parametri
risultato

Server
getrequest
sendreply

dalla parte del cliente


call servizio (servitore, argomenti, risultato)
dalla parte del servitore
Due primitive di accettazione e di risposta
con due possibilit di concorrenza sul server:
- il servizio svolto da un unico processo sequenziale (esplicito)
- il servizio un processo indipendente, generato per ogni
richiesta automaticamente (approccio implicito)
RPC e Sistemi di nomi 5

5:36

RPC TOLLERANZA AI GUASTI


Obiettivo applicativo mascherare i malfunzionamenti
- perdita di messaggio di richiesta o di risposta
- crash del nodo del cliente
- crash del nodo del servitore
Ad esempio, in caso di crash del servitore prima di avere fornito la risposta
o in caso di sua non presenza, o in caso di perdita di messaggio in andata
o ritorno,

il cliente pu tentare politiche diverse e diversi comportamenti:


aspettare per sempre
time-out e ritrasmettere (uso identificatori unici)
time-out e riportare una eccezione al cliente

Spesso si assume che le operazioni siano idempotenti ossia


che si possano eseguire un numero qualunque di volte con lo stesso
esito per il sistema cliente/servitore (?)

RPC e Sistemi di nomi 6

6:05

FAULT TOLERANCE e SEMANTICA


Le RPC hanno alcune semantica tipiche e strategie relative
may-be
at-least-once
at-most-once
exactly-once

time-out per il cliente


time-out e ritrasmissioni
tabelle delle azioni effettuate
l'azione viene fatta fino alla fine

mai in RPC

Invece, in caso di crash del cliente, si devono trattare orfani sul nodo
servitore, ossia i processi in attesa di consegnare risultato
Politiche tipiche
- sterminio: ogni orfano risultato di un crash viene distrutto
- terminazione a tempo: ogni calcolo ha una scadenza, oltre la quale
automaticamente abortito
- reincarnazione (ad epoche): tempo diviso in epoche; tutto ci che
relativo alla epoca precedente obsoleto e distrutto RPC e Sistemi di nomi 7

8:44

Open Network Computing ONC


Sun propone una chiamata RPC
(diversa dalla locale)
primitiva callrpc() con parametri aggiuntivi oltre a quelli logici
nome del nodo remoto
identificatore della procedura da eseguire
specifiche di trasformazione degli argomenti (si introduce un formato
standard eXternal Data Representation XDR)

Schema del modello ONC


NON TRASPARENZA
adottato da

HP-UX, Sun
Sistemi UNIX compatibili,
Novell Netware

Clie nt

Se rve r

Progr amma client

Processo ser ver


esecuzione richiesta

chiamata

callrpc()
ser vizio
r itor no
r isposta
r ichiesta completata

RPC e Sistemi di nomi 8

9:24

Network Computing Architecture NCA


Si introducono ai due endpoint di comunicazione, il client e il server
delle routine stub per ottenere la trasparenza
Le chiamate diventano del tutto locali all endpoint e stub
Schema del modello NCA
Cli e n t
Se rv e r
Comunicazione di rete

P r ogr a m m a clien t
P r ocedu r a ser ver
Gli stub sono forniti
In t er fa ccia
In t er fa ccia
dall'implementazione e
St u b del clien t
St u b del ser ver
generati automaticamente
Le parti logiche di programma
RP C r u n -t im e
RP C r u n -t im e
sono "del tutto" inalterate
ci si dirige verso lo stub
che nasconde le operazioni COSTO: due chiamate per RPC
Mercury ottimizza i messaggi con stream di chiamate

RPC e Sistemi di nomi 9

10:17

MODELLO con TRASPARENZA


Nelson descrive il modello implementativo NCA trasparente con uso
di stub ossia interfacce locali per la trasparenza
che trasformano la richiesta da locale a remota
Client

Server

Programma client

Procedura server

Interfaccia

Interfaccia

Stub del client

Stub del server


Comunicazione di rete

RPC run-time

RPC run-time

Modello asimmetrico a molti clienti/ un solo servitore


RPC e Sistemi di nomi 10

10:42
salto a slide 17
e ritorno

MODELLO con STUB


Modello cliente / servitore asimmetrico applicativo
- Il cliente invoca uno stub, che si incarica di tutto: dal recupero del
server, al trattamento dei parametri e dalla richiesta al supporto run-time,
al trasporto della richiesta
- Il servitore riceve la richiesta dallo stub relativo, che si incarica del
trattamento dei parametri dopo avere ricevuto la richiesta pervenuta dal
trasporto. Al completamento del servizio, lo stub rimanda il risultato al
cliente

Lo sviluppo prevede
la massima trasparenza
STUB prodotti in modo automatico
Lutente finale progetta e
si occupa solo delle reali parti
applicative e logiche

Client

Server

Programma client

Procedura server

Interfaccia

Interfaccia

Stub del client

Stub del server


Comunicazione di rete

RPC run-time

RPC run-time

RPC e Sistemi di nomi 11

11:40

ESEMPIO di funzioni nello STUB


Negli stub si concentra tutto il supporto nascosto allutente finale
operazione(parametri)
stub cliente:
< ricerca del servitore>
<marshalling argomenti>
<send richiesta>
<receive risposta>
<unmarshalling risultato>
restituisci risultato
fine stub cliente;

stub servitore:
< attesa della richiesta>
<unmarshalling argomenti>
invoca operazione locale
ottieni risultato
<marshalling del risultato>
<send risultato>
fine stub servitore;
operazione(parametri)

In questo schema mancano le ritrasmissioni possibili da parte del


cliente e il controllo della operazione da parte del servitore
(concorrenza o meno)

RPC e Sistemi di nomi 12

Ancora schema di STUB


Gli stub si occupano di tutta la parte distribuita
Cliente
valori
Argomenti

Server

Risultato

Server
stub

Cliente
stub
MSG
richiesta

valore
Risultato

Argomenti

MSG
richiesta

MSG
risposta

protocollo
RPC

MSG
risposta

protocollo
RPC

TCP/IP
RPC e Sistemi di nomi 13

13:39

PASSAGGIO di PARAMETRI
I parametri devono passare tra ambienti diversi
passaggio per valore o per riferimento
Trattamento default dei parametri per valore
impaccamento dei parametri (marshalling) e disimpaccamento
(unmarshalling) con dipendenza dal linguaggio utilizzato
Per tipi primitivi o una entit con valori privati
marshalling / unmarshalling per la presentazione
Per tipi utente costruiti e dinamici, ad esempio, una lista o un albero
e la memoria dinamica (?) la logica guida la trasformazione
si deve (?) copiarla o (?) muoverla e ricostituirla sul server per poi
riportarla sul nodo iniziale

In genere si favorisce il passaggio per valore


RPC e Sistemi di nomi 14

PASSAGGIO di PARAMETRI
Passaggio parametri dal cliente al servitore
nel caso di passaggio per valore
passaggio con trasferimento e visita (valore perso sul server)
nel caso di passaggio per riferimento
passaggio senza trasferimento ma rendendo loggetto remoto
uso di oggetti che rimangono nel nodo di partenza e devono essere
identificati in modo unico nell'intero sistema
Se si vuole riferire un entit del cliente, si passa il riferimento alla
stessa entit che i nodi remoti possono riferire attraverso RPC
Per esempio, un oggetto che sia gi in uso sul nodo del cliente deve
potere essere riferito dal nodo servitore e cambiato in stato senza
interferire con luso locale delloggetto
RPC e Sistemi di nomi 15

15:35

TRATTAMENTO delle ECCEZIONI


Le RPC hanno previsto integrazione con exception handling
trattando gli eventi anomali dipendenti dalla distribuzione o ai guasti
integrandola con la gestione locale e inserendola nella gestione locale
delle eccezioni
In genere, si specifica la azione per il trattamento anomalo in un
opportuno gestore della eccezione
Si pu anche inserire l'eccezione nello scope di linguaggio
CLU (Liskov)
a livello di invocazione della RPC
MESA (Cedar)
a livello di messaggio
Java
definizione delle exception
una RPC pu produrre il servizio con successo o produrre insuccesso e
determinare una eccezione locale con semantica tipica
may-be
con time-out per il cliente
at-least-once
SUN RPC
at-most-once
con l'aiuto del trasporto
RPC e Sistemi di nomi 16

16:33

INTERFACE DEFINITION LANGUAGE


Interface Definition Language IDL
linguaggi per la descrizione delle operazioni remote, la
specifica del servizio (detta firma) e la generazione degli stub
Un IDL deve consentire la identificazione non ambigua
identificazione (unica) del servizio tra quelli possibili
uso di nome astratto del servizio spesso prevedendo versioni diverse del
servizio

definizione astratta dei dati da trasmettere in input ed output


uso di un linguaggio astratto di definizione dei dati (uso di interfacce, con
operazioni e parametri)

possibili estensioni: linguaggio dichiarativo con ereditariet, ambienti


derivati con binder ed altre entit
Dalla definizione del linguaggio IDL fornita dallutente si possono
generare gli stub
RPC e Sistemi di nomi 17

17:50

TIPICI LINGUAGGI IDL


Sono stati definiti molti linguaggi IDL
che hanno permesso di studiare le implicazioni e le politiche a livello
di sistema di supporto
Sono nati molti IDL e relativi strumenti correlati per lo sviluppo automatico
di parte dei programmi direttamente dalla specifica astratta, esempi sono

SUN
XDR
primo esempio di standard interno
OSF
DCE IDL
ANSA
ANSAware
HP
NCS IDL
CORBA IDL
Le differenze hanno generato dibattiti e confronti anche accesi,
spentisi visti gli scope limitati dei linguaggi stessi
RPC e Sistemi di nomi 18
Mancanza di standard

18:32

ESEMPIO di XDR
XDR eXternal Data Representation
Il formato XDR definisce le operazioni remote e tutto quello che
necessario conoscere per la generazione di stub (parametri)
Lutente deve sviluppare un file di descrizione logica dei servizi offerti da
cui si possono generare gli stub
Si prevedono pi servizi in versioni diverse e tipi primitivi e anche
definiti dallutente
file msg.x
program MESSAGEPROG {
version MESSAGEVERS {
int PRINTMESSAGE(string) = 1;
} = 1;
} = 0x20000013;
RPC e Sistemi di nomi 19

19:00

DA IDL A STUB
Gli IDL hanno lo scopo di supporto allo sviluppo dell'applicazione
permettendo di generare automaticamente gli stub dalla interfaccia
specificata dall'utente
Strumento RPCGEN (Remote Procedure Call Generator)
compilatore di protocollo RPC per generare procedure stub
RPCGEN produce gli stub per il server e il client da un insieme di
costrutti descrittivi per tipi di dati e per le procedure remote in linguaggio
RPC
Server
Client
Programma
principale
client

chiamata
locale

comunicazione
attraverso
l'interfaccia RPC

chiamate
locali

Procedura 1
stub
client
Parti fornite da RPCGEN
Parti sviluppate direttamente dal programmatore

stub
server
Main
Procedura 2

RPC e Sistemi di nomi 20

20:08

SVILUPPO e SUPPORTO RPC


Nel caso di un utente che deve utilizzare le RPC, di varia tecnologia,
abbiamo molte fasi, alcune facilitate e poco visibili, svolte tutte dal
supporto, altre sotto il controllo utente
Dopo la specifica del contratto in IDL,
FASI TIPICHE della IMPLEMENTAZIONE
compilazione di sorgenti e stub
binding delle entit
trasporto dei dati
controllo della concorrenza
supporto alla rappresentazione dei dati
Alcuni ambienti facilitano altri meno, ma tutti hanno una qualche
caratterizzazione specifica
RPC e Sistemi di nomi 21

FASI di SUPPORTO RPC


compilazione di sorgenti e stub
La compilazione produce gli stub che servono a semplificare il progetto
applicativo e risponde alla necessit che cliente e servitore raggiungano
un accordo sul servizio da richiedere / fornire

trasporto dei dati


Il trasporto connesso e senza connessione intrinseco allo strumento e
tanto pi veloce ed efficiente, tanto meglio (TCP vs. UDP)

controllo della concorrenza


Il controllo consente di usare gli stessi strumenti per funzioni diverse, con
maggiore asincronicit e maggiore complessit (ripetizione, condivisione
di connessione, processo)

supporto alla rappresentazione dei dati


per superare eterogeneit si trasformano i dati, tanto pi veloce, tanto
meglio, bilanciata con la ridondanza se ritenuta necessaria
RPC e Sistemi di nomi 22

21:30

RPC BINDING
binding delle entit
Il binding prevede come ottenere l'aggancio corretto tra i clienti e il server
capace di fornire la operazione

Il binding del cliente al servitore secondo due possibili linee


scelta pessimistica e statica
La compilazione risolve ogni problema prima della esecuzione e forza un
binding statico (nel distribuito) a costo limitato (ma poco flessibile)

scelta ottimistica e dinamica


Il binding dinamico ritarda la decisione alla necessit, ha costi maggiori,
ma consente di dirigere le richieste sul gestore pi scarico o presente in
caso di sistema dinamico

BINDING

STATICO vs. DINAMICO

fondamentale nella relazione tra cliente e servitore


RPC e Sistemi di nomi 23

24:40

BINDING DINAMICO RPC


Il binding dinamico tipico viene ottenuto distinguendo due fasi nella
relazione cliente/servitore
- servizio (fase statica) prima della esecuzione Definizione del contratto
il cliente specifica a chi vuole essere connesso, con un nome unico
identificativo del servizio (NAMING)
in questa fase si associano dei nomi unici di sistema alle operazioni o
alle interfacce astratte e si attua il binding con la interfaccia specifica di
servizio

- indirizzamento (fase dinamica) alluso, durante la esecuzione


il cliente deve essere realmente collegato al servitore che fornisce il
servizio al momento della invocazione (ADDRESSING)
in questa fase si cercano gli eventuali servitori pronti per il servizio
(usando sistemi di nomi che sono stati introdotti proprio a tale scopo)
RPC e Sistemi di nomi 24

27:35

BINDING RPC
Parte di NAMING statica, SERVIZIO
risolto con un numero associato staticamente alla interfaccia del servizio
(nomi unici)

Parte di ADDRESSING dinamica, durante lesecuzione


La parte dinamica deve avere costi limitati ed accettabili durante il servizio

1) ESPLICITA attuata dai processi


Il cliente deve raggiungere un servitore
si pu risolvere con un multicast o broadcast attendendo solo la prima
risposta e non le altre

2) IMPLICITA tramite un agente esterno, un servitore di nomi


uso di un name server che registra tutti i servitori e agisce su opportune
tabelle di binding ossia di nomi, prevedendo funzioni di ricerca di nomi,
registrazione, aggiornamento, eliminazione
SISTEMI di NOMI
RPC e Sistemi di nomi 25

FREQUENZA del BINDING


In caso di BINDING DINAMICO
Ogni chiamata richiede un collegamento dinamico
spesso dopo un primo legame si usa lo stesso binding ottenuto come
se fosse statico per questioni di costo
il binding pu avvenire meno frequentemente delle chiamate stesse
in genere, si usa lo stesso binding per molte richieste e chiamate allo
stesso server
Name Server

Programma cliente

Procedura servitore

Interfaccia

Interfaccia

Stub del client

Stub del server

RPC run-time

RPC run-time
Comunicazione di rete

RPC e Sistemi di nomi 26

30:00

SISTEMI di NOMI
Le RPC hanno portato a molti sistemi di nomi, detti Binder, Broker,
Name Server, ecc, tutte entit di sistema per il binding dinamico
Un binder deve fornire operazioni per consentire agganci flessibili
lookup
(servizio, versione, &servitore) funzione pi usata
register
(servizio, versione, servitore)
unregister (servizio, versione, servitore)
Il nome del servitore (servitore) pu essere dipendente dal nodo di
residenza o meno
se dipendente, allora ogni variazione deve essere comunicata al binder

Il BINDING attuato come servizio coordinato di pi servitori


Uso di binder multipli per limitare overhead e di cache ai singoli clienti o ai
singoli nodi
Inizialmente i clienti usano un broadcast per trovare il binder pi
conveniente
RPC e Sistemi di nomi 27

NO

CONTROLLO e ASINCRONICIT
ASINCRONICIT
Necessit di RPC asincrone, o meglio non bloccanti
il cliente non si blocca ad aspettare il servitore

Possibilit di modalit asincrone nei diversi ambienti di uso


per maggiore parallelismo ottenibile
con processi leggeri per il server
problema fondamentale come ottenere il risultato
due punti di vista di progetto
RPC bassa latenza vs. RPC alto throughput
RPC bassa latenza
tendono a mandare un messaggio di richiesta ed a trascurare il risultato
realmente asincrone

RPC throughput elevato


tendono a differire l'invio delle richieste per raggrupparle in un unico
RPC e Sistemi di nomi 28
messaggio di comunicazione

NO

RPC ASINCRONE
Implementativamente, si usano sia supporti UDP o TCP, ottenendo
semantiche diverse
Realmente asincrone (senza risultato)
Athena (XWindows)
usa UDP e bassa latenza - semantica may-be

SUN
usa TCP ad elevato throughput - semantica at-most-once
invio di una serie di RPC asincrone e di una finale in batching

asincrone (con restituzione di risultato)


Chorus - bassa latenza
uso di una variabile che contiene il valore del risultato nel cliente

Mercury - alto throughput


uso di stream per le richieste tenendo conto di azioni asincrone e
RPC e Sistemi di nomi
sincrone

29

PROPRIET
PROPRIET
delle RPC
Analisi delle propriet di ogni sistema RPC
propriet visibili all'utilizzatore
entit che si possono richiedere operazioni o metodi di oggetti
semantica di comunicazione
maybe, at most once, at least once
modi di comunicazione
a/sincroni, sincroni non bloccanti
durata massima e eccezioni
ritrasmissioni e casi di errore
propriet trasparenti all'utilizzatore
ricerca del servitore
uso di sistemi di nomi con broker unico centralizzato / broker multipli
presentazione dei dati
linguaggio IDL ad hoc e generazione stub
passaggio dei parametri
passaggio per valore, per riferimento

eventuali legami con le risorse del server


persistenza della memoria per le RPC
crescita delle operazioni via movimento di codice
aggancio con il garbage collector

RPC e Sistemi di nomi 30

RPC di SUN
RPC di SUN con visione a processi e non trasparenza allocazione
operazioni richieste al nodo del servitore

entit che si possono richiedere


semantica di comunicazione
modi di comunicazione
durata massima

solo operazioni o funzioni


at-most-once e at-least-once
sincroni e asincroni
timeout

ricerca del servitore


presentazione dei dati

port mapper sul server

linguaggio IDL ad hoc XDR e generazione stub RPCGEN


passaggio dei parametri
passaggio per valore
le strutture complesse e definite dall'utente sono linearizzate e ricostruite al
server per essere distrutte al termine della operazione
estensioni varie
broadcast, credenziali per sicurezza, ...
RPC e Sistemi di nomi 31

SI

RMI di JAVA
RMI in Java
visione per sistemi ad oggetti passivi con trasparenza alla allocazione (?),
senza eterogeneit, e con scelte che non privilegiano la efficienza

entit da richiedere
metodi di oggetti via interfacce
semantica di comunicazione at-most-once (TCP)
modi di comunicazione
solo sincroni
durata massima e eccezioni trattamento di casi di errore
ricerca del servitore uso di registry nel sistema broker unico centrale
non sono forniti broker multipli (distribuiti?) ma si possono anche
avere organizzazioni pi complesse
presentazione dei dati
generazione stub e skeleton
passaggio dei parametri
passaggio a default per valore,
passaggio per riferimento di oggetti con interfacce remotizzabili
eventuali legami con le risorse del server e aggancio con il sistema di
sicurezza, e aggancio con il garbage collector
RPC e Sistemi di nomi 32

30:50

SISTEMI di NOMI
Spesso nei sistemi distribuiti siamo in presenza di molto sistemi di
nomi che hanno molte propriet e sono anche molto diversi
Propriet di base dei Sistemi di NOMI
generalit
variet dei nomi disponibili e trattati

definizioni multiple della


stessa entit
variet di nomi per lo stesso
oggetto con mapping
capace di traslare tra questi

distribuibilit
uso di direttori partizionati
e/o replicati

Computer 1A
Computer 1B
Nome di
utente
Nome del
processo

Processo

Nome di
utente

Nome di
sistema

Nome del
processo

Indirizzo

Nome di
sistema
Porte di
processo

Porte di
comunicazione
Computer_id

Indirizzo

Network A

Porte di
comunicazione
Computer_id
Computer 1B

Route
Computer 2A

Computer 3A

Gateway 1

Computer 2B
Gateway 2

user-friendliness
nomi facili per lutente

Processo

Porte di
processo

Network B
Computer 3B

Gateway 3
Computer 1C

Computer 2C

RPC e Sistemi di nomi 33

NOMI
Problema fondamentale nel distribuito la necessit di ritrovare (cio
identificare) le altre entit nel sistema
Complessit del problema e difficolt di soluzioni generali

entit diverse eterogenee livelli diversi di nomi


pi sistemi di naming e pi livelli di nomi nel sistema

con contesti di visibilit


pi funzioni di trasformazione da nome all'entit

NOMI identificatori come


stringa di caratteri - nomi esterni
(nomi di utente)
numero binario
- nomi interni
(nomi di sistema)
Le entit di un programma sono oggetti e spesso sono associati a
diversi sistemi di nomi
sia nomi di utente (significativi per lutilizzatore )
sia nomi di sistema (meno leggibili ma pi efficienti)
RPC e Sistemi di nomi 34

37:00

LIVELLI di NOMI
Spesso si possono considerare alcuni livelli di nomi per il distribuito
NOME in tre possibili livelli (Shock)
nome
LOGICO esterno
indirizzo FISICO
route
organizzazione per la raggiungibilit
nome specifica quale oggetto (entit) si riferisce e denota la entit
indirizzo specifica dove l'oggetto risiede e lo riferisce dopo un binding
route specifica come raggiungere l'oggetto
Funzioni di corrispondenza o MAPPING per passare da una forma
ad unaltra e per aiutare lutente finale
- mapping nomi

indirizzi
- mapping indirizzi

route
I nomi scelti dall'utente, gli indirizzi assegnati dal sistema
lutente deve specificare nomi e ritrovare route
RPC e Sistemi di nomi 35

SISTEMI di NOMI
SPAZI dei NOMI pi usati
piatto (flat)
con nessuna struttura, ma adatto per pochi utenti e poche entit

partizionato
gerarchia e contesti (DNS), ad esempio, deis33.deis.unibo.it

descrittivo
con riferimento ad una struttura di oggetto caratterizzato da attributi per
identificare la entit corrispondente (OSI X.500)
username e password
attributi con liste di valori (rigidi o meno)

In questi scenari, spesso ci possono essere problemi nellidentificare


nomi di gruppo
un nome di gruppo identifica una lista di nomi di entit
Si noti che il problema simile a quello di un multicast vs, comunicazione
punto a punto
RPC e Sistemi di nomi 36

SCELTE sui NOMI


Piatto (flat)

antonio, acorradi
Chi distribuisce i nomi? Problemi nel caso di molti servitori di nome

Partizionato

deis33.cineca.it
deis33.deis.unibo.it
Ogni responsabile di partizione mantiene e distribuisce i nomi

Descrittivo

nome=Antonio & organizzazione=UniBologna


Ogni nome pu identificare anche una molteplicit di entit che si
possono trovare solo con una ricerca esaustiva sul sistema di nomi

Nomi di gruppo

IP classe D
Ogni gruppo individua un insieme di entit denotate dal nome stesso
anche molto lontane, poco correlate, e spesso non gestite dallo stesso
servitore di nomi
Necessit di una infrastruttura di supporto al gruppo
RPC e Sistemi di nomi 37

COMPONENTI di un SISTEMA di NOMI


In un servizio di nomi, consultato implicitamente o esplicitamente,
i clienti del name server sono
sia i clienti che devono risolvere un nome per potere riferire una risorsa
sia le entit risorse (server rispetto ai clienti di prima, ossia che devono
essere riferiti) che devono rendersi note al servizio e diventano clienti del
name server
a parte questi clienti e le loro richieste, il supporto deve considerare:
Comunicazione dei clienti con il name server
Name Server (anche pi di uno)
Gestione dei nomi veri e propri (coordinamento)
Gestione tabelle e coordinamento (spesso ottimizzato localmente)

Le comunicazioni dei clienti con il name server possono essere


ottimizzate per le operazioni pi frequenti
I clienti propongono la maggiore parte del traffico
Le risorse da registrare fanno operazioni pi rare e producono traffico pi
RPC e Sistemi di nomi 38
limitato

COMPONENTI: NAME SERVER


Name server devono fornire operazioni per consentire la migliore
operativit sugli oggetti interni, ossia le tabelle di corrispondenza
modellate come tuple di attributi
Le operazioni
Query
ricerca un oggetto
AddTuple
aggiungi una tupla dal server
ModifyTuple/DeleteTuple modifica/togli una tupla
Enumerate
lista tutte le tuple, una alla volta
Ogni sistema di nomi decide:
- il formato delle tuple
- il formato specifico delle operazioni
Le realizzazioni prevedono sia Unico servitore sia Agenti Multipli
Il servizio pu essere centralizzato,
o molto pi spesso distribuito e anche replicato (vedi DNS)
RPC e Sistemi di nomi 39

COMPONENTI: COMUNICAZIONE
Nelle realizzazioni con molteplici Name Server il servizio prevede
una comunicazione tra loro, usando
- messaggi singoli, o datagrammi
- connessioni
- invocazioni di alto livello come RPC
Il traffico tra i diversi Name Server deve essere supportato mentre si
continua a fornire il servizio

Il coordinamento dei servitori deve essere minimizzato in tempo ed


uso delle risorse tenendo conto anche delle propriet che si vogliono
garantire
In uno spazio piatto, necessit di fare una partizione dello spazio dei nomi
per limitare la coordinazione
In uno spazio partizionato, i nomi sono usati dalla autorit preposta senza
coordinamento

Le gestione delle tabelle e il coordinamento creano problemi di


consistenza e affidabilit, complicato dalla replicazione

RPC e Sistemi di nomi 40

COMPONENTI: GESTIONE NOMI


I nomi in molte forme e in base a queste la gestione
dipendenti dalla locazione, dipendenti dalla autorit (uso di domini)
organizzati in gerarchia (uso di un albero unico riconosciuto di domini)
liberi da struttura (uso di un insieme di attributi e del loro valore)

Nella gestione dei nomi sono fondamentali due decisioni


- Distribuzione
dei nomi
- Risoluzione
dei nomi
Distribuzione dei nomi
I nomi sono mantenuti in oggetti che ne hanno la responsabilit o autorit
con un partizionamento tra i server responsabili
Come dividere la gestione e il mantenimento?
Con politiche di Clustering di vario genere
Algoritmico
Sintattico
Basato su Attributi

(hash table / tabelle hash) es. funzione di mapping


(pattern matching) es. iniziale del nome
(tuple) es. sulla base del valore di attributi
RPC e Sistemi di nomi 41

RISOLUZIONE NOMI
Per la Risoluzione dei nomi, le richieste dal cliente devono fluire fino
al server che pu dare risposta
Il processo di risoluzione dei nomi per dare una risposta prevede
alcune fasi (non sempre presenti)
- trovare la autorit corretta
- verificare le autorizzazioni alla operazione
- eseguire la operazione
Ogni nodo specifica i name server noti e tende a limitare se possibile
le comunicazioni tra i server
Strategie usuali per limitare i costi sono:
- Politiche di caching
- Politiche di route tra server
- Creazione di contesti o vicinati tra i server
- Propagazione di conoscenza tra vicini
RPC e Sistemi di nomi 42

ESEMPIO di SISTEMA GLOBALE


USO DI CONTESTI E LOCALIT nei sistemi globali tipo DNS
Si distribuisce e risolve nel contesto locale
Si ricorre ad altri contesti solo in caso sia necessario
Le strategie di coordinamento tra i server devono essere a basso
costo, se possibile
RISOLUZIONE RICORSIVA
RISOLUZIONE ITERATIVA
Name
server

Name
server

Name
server

Name
server

Name
server

Name
server

Name
server

Name
agent

Name
server

Name
agent

Name
server

Name
server

Name
server

Name
server

Name
agent

(non DNS) RISOLUZIONE TRANSITIVA


39:40

RPC e Sistemi di nomi 43

(chemminchiadico?!)

ALTRI SISTEMI di NOMI (oltre DNS)


Altri sistemi di nomi, oltre al DNS molto specifico, hanno organizzato i
nomi attraverso attributi e ricerca su questi
OSI X.500 o Directory - Servizio standard di Direttorio e di Nomi
con realizzazione partizionata, decentralizzata, disponibile 24/7
CCITT definisce X.500 come "una collezione di sistemi aperti che
cooperano per mantenere un database logico di informazioni sugli oggetti
del mondo reale. Gli utenti della Directory possono leggere o modificare
l'informazione, o parte di essa, solo se hanno i privilegi necessari"
CCITT

ISO

TITLE

X.500

9594-1

Overview of Concepts, Models and Services

X.501

9594-2

Models

X.509

9594-8

Authentication Framework

X.511

9594-3

Abstract Service Definition

X.518

9594-4

Procedures for Distributed Operation

X.519

9594-5

Protocol Specifications

X.520

9594-6

Selected Attribute Types

X.521

9594-7

Selected Object Classes

X.525

9594-9

Replication

RPC e Sistemi di nomi 44

53:15

DIRECTORY X.500
X.500 un insieme di standard di nomi, articolato e completo
La base linsieme delle informazioni che caratterizzano la struttura
di directory, organizzate in un albero logico detto Directory
Information Tree (DIT) a formare il Directory Information Base (DIB),
L'albero logico costruito in base al valore di attributi del tutto liberi
e a scelta dellutente

La novit sta nella organizzazione


basata sui contenuti e
le ricerche (operazioni di lettura)
che si possono fare
in modo molto flessibile
per singole entit e
anche per attributo e ritrovando
gruppi di elementi (nodi)

Root node

Country =AU

Organization =
ABC Ltd

Org. Unit =
Sales

Common Name
= F. Jones

Country=US

Locality =
New York

Country=It

Organization =
ABC Ltd

Common Name
= A. Chew

Org. Unit =
Production

Common Name

Common Name

J. Smart
= Fax Machine
RPC e =Sistemi
di nomi
45

59:18

NOMI e QUERY in DIRECTORY X.500


Ogni entry (o nodo) si ritrova attraverso diverse notazioni
Distinguished Name (DN) che identifica univocamente l'oggetto
all'interno del DIT
Relative Distinguished Name (RDN) che definisce univocamente un
oggetto all'interno di un contesto

DN pu fungere da chiave per identificare unicamente un nodo


I nodi sono anche selezionalbili attraverso delle tuple, insiemi di
coppie attributo = valore
ad esempio: country, organization, organization unit, common name
US
ABCLtd
Production
J.Smart

Le ricerche possono essere fatte in modo globale o contestuale per


uno specifico DN ma anche per contenuto dei nodi, in base agli
attributi:
ad un attributo o ad un filtro generalizzato sugli attributi portando
ad un risultato di un nodo o pi nodi
RPC e Sistemi di nomi 46

INFORMAZIONI in DIRECTORY X.500


Le informazioni (attributi)
dei nodi sono
molto eterogenee
Si possono descrivere
organizzazioni, persone,
beni patrimoniali, risorse
geografiche, ecc.

RPC e Sistemi di nomi 47

59:20

RICERCHE con FILTRI


I filtri sono molto potenti come capacit espressiva
ad esempio, sono permesse condizioni logiche sugli attributi
CN=Corradi AND C=Italy
anche con espressioni regolari email=*hotmail*
anche con condizioni aritmetiche (age >18)AND(cookies <10)
Le ricerche si possono applicare anche a scope limitati (contesti o
sottoalberi)

Le operazioni previste
sono molte
La prima il bind con il
directory poi ricerche frequenti
e cambiamenti rari
La interfaccia con il direttorio
anche molto complessa tenendo
conto anche della
durata delle operazioni
RPC e Sistemi di nomi 48

ORGANIZZAZIONE INTERNA X.500


Ricerca sul direttorio X.500 avviene attraverso agenti:
DUA, Directory User Agent tramite per fare richieste
DSA, Directory System Agent che mantiene informazioni di contesto
DSP, Directory System Protocol per scambiare informazioni tra DSA
DAP, Directory Access Protocol, protocollo di accesso al direttorio

Dopo la connessione, si fanno operazioni di lettura, confronto,


ricerca, lista delle entit con tecniche di ricerca ricorsive ed iterative
LDAP,
Lightweight Directory Access Protocol
Protocollo limitato compatibile Internet
usato per infrastrutture di
verifica certificati
RPC e Sistemi di nomi 49

DIRECTORY e NON DB
Obiettivo di un directory mantenere informazioni su un insieme di
risorse eterogene per un ambiente evitando duplicazioni di
informazioni e problemi di sincronizzazione e consentendo
una capacit espressiva ampia ed estendibile
una gestione anche molteplice con pi autorit per parti
una sicurezza anche partizionata e differenziata

Al contrario di un database (o pi database)


- si associano attributi anche diversi con i singoli oggetti
- gli oggetti sono indipendenti tra di loro (e possono essere diversi)
- si considera la relazione di contenimento alla base della organizzazione
- si possono avere propriet di accesso differenziate per i singoli oggetti
- si ottimizza considerando un numero elevato di letture e poche scritture

Necessit di un protocollo standard unificato per accedere alle


informazioni, esprimere le specifiche di accesso, ed estrarre
informazioni in modo efficace
RPC e Sistemi di nomi 50

USO di DIRECTORY
i Directory sono tipicamente usati (vedi costo) per rappresentare
entit eterogenee, come persone, risorse, servizi, server, ...
In generale, per informazioni concettuali che rappresentano la gestione di
oggetti comuni in un ambiente condiviso
i certificati per autenticare e autorizzare accesso

MANAGEMENT DELLE RISORSE


In un sistema di gestione in cui consideriamo una molteplicit di gestori
con autorit e responsabilit anche non completamente note e forse
variabili lentamente nel tempo

si usano DIRECTORY per


. localizzare i diversi gestori e le loro politiche
. trattare i problemi di domini incrociati (cross-domain)
. ritrovare le propriet delle risorse
. ritrovare le propriet dei gestori delle risorse

I costi sono dipendenti dal numero dei nodi (e attributi)


motivati dalle propriet di QoS offerto (affidabilit e disponibilit)
RPC e Sistemi di nomi 51

SVILUPPO dei SISTEMI di NOMI


Due forme di evoluzione
Protocolli di Directory vs. Protocolli di Discovery
Considerando che una entit possa avere sia attributi con lente variazioni
sia attributi con variazioni veloci

Directory

soluzioni di nomi globali

servizi completi e complessi con costo elevato delle operazioni

Discovery soluzioni di nomi locali


servizi essenziali e funzioni limitate costo limitato adatto a variazioni rapide

Ad esempio: Un utente generico che si muova in un sistema globale


vuole avere accesso a
informazioni globali, essenzialmente stabili, come
descrizione dei dispositivi, delle preferenze proprie del suo profilo,
delle sue firme digitali e PKI, delle sue sorgenti di informazioni, ecc.

informazioni locali, anche molto variabili, come


descrizione delle risorse locali, dei gestori presenti, ecc.
RPC e Sistemi di nomi 52

PROTOCOLLI DI DIRECTORY
Un servizio di directory garantisce le propriet di QoS, ossia di
replicazione, sicurezza, gestione multiserver, ..., tutto il supporto per
memorizzare le informazioni organizzate prevedendo molti accessi in
lettura e poche variazioni
UPnP (Universal Plug-and-Play) Standard per architetture Microsoft
Servizi di Nomi basati su variazioni di DAP (o LDAP)
Windows2000 propone Active Directory come un servizio di direttori
integrato nel e per il sistema operativo

Salutation - Service Location Protocol (RFC 2165)


si possono registrare servizi diversi
i servizi vengono divisi in localit distinte
i servizi vengono protetti in diversi modi
interfacce compatibili con i browser (Web) e uso di nomi URL
Le operazioni definite e implementate permettono di fare ricerche evolute
sulle informazioni (memorizzate in modo globale) e compatibili con la
maggior parte degli strumenti e dei sistemi di nomi pi diffusi
implementazioni: Cisco, Apple, Novell
RPC e Sistemi di nomi 53

PROTOCOLLI DI DISCOVERY
Per computazione distribuita e cooperativa in ambito locale
Una unit deve ritrovarne altre, in modo veloce e economico
si prevedono azioni come il broadcast e solleciti periodici

un servizio di discovery definisce e standardizza come si


possano ritrovare altre entit correntemente visibili (localit
delle risorse)
JINI protocollo Java per il discovery di appliances
Si vuole rispondere alle esigenze di chi arriva in un contesto e vuole
operare senza conoscenze predefinite
Protocolli di lookup
Start up con multicast
in ambiente locale
Il discovery server
verifica la presenza
delle risorse ad intervalli opportuni
RPC e Sistemi di nomi 54
1 Richiesta Multicast

1 Richiesta Multicast

Rete Locale

Jini Service

2R

Jini Client

isp

o st

ad

el L

oo

kup

Se

rvic

Lookup Service

p
Ris

ost

ad

el L

oo

S
ku p

e rv

ice