P3-04: I/O multiplexing

Documenti analoghi
Problema. I/O Multiplexing. Struttura delle Operazioni di Lettura. Modelli di I/O. Prof. Vincenzo Auletta

Laboratorio di Reti di Calcolatori

Funzioni bloccanti e soluzioni

Funzioni bloccanti e soluzioni. Funzioni bloccanti e soluzioni (2) Parametri della funzione select() Funzione select()

funzione fork() La funzione fork è usata per duplicare un processo. #include <unistd.h> pid_t fork (void);

PRATICA - Lezione 1. Autunno PRATICA (Lez. 1)

SERVER CLIENT. Struttura di un Applicazione UDP. Socket UDP. Parametri di sendto. Funzioni di Input/Output. Prof. Vincenzo Auletta

Laboratorio di Reti di Calcolatori

Timeout. Socket Avanzati. Funzione alarm() Client echo UDP con alarm

funzione close() La funzione close è utilizzata normalmente per chiudere un descrittore di file, è utilizzata per chiudere un socket e terminare una

Laboratorio di Reti di Calcolatori

SERVER CLIENT. Letteralmente significa presa (di corrente) È l astrazione di un canale di comunicazione fra due computer connessi da una rete

Progettazione di Applicazioni Robuste. Applicazione Echo. Schema Generale di un Server TCP Ricorsivo 1. Applicazione echo

Socket II MIDLAB. Sirio Scipioni. M I D L A B.

Acknowledgment: Prof Vincenzo Auletta, Università di Salerno. Approfondimento alla programmazione distribuita

Corso di laurea in Informatica. Reti di Calcolatori A.A Prof. Roberto De Prisco LABORATORIO. Lezione

Server Iterativi. Server TCP Ricorsivi. Fork. Server Ricorsivi. un server iterativo gestisce una connessione alla volta. Prof.

LABORATORIO di Reti di Calcolatori

*HVWLRQHDYDQ]DWDGHOOH6RFNHWLQ& ODSULPLWLYDVHOHFW

Sviluppo di Applicazioni su Rete. Introduzione all API socket di Berkeley. Interazione tra Processi. Modello Client-Server

Esempi di Client e Server

request reply richiesta client processo di servizio processo server principale From - Valeria Cardellini, Corso Sist. Distr. A.A.

Progettazione di un client TCP. Progettazione di un server TCP. Esempio: daytime TCP. Client TCP daytime

Laboratorio di Reti di Calcolatori

Esempio 1: stampa locale di file remoto

Sistemi operativi Modulo II I semafori 2 Select

Socket per TCP: Fondamenti

Timeout. Socket Avanzati. Client echo UDP con alarm. Funzione alarm()

Reti Informatiche. Socket (Seconda Parte) Acknowledgment: Prof Vincenzo Auletta, Università di Salerno

I/O su Socket TCP: read()

Socket TCP. prima parte

Interazione con il DNS Conversioni di Nomi ed Indirizzi

Laboratorio di Programmazione in Rete

Reti di Calcolatori - Laboratorio. Lezione 5. Gennaro Oliva

Parametri valore-risultatorisultato

Programmazione di applicazioni di rete con socket - parte 2

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

Laboratorio di Reti di Calcolatori

SC per Inter Process Comminication. Comunicazione fra macchine diverse: socket

Opzioni del Socket. Socket Options. Opzioni di Livello Socket. Livello delle Opzioni

I files in C. A cura del prof. Ghezzi

Introduzione ai socket

Esercitazione [6] Client/Server con Socket

L uso di Socket UDP. TCP vs. UDP UDP

Laboratorio di Sistemi Operativi

Laboratorio reti AA 2008/2009. Dott. Matteo Roffilli Ricevimento in ufficio dopo la lezione

Esercitazione sulle Socket

Inter-process communication: socket

Sistemi Operativi Teledidattico

Programmazione di applicazioni di rete con socket - parte 1

Socket per TCP: Fondamenti

Esercitazione [5] Input/Output su Socket

C: panoramica. Violetta Lonati

Esercitazione di Lab. di Sistemi Operativi 1 a.a. 2011/ Comunicazione Tra Processi (IPC) Parte -

LABORATORIO di Reti di Calcolatori

Capitolo 5 -- Stevens

(VHUFLWD]LRQLGLEDVHVXOOH6RFNHWLQ&

IPC Inter Process Communication

Socket I MIDLAB. Sirio Scipioni. M I D L A B

