0:40Oggi proviamo a fare un viaggio verso certe cose assai affascinanti, la capacità di usare le chiamate di sistema di Unix per interfacciarci col networking, con la rete e spedire pacchetti e ricevere pacchetti.
0:59Ma in questo viaggio ci accorgeremo anche di come assurde siano alcune API fornite da Unix, da quanto ostiche siano. Io, peraltro, sto facendo l'esperimento questa sera di non andarmi a vedere apposta come eh di non andarmi a rileggere, perché l'ho fatto 1le volte in passato, ma poi vi dico la verità, io a un certo punto mi sono rotto e mi sono scritto una libreria che poi ho usato
1:28per molti anni per fare il networking, per astrarmi il networking. Ecco, vedete qua è una libreria piccola di poche righe di codice, ma che fa la differenza. Quindi non mh diciamo evito di usare, diciamo, di solito l'API eh row, però in realtà mi capita. Oggi una piccola premessa, ci sono i large language model per cui tutto ciò non è necessario, però nel corso di questa lezione noi vedremo come i large language model possono
1:58intervenire in una seconda fase quando si crea un'applicazione a certa complessità, ma qui in qualche modo è un corso di programmazione in C, si fa artigianato, si fanno le cose a mano, anche se comunque a questo punto degli inserimenti di programmazione automatica sono interessanti a volte per comprendere perché è utile capire quello che succede, diciamo, in questo caso sotto il cofano per poi prendere le decisioni successive e poi quando queste decisioni sono state prese, quando
2:27l'architettura è chiara, come effettivamente un coding agent ci permette poi di andare più spediti nello nello sviluppo del codice. Allora, io vorrei implementare in questa lezione un il protocollo DNS. Credo che quasi sicuramente non riuscirò in una lezione singola della durata, quella classica, di quanto duravano tradizionalmente questi episodi, quanto? 20 minuti, poi ci sono stati alcuni di 40 minuti.
2:55Eh, perché tanto per iniziare dobbiamo partire dallo spiegare che cos'è il protocollo UDP. Allora, il protocollo UDP è il protocollo più semplice che c'è su internet sopra il protocollo IP. astrae un attimo il protocollo IP. Il protocollo IP è quello che consente, io qua c'ho due computer, questo computer e questo computer vogliono comunicare. Beh, se vogliono comunicare, diciamo, in termini moderni,
3:23allora, eh avranno una connessione TCP che dà l'impressione che c'è un tubo continuo di dati qui, ok? eh con cui si eh in cui non c'è la l'idea che i dati sono spediti su pacchetti discreti che contengono solo pezzettini eccetera eccetera, no? Eh eh per il protocollo UDP in realtà è un protocollo che non
3:52mentre il protocollo IP riesce praticamente a spedire un pacchetto da un computer a un altro, però poi un pacchetto di dati, quindi una quantità fissa con dei byte dentro, quindi da un indirizzo IP, per esempio 1.1.1.1 a 1.1.1.2.
4:14Control Z funziona qua. Sì. E il problema è che quando questo pacchetto raggiunge poi questo computer qua, eh a chi lo deve consegnare? Perché qua dentro noi possiamo avere diversi processi. C'è un programma che gira, c'è un altro programma che gira e c'è un altro programma ancora che gira. A chi lo consegno? Non si sa. L'UDP risolve esattamente questo problema. In che modo risolve questo problema? ma lo risolve eh mettendo eh il concetto di porta sorgente
4:46e porta di destinazione di ST dentro il pacchetto. Quindi praticamente tu hai il tuo pacchetto IP che è questo. Il pacchetto IP ha indirizzi sorgente e destinazione. Poi qua c'è i dati, c'è il leader UDP. Allora, questa cosa ve la devo far vedere. ODP packet incapsulation. Esatto. Guardate qua c'è il l'ader del pacchetto IP e qua ci sono indirizzi sorgente destinazione più altre cose.
5:22Poi c'è l'header UDP e poi ci sono i dati dell'UDP. In questo header UDP che cosa c'è? UDP header. È molto semplice l'header UDP. Guardate. Sfort destination port. Quindi si può si può identificare il programma che spedisce di un dato computer e il programma che deve ricevere questo pacchetto, la lunghezza, la somma di controllo e i dati. Ecco, per fare alcuni esperimenti noi potremmo usare in realtà Netcut. Vediamo se io mi apro un netcut qua.
5:54Spostiamo questa finestra qua. È un netcut qua. Quindi abbiamo un netcut qui. Allora, qua NC Netcut - UDP men listen lo facciamo ascoltare. Allora, questo significa io voglio UDP. Devi rimanere in ascolto nella porta 555 DP, quindi porta destinazione. Qua io gli dico Netc menù 555,
6:22faccio e ciao e lo mando. Di solito Netcat, se non specifico niente legge dallo standard input, quindi io gli mando questo. Ciao. Allora, Pours la destination port 12700155.
6:43Esatto. Vedete che qui abbiamo ricevuto ciao perché gliel'abbiamo spedito da qui. In realtà quello era un pacchetto, ma ve la devo f vedere meglio questa cosa. Facciamo un'altra eh un altro tab del terminale. TCP Dump UDP 5555. Vi dico ATCP Dump che è un programma che mostra i pacchetti che passano dalla
7:10rete. Bisogna vedere in quale interfaccia come si chiama? L0 L0
7:27I lo0 expression esatto I l0 quindi dico di ascoltare l'interface lpec protocollo UDP porta 5555 quindi quando io poi qua scrivo qualcosa. Ah, no, devo devo rifarlo da capo e faccio di nuovo questa cosa qua. E qua dovrei in teoria ricevere il prossimo ciao, ma no, perché ricevo un pacchetto solo e si ferma. Esattamente è arrivato di nuovo.
8:03Guardate qui cosa ho visto, eh, in tra i pacchetti UDP che sono che sono transitati. Guardate l'ultimo che è quello che veramente è riuscito ad arrivare a segno. Quindi l'indirizzo IP era Localos 127001 e questa era la porta sorgente che è stata scelta da Netcat. L'altra che è la porta 555, vabbè, qua mi scrive personal agent perché evidentemente la porta 555 è mappata a un nome, si usa per questa
8:32cosa per il personal agent che chissà che cos'è. Sicuramente non era la gente ehm nel senso moderno, ma forse Netc TCP DAM se io lo faccio partire con - n dovrebbe mostrarmi solo numeri. Vediamo se è vero. Esatto, guardate. IP 127001 e questa è la porta. E questo invece è
8:58la destinazione 5555 VDP di lunghezza 5 byte. perché c'è probabilmente anche il new line là dentro. Quindi eh come vedete ecco un protocollo a pacchetti e per questo si chiama datagram UDP. Eh UDP è l'acronimo di Universal Datagram Protocol.
9:23Eh, andiamo a vedere eh user, scusate, datagram protocol perché lo può usare appunto l'utente perché le applicazioni possono registrare delle porte, spedire a delle porte, quindi è una comunicazione tra processi. Ora però come faccio a creare una socket di USP e a spedire effettivamente eh una eh Ecco, noi possiamo usare da un
9:51lato teniamo il nostro eh Netcut che ascolta nella porta 555. Noi dobbiamo provare a scrivere un programma in C effettivamente è in grado di spedire un programma, un pacchetto UTP con un dato contenuto. E questo, ragazzi, è un casino. Ora vi faccio vedere. Eh vabbè, includiamo stdo. Eh, per ovvie ragioni. Qua è un po' tagliata la finestra dov riuscire ad abbassare un po', ma è praticamente impossibile perché questo mi fa questi scherzi qui.
10:32Vabbè, dai, così ce la possiamo fare. Allora, vediamo quante cose devo includere. Prima di tutto mi serve la chiamata di sistema socket. sissocket.
10:47Poi mi serve eh Unix Standard per Send to che mi serve per spedire. Poi sissocket. Già ce l'abbiamo. Vabbè, ora le includiamo man mano. Int main. Allora, io voglio tanto per iniziare creare su su Unix ogni cosa è un file descriptor, ok? è un descrittore di file, quindi così come uno può aprire un file scrivendo intor
11:15uguale open, la chiamata di sistema open a basso livello, non so se ve l'ho fatta vedere o se abbiamo fatto sempre F open.
11:21Questa è la chiamata di sistema a basso livello dove poi si usano le altre chiamate di sistema read, Wright e così via. Eh, praticamente un socket DP non è tanto diverso, ma io qua lo chiamo S perché è un socket e si apre con una chiamata di sistema che si chiama socket Man 2 Socket, la vedete qua. E noi dobbiamo aprire un eh socket di eh
11:49internet, quindi pfet. Guardate il primo argomento, vedete che è il dominio, cioè praticamente è il Allora, vediamo se ci sono degli esempi. No, non c'è alcun esempio. Quindi il dominio, leggiamo la la pagina del manuale, specifica il dominio di comunicazione, cioè praticamente cos'è un un socchetto di Unix.
12:22che è una forma di i interprocess communication eh tra quindi non è veramente una rete, è internet versione 4, è internet, cioè il P eh IP versione 6 e così via, un socket di dominio di Unix, ci sono diversi tipi di socket. Chiaramente per noi il punto è aprire una eh vogliamo usare noi CCP con l'IP a versione 4 e quindi useremo PF Inet. Questo già lo possiamo scrivere PF inet.
12:57Poi secondo argomento, type Sock di Gram è l'UDP. Soc stream sarebbe il TCP. Sock row è un socket che mi permette di forgiare un pacchetto mio, che è una cosa che ho usato tantissimo in passato, perché ho scritto tanto tempo fa un programma che si chiama Hping
13:24che permette appunto di fare strane cose con il TCP, eh tra cui Lidl Scan si possono utilizzare tecniche interessanti. È un po' questa sicurezza del passato. Secondo me ancora ci sono bug negli stack e così via. Uno è stato trovato all'AI, mi pare lo stack del di Open BSD qualche tempo fa ne avevo parlato, se ben ricordo, però insomma le le socket Row sono utili, sono interessanti, ma in questo momento in effetti non ci interessano. A noi ci
13:53interessa una Sock di Gram e l'ultimo argomento è protocol e che vi dico la verità, io non mi ricordo assolutamente. A particolar protocol to normally only a single protocol exists to support a particle socket type protocol family. Vabbè, praticamente devo mettere zero. Vabbè, dovrei mettere zero, credo. Ora vediamo. Quindi abbiamo creato la socket, ma che ci facciamo? Come vedete che è un oggetto completamente astratto.
14:32Per spedire attraverso questa socket noi dobbiamo avere l'indirizzo, un modo per mettere l'indirizzo di destinazione che è 127001 eh con l'IP e la porta è 555.
14:47Di solito si usa la chiamata di sistema Send to e guardate come funziona questa send to. Praticamente sendto to. Gli dico qual è la socket dove voglio spedire, gli dico qual è il buffer che contiene i dati e la lunghezza di questi dati, gli do flag e poi però gli devo dare, guardate, un indirizzo di destinazione che è nella forma struct,
15:15però questa è una forma generica, qua la cosa è un po' complicata. Struct sock ad in. In realtà a me mi serve un indirizzo di socket di internet, ok? Che è quello di IPV4 e io questo structo,
15:35sa. Ok, lo resetto memet, prendo l'indirizzo e gli metto tutti zero per la dimensione di SA. Quindi inizializzo tutti i cambi a zero. Questo è prassi ed è importante farlo perché eh noi ora setteremo solo alcuni campi di di questo di questo indirizzo e ora vedrete manock ad AD in. Eh, ma sapete che ora non so dove andarlo a prendere. Ora vediamo sendi.
16:18Eh, socket gets occopt. Siccome io non me lo ricordo, devo andare a cercare esattamente. Allora, guardate qua, gli devo dire la famiglia, perché voi direte perché una cosa del genere, che senso ha?
16:35Ehm, il fatto è questo, eh, praticamente questa struttura qui ha dei campi che sono condivisi con gli con con le altre strutture di tipo soccader. Sapete che che io poi praticamente nella chiamata Send to devo andare e fare il casting, cioè devo passare il puntatore non a un soccader in, ma a un generico soccader e siccome tutti i soccader hanno come
17:01primo campo la famiglia del socket, come abbiamo visto qua, lui si può comprendere che si tratta di un soccader in perché è questo primo campo che glielo dirà, perché altrimenti, vedete, non ha un argomento la sentio io gli passo anche a F inet. Ok, quindi ora che ho inizializzato tutto, quindi
17:27ora scrivo SA pun sin family è uguale a F inet SA pun sin port è UG H2NS55.
17:42Cos'è questo H2Ns? Allora, per motivi storici, tutte le cose che hanno a che fare con la rete si esprimono non in little Indian, quindi con la con l'organizzazione dei byte negli interi in cui la la il byte meno significativo è il primo, poi c'è quello più significativo, alla fine c'è quello eh in assoluto di più significativo di tutti, ma esattamente al contrario.
18:08Quindi, praticamente, io c'ho i byte più significativi a a sinistra e quelli meno significativi a destra. Quindi devo convertire questo numero da host. L'host è little lendian in questo caso, qualsiasi cosa sia, host network, quindi host to network short. Sta per short. Se io fossi in un computer big Indian, siccome l'ordinamento di rete è uguale a Bing Indian, questa funzione non farebbe
18:36nulla. Ma in questo caso fa inverte eh converte questo numero in questa modalità. Io infatti questa cosa ve la voglio fare vedere. Guardate, se io qua scrivo 5555 return zero e compilo questo programma che però non posso compilare perché mi devo ricordare dov'è definita Socadre in eh Socd. includes devo qui devo includere questo. Scusate gli avvicini c'erano già.
19:25Memet è in string. Compiliamo e print f. Eh, qua, scusate, ho messo S invece di D. Ora ci siamo. Guardate, questo mi scrive 5555 eccetera eccetera. Se io faccio dal lost al network questa conversione di questo short, mi diventa un altro numero, ma questo numero non è altro che 555 coi byte invertiti, ok? E quindi diventa 458 4. Vi faccio vedere. Io me la potrei
20:02scrivere anche da solo la eh hns my htns, quindi ints. Veramente è short input i chiamiamolo. Quindi qua definisco un puntatore unsignnet char che è uguale all'indirizzo di memoria dove c'è registrato questo intero. Così ora io posso accedere ai due eh ai due byte con ID1 ID0 e ID1. Ora guardate, io sti byte
20:42lì inverto. Qua facciamo unsigned chart è uguale a eh ID0 ID0 lo sto facendo uno swap è uguale a ID1 banale e ID1 che altrimenti l'avrei persa, me lo prendo da T che l'ho salvato apposta per questo motivo qui e qua ritorno
21:08i ok. dopo che ho invertito i 2 byte che rappresentavano l'intero. Guardate, se io qua uso la my H2Ns che non funziona, unsigned char, unsigned char. Qua ho sbagliato perché doveva essere ovviamente delle P. Esatto, perché il mio puntatore si chiama P, scusate. Eh, anche qui ora combina e eh mi dà un valore diverso. Come mai? P0 è = P1. P1 è uguale a E questo è uno short. Sì.
22:40Unsignnet. short, molto semplicemente era un signet, scusatemi. Eh, esatto. Ora i due numeri cono perché queste funzioni sono definite su numeri da 16 bit senza segno. L'ansignnet short è un intero di 16 bit senza segno. Eh, come vedete, quindi uno se la può creare, semplicemente inverte i byte perché cambia la perché allora vedete tutte singolarmente sono delle fesserie.
23:12Il problema è che per spedire un pacchetto UDP, vedete quanti dettagli ci sono. Allora, Sin poi SA sin ADR, dove si dovrebbe chiamare se me lo se mi ricordo bene. Sin ADR. Sin ADR eh man inet pito p si dovrebbe chiamare la funzione che mi converte un indirizzo IP. ha la sua rappresentazione qua dentro dentro il eh la il suo cadut in. Allora, vediamo come funziona sta funzione.
23:54Allora, io usavo più spesso di solito a ton che è più semplice e funziona. Vabbè, facciamola con questa perché questo N top gestisce più famiglie. Esattamente. Allora, prima lo facciamo con questo ineton che è molto più lineare.
24:24Quindi io faccio constri che sarebbe 107001 stract in other. Quindi qua faccio stct in other perché devo castare fare fare il casting a questa struttura generica che però poi si specializza tramite il suo primo campo che si chiama SA. Nel mio caso l'avevo chiamata SA qui
24:52vedete? Quindi sempre si passano i puntatori come se fossero tipo eh ah no, scusate, questo è inader, quindi è SA. è questo punto sin ad. Credo che sia questo il modo in cui si usa sta roba qua.
25:13Esattamente. E io qua non gli passo soccater, gli passo semplicemente l'indirizzo eh soltanto che dovrebbe essere di questo tipo giusto sin add, quindi io devo prendere quale indirizzo, ma quindi in teoria io questa casting non mi serve più. Vediamo se mi dà error o se funziona bene.
25:40Ed è qua in [schiarire la voce] questo altro header, ragazzi. Cioè, qua si chiama sto sto questo header qua si chiama ARPA, cioè il nome tipo della pre internet, per capirci di come siamo combinati qui. Questo programma compila che è già qualcosa, quindi praticamente ce l'abbiamo fatta finora. Ora dobbiamo ah però attenzione dobbiamo cercare man
26:05in AN che di errore dà interpret string sping the address it turns one if the string was successfully interpreted quindi if not se ha dato errore usiamo p error anzi no facciamo la print f invalid internet address
26:34exit, anzi returnum, in questo caso basta questo. Siamo nella main. A questo punto forse possiamo usare la nostra send to. Allora, qua i dati. Data è uguale ciao. Ciao sln sono 5 byte. Sent, allora sen tu. Socket, Buffer, Len, Flag. Eh, allora, tanto per iniziare, diamoci sta cosa. Socket che era S, vi ricordate? Qui abbiamo definito int S uguale il nostro socket.
27:23Il buffer coi dati, la lunghezza 5 byte, flag, non lo so, però gli metto zero. Eh, stct Sock, ad and SA, size offs.
27:43Quindi io gli passo l'indirizzo però facendo finta che è un puntatore di tipo generico soccader perché questo se tu mica può spedire solo a indirizzi di tipo soccadr, questa è una funzione Unix generica. Può spedire diversi tipi di indirizzi, IPv6 per esempio, può spedire Socket di Unix, può spedire a varie cose teoricamente che definiscono, diciamo, questa
28:09chiamata di sistema. Per cui e poi gli devo dire la la grandezza di questo indirizzo. Lui non lo sa perché può essere di qualsiasi tipo. In realtà non capisco perché non legge la family. Qua f net e basta. Mi serve solo sapere questo zero qui.
28:33Che cos'è questo flex?
28:38Ah, ok. Questi sono process out of band data. Questi sono delle cose che poi hanno a che fare con credo che sia una proprietà del protocollo TCP. Puoi puoi praticamente spedire dei dati che anche se la Reid in una Socket TCP sta leggendo ancora dei dati e ce ne sono molti altri questi diciamo prendono la precedenza. Qua ti dice all'interfaccia don't root, quindi proprio non fare passare dalle tabelle di routing
29:06direttamente spedisci a una specifica interfaccia, non ce ne frega niente di tutto ciò e ho fatto bene a scriverlo, a metterlo a zero. Combiniamo sto programma magari con -2- wall - v, vediamo se ci dà altri warning. Non ci dà niente. Allora, qua non c'è niente scritto. Eseguo il programma. Oh, ce l'abbiamo fatta, ragazzi. Ora proviamo a usare
29:34invece di questa funzione qui che è più vecchia in etettaton inet piton in net.
29:55Questa la compiliamo.
30:03Allora, però non non controllo il valo di ritorno, quindi il socket fet srcc dovrebbe essere il mio 127001. Eh, destination e and sa sin.
30:34Ah, neanche compila.
30:44Allora, qua dobbiamo riavviare. Sì, il ciao arriva. Quindi, eh, in teoria tutta sta roba qui è corretta, eh if not, vediamo se è uguale che mi ritorna a zero. Esatto. Continua a funzionare il programma, per cui sì, i valori di ritorno sono uguali. In teoria possiamo utilizzare questa funzione più, vabbè, giusto per farvela vedere, ma in realtà usiamo aton per semplificare le cose che già ce l'avevamo e funzionava.
31:23Sulla base di questa conoscenza, noi cos'è che andremo a fare nella prossima puntata?
31:30Eh, UDP Socket, no? Allora, DNS, header, packet images. Uno che ci piace è questo. Esatto. Open image in a new tab. Eh, guardate il formato del leer. Qua c'è questi qua sono 16 bit ognuno. C'è l'ID che poi vi spiegherò a cosa serve. Poi ci sono questi vari cambi, QR, query, query o reply. Eh, quindi è una domanda o una risposta.
32:08L'opodi flag di diverso tipo. Eh, quante il numero di eh domande di qui che ci sono nel pacchetto, il numero di risposte, il numero di sezioni eh NS New Server e additional. Questo dovrebbe essere, se non mi ricordo bene, non me lo ricordo, ma poi lo andiamo a vedere di preciso questa cosa qui. Comunque finalmente siamo riusciti a eh a spedire
32:37questo pacchetto, però questa lezione non sarebbe non sarebbe sufficientemente interessante se io non vi mostrassi una cosa. Ora, creare ogni volta una socket e richiuderla non è l'ideale, quindi non astrarrò troppo, ma tutta la parte per spedire questi pacchetti qua io posso fare una funzione magari int, così da restituire un errore che si chiama sendp
33:04int socket char host int anzi unsigned short port perché la porta può essere massimo 16 bit. Quindi io posso andare a prendere tutta sta roba qui, ok? La vado a mettere qui. Quindi qua ogni volta crea praticamente qua questo qui diventa post, questo diventa port, questo diventa che quando c'è un errore il coso ritorna.
33:43Facciamo che ritorna uno nel caso dei errore, perché a me mi piace di più scrivere se eh la nuova funzione mi ritorna non zero, mi così evito il not. Ho fatto sempre così. Questo mettiamolo in line da attenzione host port eh sign char data site tata len.
34:11Cos'è che voglio spedire? Me lo devo fare dare. Quindi questo è data e questo qui è data len. Ok? Io mi sono fatto questa funzione, me la faccio una volta nella vita. Quando devo spedire un pacchetto DP scriverò sento DP. con la mia socket che non voglio riaprire ogni volta.
34:33A chi spedisco sto? Perché tra l'altro eh credo che ogni volta poi viene associato un nuovo direttamente quando creo la socket già dovrebbe avere l'indirizzo sorgente. Eh magari non lo so se è lezi nei kernel nuovi questa cosa poi se volete la vediamo, però non voglio poi riutilizzare porte così a manetta, o meglio, ci sono casi in cui le vorrò fare proprio per questa cosa della del DNS per questione di sicurezza, ma poi questa cosa la vedremo. Quindi dico 127001
35:02555 ciao e sono 5 byte. Ok, se io compilo questo nuovo programma e unsigned char perché in realtà possono essere byte. Qui è una stringa, ma io voglio unsigned.
35:29Eh, allora rifacciamo qui Netcat che ascolta di nuovo e lanciamo il programma. Ora vedete il bello delle astrazioni che quando sono è che quando sono al giusto livello tu praticamente ti puoi scordare per sempre. Questa cosa qui la scrivi una volta e contest poi continuerai a mettere questo file C dentro ai tuoi progetti, te lo scordi per sempre. E quella era la libreria ANET che vi ho fatto vedere poco fa. dopo. Spero che vi siate divertiti. Non credo proprio
35:59perché come vedete è tutto un casino. È strano che poi a un certo punto nessuno abbia pensato di Ora non dico che questa sento.
36:19Poi ogni volta è vero che noi andiamo a fare qua lavoro ripetuto. Se io devo spedire sempre lo stesso indirizzo, però si poteva estrarre si poteva avere un'interfaccia di alto livello come questa e poi la parte sotto astrarla un po' o ci potevano essere altre altri modi più interessanti. Io eh praticamente la mia socket la potevo eh astrarre come un endp, poi praticamente ogni volta se voglio la connetto o non la connetto a un determinato indizio di
36:49destinazione. Quindi quando io uso send DP gli passo questa socket più oggetto, diciamo, e quindi non va. Ho sia l'efficienza che un API molto pulita, perché se io non vado a riconnetterla si ricorda l'ultimo indirizzo non va queste cose qua e finirà per fare solo la sent, quindi diventerà estremamente efficace e però senza questo panico. Sarebbe un bell'esercizio in effetti scrivere una
37:17un'implementazione, un API astratta che dia pulizia a questa cosa qua. Sarebbe anche interessante poi darla come building block a un Llm perché possibilmente gli large language model se tu gli dai comunque delle dei building block più puliti, lo lo dicevo oggi questo Twix Karmac, [sospiri] non ci credo a questa cosa, vi dico la verità e largio linguag se ne frega, può fare benissimo questa cosa a basso livello e
37:46lui ce la fa bene, però lui diceva magari il codice meno una a mess dal punto di vista della lettura di un essere umano. Il punto è che dobbiamo chiederci se veramente vale la pena di questa lettura umana di farla o meno. Vale la pena di imparare questa cosa. Ecco, questa è la separazione.
38:04Questo bisogna saperlo perché ora che lo sapete è diverso. Quando voi creerete un LLM di scrivere un programma che vi spedisce un pacchetto DP, voi avete questa rappresentazione mentale, non ve la può togliere più nessuno, però questo significa che poi volete andare a guardare com'è che è aperto di preciso socket, che che chiamate ha fatto, ma chi se ne frega.
38:28In realtà eh questo esercizio di provare a fare diventare questo codice una libreria reale è molto interessante. Potrebbe essere in realtà una delle parti più interessanti di questa lezione, quindi anche se già siamo, diciamo, andati sul lungo, pensavo di eh di inserirlo. Allora, com'è che si fa a portare questo codice a una libreria reale utilizzabile, seppur minimale? Però giusto per capirci, tanto per iniziare qui manca la gestione degli errori in diversi punti.
39:02Per esempio questo qui int s uguale socket e così via. Poi noi dovremmo fare se S ug uguale a -1. Ricordate che le chiamate di sistema eh di posx solitamente ritornano -1 quando c'è un errore. Qui noi dovremmo tornare un errore, ma la cosa a questo punto si muove in un altro ambito.
39:25Quali sono i modi in cui io potrei associare una so che DP ha un indirizzo di destinazione? Una di queste modalità è utilizzare la chiamata connect, ma io non userò questo trucco perché vi voglio fare vedere un'idea un po' più di alto livello. Questa cosa qui, Connect, permette di connettere il socket a un indirizzo di destinazione direttamente a livello del kernel. Quindi quello che accade, proviamo a capire cos'è che
39:54accade a livello di sistema operativo in tutto ciò, perché noi finora abbiamo compreso l'API, cosa fa, come si spedisce un pacchetto DP, perché non proviamo a fare il passo successivo? Io capisco che questo richiede uno sforzo superiore, però secondo me è la parte più interessante. Allora, io qua sto chiedendo al kernel di creare all'interno del processo una socket che è sostanzialmente una struttura,
40:23uno stato legato al allo stack TCPIP del sistema operativo.
40:31questa socket alloerà una una struttura che è poi atta a spedire pacchetti UDP, avrà un suo buffer, cose del genere, ma in realtà io non credo che nessun sistema operativo, ormai quando io chiamo la chiamata di sistema socket, ehm cerchi davvero di allocare la porta effimera o dip perché io devo avere una porta sorgente per spedire un pacchetto a qualcuno. Questa porta in questo caso la sceglie la sceglie il il sistema operativo tra quelle libere che ci sono
41:01eh associate eh a un dato indirizzo perché ogni io su un dato indirizzo posso avere massimo 65.530 35 porte eh togliendo la porta zero in un dato momento. Ok? Quindi quando io creo la Socket, in realtà fino a quando io non utilizzo Send to, non viene creato niente, viene creato una struttura. Quindi questo m questo comando può fallire sostanzialmente se
41:29c'è un out of memory, credo, però il va controllato eh il ovviamente il valore di ritorno perché potrebbe fallire. Oltre a ciò, visto che io ho questa struttura ormai internal space associata al processo di questa socket che ha uno stato, posso utilizzare la chiamata di sistema connect. In teoria, per di questa socket, anche se è un DP, scriverà solo
41:58a spendirà pacchetti solo a una determinato sin ad di indirizzo di estimazione specifico. Quando io faccio ciò, in realtà credo che cambino due cose. Non solo, appunto, io poi posso tra l'altro scrivere utilizzare la chiamata di sistema WR per per scrivere dentro questa socket che è la chiamata di sistema che di solito si si usa per scrivere nei file, però ricordatevi che su Unix tutto è un file e quindi io
42:28posso utilizzare questa chiamata di sistema anche contro una socket perché utilizza la stessazione dei file, ma solo se il socket è connesso, alright mi può dire "Ma io dov'è che spedisco?" Ma infatti ve lo faccio vedere. Write Sola ciao 4 = uguale a min ugituire l'errore. Qua pure potremmo mettere retard zero, anche se è implicito a C99 in poi.
43:08Destination address required. Vedete la W dice "Ma io dov'è che dovrei dove dovrei spedirlo sto coso?"
43:16Per cui, giusto per sapere che esiste questa possibilità, io non la utilizzerò perché vi voglio far vedere un'astrazione di più alto livello. Ah, una cosa importante. Una volta che io utilizzo Connect, quando io leggo da questo socket, io reggerò solo i pacchetti che mi arrivano da quella destinazione e il kernel scarterà tutti i pacchetti che guarda caso, arrivano alla mia porta effimera. Quindi non a 555 che è la destinazione, ma alla porta locale UDP che il kernel ha deciso di
43:46assegnare a questo preciso socket che è in mano, quindi a sola a questo processo. Ok? Altrimenti io se sapessi qual è la porta FIM la posso spedire da altre destinazioni e le potrei ricevere in quel modo. E invece le ricevo solo da quello specifica indirizzo IP e porta.
44:10Allora, com'è che posso fare per creare un'idea di più alto livello? Extract con quindi connessione UDP cosha?
44:24[sospiri] Ha una socket, ha una destinazione e probabilmente basta. In teoria, ecco, in teoria io potrei dire che ha pure uno stato, ma in ogni caso dovrai inizializzarla, quindi non ne vale tanto la pena. Quindi a questo punto quello che accrederebbe è che io Ma sì, a questo punto io avrei per esempio una int perché mi deve serve restituire l'errore. Create UDP socket stract UDP con UDP.
45:19E poi send UDP, stract UDP con UDP virgola eh Allora, qua mi serve pure intetpination. Vabbè, non è il massimo del nome. Potrei avere queste API qua. Tra l'altro qua, attenzione che in teoria, vabbè, qua siamo dentro main, ma poi io in teoria dovrei fare dopo che uso questa socket close S, la devo anche chiudere. Ok, quindi qua mi serve pure create UDP, send UDP, close UDP.
46:15Allora, cos'è che farebbero queste queste funzioni? Create to DP Socket non farebbe altro che se chiamare la chiamata di sistema socket.
46:25Quindi questa la tolgo da main e diventa sostanzialmente questa cosa qua. Ok?
46:35Una volta che io s = -1 return -1.
46:39Facciamogli ritornare -1.
46:41Esattamente come ha tutte queste funzioni, come le chiamate sistema per coerenza, mi sa che è più pulito. Una volta che io faccio qua, eh io posso anche decidere qua di avere un flag eh inted
47:01intor qua faccio qua int s eccetera eccetera. UDP S = S. lo setto nella struttura connected uguale a 0 perché io voglio replicare la cosa che faceva il kerneva se la se la socket non era ancora connessa un indirizzo di destinazione. Set DP destination è quello che fa sostanzialmente sta roba qua. A questo punto la send to sarà quella che passa qui. Close UDP farà solo close UDP.
47:40S e qua ritorniamo il valore di ritorno della close. Qua non c'è niente da distruggere perché niente, non è allocato. Questo qui è parte la struttura. La struttura io poi la dichiaro qua semplicemente come variabile locale, quindi non dobbiamo distruggere nulla. Allora, invece questo qui fa setp destination. Eh, soccadin sa non serve più, quindi faccio memet UDP, com'è che si chiamava? Dest.
48:26Aspetta. const host ansignnet short port. Ehm ok in realtà non dovremmo utilizzare i nettettaton perché ricordate che non è una funzione eh posx. Questa è una funzione ormai, diciamo, che c'è ovunque, però sarebbe eh P2N, quella che abbiamo usato poco fa, però ripeto, qua ce lo stiamo accollando.
49:10Ritorniamo -1 in caso di errore.
49:15Standardizziamo tutto così. A questo punto cos'è che fa la send?
49:20Cost char cost void data size tata len. Ok. Send to dataalen qua UDP des size of UDP deskt. In teoria dovrebbe essere tutto a posto.
49:49Qua chiudo la socket. Se DP non mi serve più a niente. Allora, come si usa questo API?
49:56Struct UDP con com'è che si chiamava?
50:01Sì, UDP. Poi, quindi creo questa socket con come si chiamava? Create UDP socket. If create to UDP socket, quello che è and DP uguale uguale a -1. Vabbè, qua usiamo questo pattern del go to error perché [schiarire la voce] in questo caso faremo una uscita molto semplice di scena R P error error sendingpeto. Quindi unifichiamo qua sta roba qua [schiarire la voce] senza neanche, diciamo, curarci poi di fare la close.
50:56Poi if set to DP destination and to DP virgola 127001 55
51:11V ug -1 go to R if sendu DP and DP ciao5 ug ug -1 1 Go to R. Sto andando un po' di fretta, non so se ho fatto bene. Se siamo arrivati qui, close UDP and UDP, ce ne freghiamo dell'errore perché in ogni caso non possiamo recuperarlo e comunque il pacchetto è già partito, quindi facciamo, scusate, ho creato un file che non dovevo creare.
52:00Non lo so se ho scritto giusto.
52:06Qua dovevo ritornare zero per dire che non c'è stato sono stati problemi. Questi punto e virgola sono inutili. Non so perché li ho scritti. La mem errore perché sizeof dp. che c'è qua a 26 member SA, come si chiamava test. E qui non c'è S perché si chiama ODP S. Ok. Allora, questa è la nostra microlibreria.
52:56Che problema c'è? A 32 return. Vabbè, qua possiamo ritornare direttamente e come abbiamo fatto per la close, direttamente quello che ci ritorna sent perché poi tanto sempre meno un Allora, qua ce l'abbiamo Netc.
53:14Ciao, ciè arrivato questo. Ciao, ci'è arrivato. Quindi non lo so, possiamo supporre che eh abbiamo fatto bene. Va bene, questo è per farvi vedere, diciamo, ecco, com'è che si crea un minimo di astrazione reale comunque. Cioè, dai ragazzi, ora capisco che le cose sono volute nel tempo, però a un certo punto, non dico in questa forma esatta, avrebbero dovuto fare qualcosa del genere. Questo è comunque
53:44tutto una grande premessa perché la nostra il nostro interesse finale è riuscire a comprendere e a implementare il protocollo DNS. [musica] เฮ [musica]