TCP/IP for MINIX, the good, the bad, the ugly
Oké, welkom. Egen eerder begon ik te schrijven een TCPRP-stak voor Minix. En dan was ik jong, dus ik dacht dat ik weet hoe ik alles beter zou doen. Dus ik deed veel verschillende dingen van de dan-current BSD-stak dat iedereen gebruikt. En wat ik nogal leuk vind en andere dingen die voelen dat het niet erg succesvol zou zijn. Dus dit talk gaat over veel verschillende topics en zie je dat er veel dingen zijn. Een soort van kaas van Minix en een van de dingen die ik met mezelf kwam in het stak. Dus, ik was af en toe met mijn master gedaan. Ik ging naar I&D Tannenbaum en zei dat ik een PSD-student zou willen zijn. En hij zei dat ik een volledig gedeelte zou gaan gaan. En dan gingen ze met andere mensen en zei dat ik echt willen zijn. En die PSD-student. Dus ik heb er wat te doen om hem te impressen. En een van de dingen die ik deed was een TCPRP-stak. En, wel, natuurlijk, Minix was gebruikt veel om te trainen. Dus er is een boek die beschrijft eigenlijk elke lijn van de source in Minix. En je kunt gewoon zeggen, oké, ik ben echt een volledig file-systeem. Om mevrouw te introduceren en dingen zoals dat. Dus het had moeten echt minimaal zijn. En dan, de makkelijkste manier om een netwerk in twee minuutjes te ontdekken, tijdens het minimaal te houden, was het eigenlijk te presenteren als een device-driver. En in Minix was er natuurlijk al een message-protocool om te praten met device-driveren die in de kernel waren. En dan, als je gewoon een separate task hebt, dan is dan de netwerking device-driver. Dat kan werken. En dus je krijgt, zonder de normaal socket-kouden, je krijgt open, closed, read, write en IO-control als basic primitives die je nodig hebt voor de accessing en de netwerking device. En dan, ik dacht, wel, zonder een volledig interne structuur waar allebei kouden, etc. Ik wil dezelfde structuur in dezelfde structuur houden, interne, zelfs, ik denk dat iedereen het zegt, je moet niet build, layered implementations, zelfs als de netwerkstak is layered. Ik had in de achterkant van mijn mind, misschien, als het echt succesvol is en je kunt een nieuw boek kunnen schrijven, en dan describeer deze sourcecode. En het probleem met IPS, is dat je moet werken echt hard om het te werken.  Er zijn alle soorten zonnele layering violations. Dus in dat sens, het is een goede exercice om je te volgen om echt een TCP-layer te hebben dat het kouden open, closed, etc. op een IP-layer en dan proberen we te formaliseren alle andere interacties. Maar het probleem was dat het een echt complex koude-backstructuur leidt omdat Minix niet met vreemd is. Dus je moet het als een grote state-machine schrijven en dat werd een mesh. En dan, een van de dingen die eerder op, ik weet het niet, en dat, wel, voor een lange tijd, veel mensen het niet weten, is dat als de netwerk is voel, dan moet je niet buffer pakken. Ik denk dat deze dagen het buffer bloot, maar op een gegeven moment heb ik gelijk, nou, als het TCP generert pakken en een IP probeert te passen op de internet-devijs en de internet-devijs is slecht, dan buffer je ze, ongeveer, maar je kunt ook niet dat doen maar gewoon zeggen, wel, er is geen ruimte voor pakken, nu gaan we weg en dan kun je een mooie non-blocking senden, dat simplifieert de koude veel en je krijgt hetzelfde voor het receive dus zonder reed, dan krijg je een koude-back en dan moet je een nieuwe reed doen. Je kunt ook zeggen, wel, geef mij een pakket en gebruik deze koude-back. Dat geeft een veel betere structuur, dus dat werkt wel goed nu. Een ander ding, dat was definitief BSD-inspired, is dat, op de tijd hadden we veel sendboxen die meer dan één interface had, want eigenlijk waren de routers slecht, netwerken slecht, als je een file-server had, had je twee netwerken, je file-server had twee interfaces om te zorgen dat ze op beide netwerken waren. Vergeet dat dan, en omdat van de loose multi-homing, je een applicatie zou hebben die een pakket over één netwerker zou krijgen en dan het weer over de andere senden, want, wel, wie wil waar het in en uit gaat. Dus ik wilde een heel klere separatie van alle interfaces en minix, in mijn stack, pakketten niet van één interface naar een andere, wanneer je dat explicitisch als routering define.  Maar er is één grote drawback, natuurlijk, omdat, voordat je om te bouwen om een star te bouwen en dan pakketten van welke interfaces je nu moet innumereren alle interfaces en dat doen, dat heeft een advantage dat je ook zo wilt, dat je deze service niet wil op die interface, omdat je dat niet doet. Maar dus, het is een mooie feature dat er ook in complicities is. Dan dit heeft mij echt in gevoel gekregen, omdat, omdat er niet een soort van multihoming was, je had de traditionele looppack-device kunnen niet hebben, maar pakketten zouden nooit daar gaan. Maar je moet nog steeds de looppack-IP-adress supporten. En voor IPv4, zeker in die dagen, was het niet echt belangrijk om multiple IP-adresses per interface te hebben, en het zou waarschijnlijk wel eens zijn. Dus ik kwam met een hek dat als je het pakketten probeert te senden en je het detecteert naar de looppack, dan schrijf je een source en een destination-adress en dan senden je het op de stack, want dan denk je dat ik met mijn lokale IP-adresses een remote is leuk, dat is looppack, maar wie wil dat? Het werkt wel, het is een soort van vergelijking. Hier was de vergelijking echt uit de hand en dit was wel als je een app die trafiek senden, dan senden je het op een default route of iets zoals dat. Dus je moet een simpel route voor dat, zeker als je multiple routes of directies of iets zoals dat hebt. En dan effectueel heb je 1 per interface, want al die interfaces zijn sterkte separaties. Maar als je het dan in een route maakt, dan heb je ook een route dat schrijft. Als een pakket komt uit interface A, dan waar zou je het gaan? In interface B, en ik maak dat sterkte separaties. Dat krijgt dan heel verkeerd, omdat het mogelijk is dat je een route is, maar dat jouw apparaat traft op een default route want deze eerste output van een route is een verschillende route dan jezelf. Dus zeker voor IPv6 probeer ik gewoon de RFC te volgen en niet meer te doen. Het andere, eigenlijk niemand begint het. Je geeft een route met minus i of minus o-optie en wat doet dat, niemand weet. Dit was een soort gecreëerd minix structuur.  Als je een accept system maakt, dan doe je een listen en een file descriptor en dan doe je accept op datzelfde file descriptor, maar je krijgt een nieuwe file descriptor terug. En er is echt geen manier om dat concept in minix te expressen, want de enige manier om een file descriptor te krijgen is te openen. Je kan niet alleen andere maanden maken die ook file descriptor terug geven. Dus ik bedoel, misschien we moeten niet accepten. Ik heb gewoon een listen geleerd en dat blok en dat wacht voor een connectie te komen en dan terugkomt de connectie. En dan begint het te spelen. Dat werkt goed. Je hebt jouw server en je vertelt dat op en je hebt een soort i-netd die een nieuwe tcp een nieuwe tcp file ook listen en etc. En dan krijg je webbrowsers en webbrowsers in parallel, gewoon 6 requesten of wat niet op dezelfde tijd. En dan, alle van hem, except de eerste, krijgt een reset terug. Dus dan zijn webbrowsers helemaal geconfused en ze zeggen, dit doet geen sens. Dus dan een makkelijke manier om geconfusing van je webbrowser is om de reset te dropen. Als je detecteert dat er connecties ontwikkeld zijn van listen maar gewoon niet op de reset die dan creëert het probleem dat, omdat het nu een dropt pakket is je krijgt een tijdout, die ook heel snel maakt. Dus, eigenlijk op een gegeven moment om het op te geven en dan kreeg ik een listen cue en dan de listen file, de scripter krijgt een cue van open tcp connecties want ik kan nog niet echt implementeren, maar ik kan doen iets met cookies waar je naar de listen file, de scripter zegt, geef me cookie voor een connectie en dan ga je naar een nieuw file, de scripter je zegt, hier is een cookie, ik wil een connectie en dan kan ik direct de connectie van een file, de scripter naar een ander en je hebt dezelfde effect. Dus, soms met de framework require wat extra creativiteit om het op te werken. Dus, dit is ook een groter gegeven als je een message passen doet en dan zie je nu ik moet doen, non-blocking IO en select, dan dan wordt het gewoon een grote mess.  Je moet zeggen, file system select dan moet het de operatie op de open file de scripters, en dan misschien 1 responsie. Maar als ze niet zijn, dan moeten alle van ze remember state dat als er op een moment iets gebeurt ze moeten terugkomen. Voor Minix 3 hebben we dat eigenlijk geïnplamend en ik denk dat het een volledig mess is. Maar als je A-sync in de IO dan wordt het rather easy want als je een normaal blocking is en je een message zet en in het geval van Minix moet je terugkomen, ik ben busy en dan later de device driver zegt, oké, ik heb iets gedaan.  Met A-sync in de IO senden we de operatie en dan vertel je de applicatie oké, gewoon continu en dan alleen de file system moet remember a table, dit zijn alle operaties die ik begon en dan op een moment de applicatie kan blocken en zeggen, geef me de status om een reply te hebben oh ja, hier is de resultat dus het probleem is natuurlijk niemand schrijft een code zoals dat dus als je iets wilt porten is het non-blocking IO en select en het probleem met non-blocking IO is dat wanneer je de non-blocking IO doet er is geen buffer in gebruikerspaas dat is locken, waardoor met A-sync in de IO je immiddels een buffer lockt in sommige cases heb ik dat ik nog niet denk zodat ik een reed op een buffer die op de stack was en dan natuurlijk stack frames gaan maar de A-sync in de IO-operatie is nog in probleem, dus op een moment dat is de stack dus porting dan betekent ook een complete non-blocking IO library in gebruikerspaas, wat ik deed wat werkt of rewrijd de voortbouw zodat het A-sync is soms is het makkelijk te doen, soms is het heel hard te doen hier zijn 2 examples van je moet gewoon echt niet doen, maar dus de eerste was nou een basic IP op en rond op een moment wil je ping hebben en je hebt bsd ping code en dat is allemaal soorten complicele dingen dus dat zal echt een lange tijd te porten, maar het is heel makkelijk om een programma te schrijven dat een icmp dan gaat een icmp terug en het zegt god, iets dus, ping was geboren en dan soms later voor minix vmd ik ported de bsd ping en ze dachten niet meer maar in minix 2 mijn originele ping leefde op en niemand wist dat dit echt een groot probleem was dus op een moment de VU, mensen weren wat probleem met de lab waar er minix vmd waren en het was een collectiviteit, etc. 