CORSO DI SISTEMI OPERATIVI A - ESERCITAZIONE 6

GESTIONE DEI FILE IN C. Docente: Giorgio Giacinto AA 2008/2009

Creare un'elementare backdoor in C in ambiente UNIX

Corso di Reti di Calcolatori T

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

Reti (già Reti di Calcolatori )

File binari e file di testo

Modulo 10 System call per I/O avanzato

Esempio 1: stampa locale di file remoto

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE

Programmazione di applicazioni di rete

Laboratorio di. Reti Informatiche. Corso di Laurea Triennale in Ingegneria Informatica A.A. 2017/2018. Ing. Carlo Vallati

COMUNICAZIONE TRA PROCESSI REMOTI IN UNIX

Socket. Nei sistemi operativi moderni i servizi disponibili in rete si basano principalmente sul modello client/server.

Socket per TCP: Fondamenti

Server Ricorsivii i. Dott. Delfina Malandrino.

La Comunicazione tra Processi in Unix

Avviso ai programmatori. Programmazione in rete: i socket. Esercizio - copia dati. Messaggi di errore. stdarg.h. Funzioni di errore

Reti di Calcolatori - Laboratorio. Lezione 7. Gennaro Oliva

Programmazione socket. Queste slide sono distribuite con licenza Creative Commons Attribuzione-Non commerciale-condividi allo stesso modo 2.

IPC: InterProcess Communication

Una socket è un punto estremo di un canale di comunicazione accessibile mediante un file descriptor. Alcuni tipi predefiniti di socket

Interazione (TCP) Client-Server con le socket

DATAGRAM SOCKET. Angelastro Sergio Diomede Antonio Viterbo Tommaso

Socket. Nei sistemi operativi moderni i servizi disponibili in rete si basano principalmente sul modello client/server.

INGEGNERIA DEL WEB. VinX

Controllo dei Processi 1

I Socket. Laboratorio Software M. Grotto R. Farina

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

File I/O. M. R. Guarracino: File I/O 1

Sulla libreria standard, III. Manipolare file con stdio.h

getsockname() e getpeername() Formato dei dati - server Esempio getsockname() server (2)

Scrittura dei programmi applicativi di rete

Un server di posta (che usa il protocollo SMTP) è identificato dal numero di porta 25.

Avviso ai programmatori Programmazione in rete: i socket

Progetto fine al superamento del corso di Sistemi Operativi. Http server proxy Http web monitor

rsystem Maximiliano Marchesi

Guida all' uso dei sockets nella programmazione in C

Laboratorio di Sistemi Operativi Cognome Nome Mat.

Operazioni su file di caratteri

Transcript:

Autunno 2002 Prof. Roberto De Prisco -04: I/O multiplexing Università degli studi di alerno Laurea e Diploma in Informatica Problema 04.2 Un programma deve gestire due input simultaneamente tandard input (leggere da tastiera) Un socket (leggere dal socket) Abbiamo visto un esempio in cui il client era bloccato a leggere da standard input Non poteva leggere il FIN sul socket Normalmente una funzione di I/O si blocca se non ci sono dati da leggere erve un modo per poter aspettare da più canali di input Il primo che produce dati viene letto 1

Modelli di I/O 04.3 Vari modelli di Input/Output 1. Blocking 2. Nonblocking 3. I/O multiplexing 4. Guidato dai segnali 5. Asincrono sincroni incrono: il processo si blocca (quando chiama l operazione di lettura) fino alla conclusione dell operazione In una operazione di lettura da un canale di I/O possiamo distinguere due fasi 1. Attesa per i dati da parte del kernel 2. opia dei dati dal kernel al processo che deve usarli Blocking I/O 04.4 applicazione kernel Recvfrom ystem call Non ci sono datagram pronti FAE 1: attesa BLOATA datagram pronto opia datagram FAE 2: copia Processo continua (elabora il datagram) Ritorna OK opia completata 2

Nonblocking I/O 04.5 applicazione kernel Recvfrom ystem call Non ci sono datagram pronti Recvfrom Recvfrom EWOULDBLOK EWOULDBLOK ystem call ystem call datagram pronto FAE 1: attesa opia datagram BLOATA FAE 2: copia Processo continua (elabora il datagram) Ritorna OK opia completata I/O multiplexing 04.6 applicazione kernel select ystem call Non ci sono datagram pronti BLOATA Recvfrom Ritorna pronto ystem call datagram pronto opia datagram FAE 1: attesa BLOATA FAE 2: copia Processo continua (elabora il datagram) Ritorna OK opia completata 3

I/O guidato dai segnali 04.7 applicazione signal ystem call kernel Non ci sono datagram pronti FAE 1: attesa GETORE EGNALE Recvfrom EGNALE ystem call datagram pronto opia datagram BLOATA FAE 2: copia Processo continua (elabora il datagram) Ritorna OK opia completata I/O asincrono 04.8 applicazione aio_read ystem call kernel Non ci sono datagram pronti FAE 1: attesa datagram pronto opia datagram FAE 2: copia GETORE EGNALE Processo continua (elabora il datagram) EGNALE opia completata 4

Funzione select 04.9 #include <sys/select.h> #include <sys/time.h> int select(int maxfd, fd_set readset, fd_set writeset, fdset exceptionset, const struct timeval *timeout); Valore di ritorno: se errore, 0 se timeout, numero di descrittori pronti Permette di aspettare che uno o più file descriptor siano pronti per essere letti Il timeout è dato dalla struttura struct timeval { long tv_sec; long tv_usec; Parametri select 04.10 Timeout 1. Puntatore nullo: aspetta senza timeout (fino a che un descrittore è pronto) 2. truttura con un timeout non zero: aspetta fino al timeout, poi ritorna anche se non ci sono descrittori pronti Anche se possiamo specificare i microsecondi alcuni kernel arrotondano a multipli di 10 microsecondi Alcuni sistemi Linux modificano la struttura timeout (vale il tempo rimanente al momento del ritorno) 3. truttura con un timeout pari a 0: non aspettare, ritorna immediatamente (polling) File descriptor da controllare Readset: pronti per la lettura Writeset: pronti per la scrittura Exceptionset: condizioni particolari Arrivo di dati fuori banda su un socket Informazioni di controllo da uno pseudo terminale 5

Parametri select 04.11 Per descriveri gli insiemi si usa la struttura fd_set che è un insieme di bit void FD_ZERO(fd_set *fdset); Azzera la struttura fdset void FD_ET(int fd, fd_set *fdset); Mette a 1 il bit relativo al file descriptor fd void FD_LR(int fd, fd_set *fdset); Mette a 0 il bit relativo al file descriptor fd int FD_IET(int fd, fd_set *fdset); ontrolla se il bit relativo al file descriptor fd è a 1 La costante FD_ETIZE (select.h) è il numero di descrittori in fd_set (solitamente 1024) maxfd: è il numero massimo di descrittori effetivamente usati Usato per efficienza dal kernel Es. se siamo interessati ai descrittori 1,4,7,9 maxfd deve valere 10 (i file descriptor iniziano da 0) Descrittori pronti 04.12 Quando un socket descriptor è pronto per essere usato? ocket in lettura Quando c è almeno un byte da leggere La soglia si può cambiare con le opzioni dei socket Il socket è stato chiuso in lettura Es. è stato ricevuto il FIN L operazione di lettura ritorna EOF Il socket è un listening socket e ci sono delle connessioni completate è un errore L operazione di lettura ritornerà e errno specificherà l errore 6

Descrittori pronti 04.13 ocket in scrittura Il numero di byte di spazio disponibile nel buffer del kernel è maggiore di 2048 La soglia si può cambiare con le opzioni dei socket L operazione di scrittura ritorna il numero di byte effettivamente passati al livello di trasporto Il socket è stato chiuso in scrittura Un operazione di scrittura genera IGPIPE è un errore L operazione di scrittura ritornerà e errno specificherà l errore Eccezioni per socket Arrivo di dati fuori banda echoclient versione select (1) 04.14 void client_echo_select(file *fp, int sockfd) { int maxfdl; fd_set rset; char sendline[maxline], recvline[maxline]; int n; echocli-slct.c FD_ZERO(&rset); for( ; ; ) { FD_ET(fileno(fp), &rset); FD_ET(sockfd, &rset); maxfdl = MAX(fileno(fp), sockfd) + 1; if( select(maxfdl, &rset, NULL, NULL, NULL) < 0 ) err_sys("select error"); if( FD_IET(sockfd, &rset) ) { if ( (n = reti_readline(sockfd, recvline, MAXLINE)) < 0) { if( errno == EPIPE ) { err_msg( %s [%d]: server disconnesso, FILE, LINE ); break; else err_sys("readline error"); 7

echoclient versione select (2) 04.15 if (n == 0) err_quit( %s [%d]: server disconnesso, FILE, LINE ); fputs(recvline, stdout); if( FD_IET(fileno(fp), &rset) ) { if( fgets(sendline, MAXLINE, fp) == NULL) return; if( (reti_writen(sockfd, sendline, strlen(sendline))) < 0) err_sys("write error"); Il client riesce a gestire sia l input da tastiera che l input dal socket e il server termina viene spedito un EOF sul socket Il client lo riceve e termina la connessione enza select il client se ne sarebbe accorto dopo echoclient e select 04.16 ondizioni gestite da select in lettura su stdin ed un socket Data o EOF stdin socket lient TP RT data FIN 8

top-and-wait 04.17 Il client opera in modalità stop-and-wait: pedisce una linea di input e si blocca in attesa della risposta del server echo Tempo 0 dati Tempo 4 echo Tempo 1 dati Tempo 5 echo Tempo 2 dati Tempo 6 echo Tempo 3 dati Tempo 7 echo Batch input 04.18 i spediscono le richieste consecutivamente senza aspettare le risposte, che arriveranno dopo Tempo 0 d1 Tempo 4 d5 d4 d3 d2 r1 Tempo 1 d2 d1 Tempo 5 d6 d5 d4 d3 r1 r2 Tempo 2 d3 d2 d1 Tempo 6 d7 d6 r1 d5 r2 d4 r3 Tempo 3 d4 d3 d2 d1 Tempo 7 d8 r1 d7 r2 d6 r3 d5 r4 9

hutdown della connessione 04.19 Quando il client finisce di spedire non può chiudere il socket i possono esser ancora dati in arrivo i deve chiudere il socket solo in scrittura e lasciarlo aperto in lettura pedire il FIN solo in una direzione #include <sys/socket.h> int shutdown(int sockfd, int howto); Valore di ritorno: se errore, 0 se OK howto = HUT_RD, HUT_WR, HUT_RDWR echoclient versione shutdown 04.20 void client_echo_shutdown(file *fp, int sockfd) { int maxfdl, stdineof; fd_set rset; char sendline[maxline], recvline[maxline]; int n; echocli-shtd.c FD_ZERO(&rset); for( ; ; ) { FD_ET(fileno(fp), &rset); FD_ET(sockfd, &rset); maxfdl = MAX(fileno(fp), sockfd) + 1; if( select(maxfdl, &rset, NULL, NULL, NULL) < 0 ) err_sys("select error"); if( FD_IET(sockfd, &rset) ) { if ( (n = reti_readline(sockfd, recvline, MAXLINE)) < 0) { if( errno == EPIPE ) { err_msg("%s [%d]: server disconnesso", FILE, LINE ); break; else err_sys("readline error"); 10

echoclient versione shutdown 04.21 if (n == 0) { if( stdineof == 1 ) return; else { err_msg("%s [%d]: server disconnesso", FILE, LINE ); exit(); fputs(recvline, stdout); if( FD_IET(fileno(fp), &rset) ) { if( fgets(sendline, MAXLINE, fp) == NULL) { stdineof = 1; shutdown(sockfd, 1); FD_LR(fileno(fp), &rset); continue; if( (reti_writen(sockfd, sendline, strlen(sendline))) < 0) err_sys("write error"); elect per il server Possiamo usare select anche nel server 04.22 Al posto di creare un figlio per ogni connessione elect può leggere da tutti i client connessi trutture dati utilizzate Array rset, contiene file descriptor dei socket utilizzati dal server (sia listening che connessi) Array client, contiene interi che indicano fd client 1 2 3 rset fd0 fd1 fd2 fd3 fd4 fd5 0 0 0 0 0 0 FD_ETIZE 11

trutture dati per il server 04.23 Il server crea il listening socket chiamando listen upponiamo che gli standard file siano aperti e che il fd ritornato da listen sia 3 Tale informazione verrà memorizzata in rset rset fd0 fd1 fd2 fd3 fd4 fd5 0 0 0 1 0 0 Il server chiama select per leggere da tutti i socket (file descriptor) aperti All inizio c è solo il il listening socket, su fd 3 Quindi il parametro maxfd di select deve essere 4 trutture dati per il server 04.24 Quando un client stabilisce una connessione verrà creato un socket per la connessione con la funzione accept upponiamo che il fd ritornato è 4 client 1 2 3 4 rset fd0 fd1 fd2 fd3 fd4 fd5 0 0 0 1 1 0 FD_ETIZE Di nuovo il server chiama select per leggere da tutti i socket (file descriptor) aperti Ora ci sono due socket, su fd 3 (listening) e fd 4 (connessione) Quindi il parametro maxfd di select deve essere 5 12

trutture dati per il server 04.25 upponiamo che un altro client si connette, verrà creato un nuovo socket upponiamo che il fd ritornato è 5 client 1 2 3 4 5 rset fd0 fd1 fd2 fd3 fd4 fd5 0 0 0 1 1 1 FD_ETIZE Di nuovo il server chiama select per leggere da tutti i socket (file descriptor) aperti Ora ci sono tre socket, su fd 3 (listening), e fd 4 e fd 5 per le due connessioni Quindi il parametro maxfd di select deve essere 6 trutture dati per il server 04.26 upponiamo ora che la prima connessione (quella che usa fd 4) venga chiusa client 1 2 3 5 rset fd0 fd1 fd2 fd3 fd4 fd5 0 0 0 1 0 1 FD_ETIZE Il server chiama select per leggere da tutti i socket (file descriptor) aperti Ora ci sono due socket, su fd 3 (listening), e fd 5 (connessione) Quindi il parametro maxfd di select deve essere 6 13

Echo server versione select (1) 04.27 int main(int argc, char **argv) { int listenfd, connfd, sockfd; int i, maxi, maxfd; int ready, client[fd_etize]; char buff[maxline]; fd_set rset, allset; ssize_t n; struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; echosrv-slct.c if( (listenfd = socket(af_inet, OK_TREAM, 0)) < 0) err_sys("socket error"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(inaddr_any); servaddr.sin_port = htons(port); if( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0) err_sys("bind error"); if( listen(listenfd, BAKLOG) < 0 ) err_sys("listen error"); Echo server versione select (2) 04.28 maxfd = listenfd; /* inzializza il numero di descrittori */ maxi = ; for ( i = 0; i < FD_ETIZE; i++) client[i] = ; /* inizializza l'array client a */ FD_ZERO(&allset); /* inizializza a zero tutti i descrittori */ FD_ET(listenfd, &allset); /* setta il descrittore di ascolto */ for ( ; ; ) { rset = allset; /* insieme descrittori da controllare per la lettura */ if( (ready = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0 ) err_sys("select error"); if( FD_IET(listenfd, &rset) ) { /* richiesta ricevuta dal listening socket */ cliaddr_len = sizeof(cliaddr); if( (connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &cliaddr_len)) < 0) err_sys("accept error"); for(i = 0; i < FD_ETIZE; i++) if( client[i] < 0 ) { /* cerca il primo posto libero per il nuovo il descrittore */ client[i] = connfd; break; if( i == FD_ETIZE ) err_quit("troppi client"); FD_ET(connfd, &allset); /* setta connfd per la select */ if( connfd > maxfd ) maxfd = connfd; /* aggiorna maxfd */ if( i > maxi ) maxi = i; /* aggiorna maxi */ if( --ready <= 0 ) continue; /* se non ci sono altri socket pronti riprendi da select */ 14

Echo server versione select (3) 04.29 for( i = 0; i <= maxi; i++ ) { /* controlla tutti i socket attivi per controllare se sono leggibili */ if( (sockfd = client[i]) < 0 ) continue; if ( FD_IET(sockfd, &rset) ) { /* se sockfd è leggibile invoca la readline */ if ( (n = reti_readline(sockfd, buff, MAXLINE)) == 0) { /* connessione chiusa dall'altro endpoint */ close(sockfd); /* rimuovi sockfd dalla lista di socket che la select deve controllare */ FD_LR(sockfd, &allset); client[i] = ; /* cancella sockfd da client */ else reti_writen(sockfd, buff, n); if ( --ready <= 0 ) break; Denial of ervice Attack 04.30 onsideriamo la seguente situazione che può accadere con il server visto poco fa Un client si connette, spedisce un solo byte (che non sia un newline) e non fa più nulla Il server chiama readline che leggerà il singolo byte ma si bloccherà nella prossima chiamata a read in attesa di un newline Il server è bloccato e nessun altro client riceverà il servizio Denial of ervice Attack Un client riesce a far i modo che il server non risponda più ad altri client 15

Denial of ervice Attack 04.31 Il problema deriva dal fatto che il server si blocca in una funzione relativa ad un client mentre ci sono anche altri client Potrebbe andare bene se il server deve gestire un solo client Possibili soluzioni Usare un singolo processo per ogni client Utilizzare un timeout sulle operazioni di I/O Usare I/O non-blocking 16