tcp.c 247 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. tcp.c
  5. Abstract:
  6. This module implements the Transmission Control Protocol.
  7. Author:
  8. Evan Green 10-Apr-2013
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. //
  16. // Protocol drivers are supposed to be able to stand on their own (ie be able to
  17. // be implemented outside the core net library). For the builtin ones, avoid
  18. // including netcore.h, but still redefine those functions that would otherwise
  19. // generate imports.
  20. //
  21. #define NET_API __DLLEXPORT
  22. #include <minoca/kernel/driver.h>
  23. #include <minoca/net/netdrv.h>
  24. #include <minoca/net/ip4.h>
  25. #include "tcp.h"
  26. //
  27. // ---------------------------------------------------------------- Definitions
  28. //
  29. #define TCP_TIMER_MAX_REFERENCE 0x10000000
  30. #define TCP_POLL_EVENT_IO \
  31. (POLL_EVENT_IN | POLL_EVENT_OUT | \
  32. POLL_EVENT_IN_HIGH_PRIORITY | POLL_EVENT_OUT_HIGH_PRIORITY)
  33. //
  34. // ------------------------------------------------------ Data Type Definitions
  35. //
  36. /*++
  37. Structure Description:
  38. This structure defines a TCP socket option.
  39. Members:
  40. InformationType - Stores the information type for the socket option.
  41. Option - Stores the type-specific option identifier.
  42. Size - Stores the size of the option value, in bytes.
  43. SetAllowed - Stores a boolean indicating whether or not the option is
  44. allowed to be set.
  45. --*/
  46. typedef struct _TCP_SOCKET_OPTION {
  47. SOCKET_INFORMATION_TYPE InformationType;
  48. UINTN Option;
  49. UINTN Size;
  50. BOOL SetAllowed;
  51. } TCP_SOCKET_OPTION, *PTCP_SOCKET_OPTION;
  52. //
  53. // ----------------------------------------------- Internal Function Prototypes
  54. //
  55. KSTATUS
  56. NetpTcpCreateSocket (
  57. PNET_PROTOCOL_ENTRY ProtocolEntry,
  58. PNET_NETWORK_ENTRY NetworkEntry,
  59. ULONG NetworkProtocol,
  60. PNET_SOCKET *NewSocket
  61. );
  62. VOID
  63. NetpTcpDestroySocket (
  64. PNET_SOCKET Socket
  65. );
  66. KSTATUS
  67. NetpTcpBindToAddress (
  68. PNET_SOCKET Socket,
  69. PNET_LINK Link,
  70. PNETWORK_ADDRESS Address
  71. );
  72. KSTATUS
  73. NetpTcpListen (
  74. PNET_SOCKET Socket
  75. );
  76. KSTATUS
  77. NetpTcpConnect (
  78. PNET_SOCKET Socket,
  79. PNETWORK_ADDRESS Address
  80. );
  81. KSTATUS
  82. NetpTcpAccept (
  83. PNET_SOCKET Socket,
  84. PIO_HANDLE *NewConnectionSocket,
  85. PNETWORK_ADDRESS RemoteAddress
  86. );
  87. KSTATUS
  88. NetpTcpClose (
  89. PNET_SOCKET Socket
  90. );
  91. KSTATUS
  92. NetpTcpShutdown (
  93. PNET_SOCKET Socket,
  94. ULONG ShutdownType
  95. );
  96. KSTATUS
  97. NetpTcpSend (
  98. BOOL FromKernelMode,
  99. PNET_SOCKET Socket,
  100. PSOCKET_IO_PARAMETERS Parameters,
  101. PIO_BUFFER IoBuffer
  102. );
  103. VOID
  104. NetpTcpProcessReceivedData (
  105. PNET_LINK Link,
  106. PNET_PACKET_BUFFER Packet,
  107. PNETWORK_ADDRESS SourceAddress,
  108. PNETWORK_ADDRESS DestinationAddress,
  109. PNET_PROTOCOL_ENTRY ProtocolEntry
  110. );
  111. KSTATUS
  112. NetpTcpProcessReceivedSocketData (
  113. PNET_LINK Link,
  114. PNET_SOCKET Socket,
  115. PNET_PACKET_BUFFER Packet,
  116. PNETWORK_ADDRESS SourceAddress,
  117. PNETWORK_ADDRESS DestinationAddress
  118. );
  119. KSTATUS
  120. NetpTcpReceive (
  121. BOOL FromKernelMode,
  122. PNET_SOCKET Socket,
  123. PSOCKET_IO_PARAMETERS Parameters,
  124. PIO_BUFFER IoBuffer
  125. );
  126. KSTATUS
  127. NetpTcpGetSetInformation (
  128. PNET_SOCKET Socket,
  129. SOCKET_INFORMATION_TYPE InformationType,
  130. UINTN SocketOption,
  131. PVOID Data,
  132. PUINTN DataSize,
  133. BOOL Set
  134. );
  135. KSTATUS
  136. NetpTcpUserControl (
  137. PNET_SOCKET Socket,
  138. ULONG CodeNumber,
  139. BOOL FromKernelMode,
  140. PVOID ContextBuffer,
  141. UINTN ContextBufferSize
  142. );
  143. VOID
  144. NetpTcpWorkerThread (
  145. PVOID Parameter
  146. );
  147. VOID
  148. NetpTcpProcessPacket (
  149. PTCP_SOCKET Socket,
  150. PNET_LINK Link,
  151. PTCP_HEADER Header,
  152. PNET_PACKET_BUFFER Packet,
  153. PNETWORK_ADDRESS SourceAddress,
  154. PNETWORK_ADDRESS DestinationAddress
  155. );
  156. VOID
  157. NetpTcpHandleUnconnectedPacket (
  158. PNET_LINK Link,
  159. PTCP_HEADER Header,
  160. PNET_PACKET_BUFFER Packet,
  161. PNETWORK_ADDRESS SourceAddress,
  162. PNETWORK_ADDRESS DestinationAddress
  163. );
  164. VOID
  165. NetpTcpFillOutHeader (
  166. PTCP_SOCKET Socket,
  167. PNET_PACKET_BUFFER Packet,
  168. ULONG SequenceNumber,
  169. USHORT ExtraFlags,
  170. ULONG OptionsLength,
  171. USHORT NonUrgentOffset,
  172. ULONG DataLength
  173. );
  174. USHORT
  175. NetpTcpChecksumData (
  176. PVOID Data,
  177. ULONG DataLength,
  178. PNETWORK_ADDRESS SourceAddress,
  179. PNETWORK_ADDRESS DestinationAddress
  180. );
  181. BOOL
  182. NetpTcpIsReceiveSegmentAcceptable (
  183. PTCP_SOCKET Socket,
  184. ULONG SequenceNumber,
  185. ULONG SegmentLength
  186. );
  187. KSTATUS
  188. NetpTcpProcessAcknowledge (
  189. PTCP_SOCKET Socket,
  190. ULONG AcknowledgeNumber,
  191. ULONG SequenceNumber,
  192. ULONG DataLength,
  193. USHORT WindowSize
  194. );
  195. VOID
  196. NetpTcpProcessPacketOptions (
  197. PTCP_SOCKET Socket,
  198. PTCP_HEADER Header,
  199. PNET_PACKET_BUFFER Packet
  200. );
  201. VOID
  202. NetpTcpSendControlPacket (
  203. PTCP_SOCKET Socket,
  204. ULONG Flags
  205. );
  206. VOID
  207. NetpTcpProcessReceivedDataSegment (
  208. PTCP_SOCKET Socket,
  209. ULONG SequenceNumber,
  210. PVOID Buffer,
  211. ULONG Length,
  212. PTCP_HEADER Header
  213. );
  214. KSTATUS
  215. NetpTcpInsertReceivedDataSegment (
  216. PTCP_SOCKET Socket,
  217. PTCP_RECEIVED_SEGMENT PreviousSegment,
  218. PTCP_RECEIVED_SEGMENT NextSegment,
  219. PTCP_HEADER Header,
  220. PVOID *Buffer,
  221. PULONG SequenceNumber,
  222. PULONG Length,
  223. PBOOL InsertedSegment
  224. );
  225. VOID
  226. NetpTcpSendPendingSegments (
  227. PTCP_SOCKET Socket,
  228. PULONGLONG CurrentTime
  229. );
  230. KSTATUS
  231. NetpTcpSendSegment (
  232. PTCP_SOCKET Socket,
  233. PTCP_SEND_SEGMENT Segment
  234. );
  235. PNET_PACKET_BUFFER
  236. NetpTcpCreatePacket (
  237. PTCP_SOCKET Socket,
  238. PTCP_SEND_SEGMENT Segment
  239. );
  240. VOID
  241. NetpTcpFreeSentSegments (
  242. PTCP_SOCKET Socket,
  243. PULONGLONG CurrentTime
  244. );
  245. VOID
  246. NetpTcpFreeSocketDataBuffers (
  247. PTCP_SOCKET Socket
  248. );
  249. VOID
  250. NetpTcpShutdownUnlocked (
  251. PTCP_SOCKET TcpSocket,
  252. ULONG ShutdownType
  253. );
  254. VOID
  255. NetpTcpShutdownTransmit (
  256. PTCP_SOCKET TcpSocket
  257. );
  258. VOID
  259. NetpTcpShutdownReceive (
  260. PTCP_SOCKET TcpSocket,
  261. PBOOL ResetSent
  262. );
  263. KSTATUS
  264. NetpTcpCloseOutSocket (
  265. PTCP_SOCKET Socket,
  266. BOOL InsideWorker
  267. );
  268. VOID
  269. NetpTcpHandleIncomingConnection (
  270. PTCP_SOCKET ListeningSocket,
  271. PTCP_HEADER Header,
  272. PNET_PACKET_BUFFER Packet,
  273. PNET_LINK Link,
  274. PNETWORK_ADDRESS LocalAddress,
  275. PNETWORK_ADDRESS RemoteAddress
  276. );
  277. VOID
  278. NetpTcpSetState (
  279. PTCP_SOCKET Socket,
  280. TCP_STATE NewState
  281. );
  282. KSTATUS
  283. NetpTcpSendSyn (
  284. PTCP_SOCKET Socket,
  285. BOOL WithAcknowledge
  286. );
  287. VOID
  288. NetpTcpTimerAddReference (
  289. VOID
  290. );
  291. ULONG
  292. NetpTcpTimerReleaseReference (
  293. VOID
  294. );
  295. VOID
  296. NetpTcpQueueTcpTimer (
  297. VOID
  298. );
  299. VOID
  300. NetpTcpArmKeepAliveTimer (
  301. ULONGLONG DueTime
  302. );
  303. KSTATUS
  304. NetpTcpReceiveOutOfBandData (
  305. BOOL FromKernelMode,
  306. PTCP_SOCKET TcpSocket,
  307. PSOCKET_IO_PARAMETERS Parameters,
  308. PIO_BUFFER IoBuffer
  309. );
  310. PTCP_SEGMENT_HEADER
  311. NetpTcpAllocateSegment (
  312. PTCP_SOCKET Socket,
  313. ULONG AllocationSize
  314. );
  315. VOID
  316. NetpTcpFreeSegment (
  317. PTCP_SOCKET Socket,
  318. PTCP_SEGMENT_HEADER Segment
  319. );
  320. //
  321. // -------------------------------------------------------------------- Globals
  322. //
  323. //
  324. // Store a pointer to the global TCP timer.
  325. //
  326. PKTIMER NetTcpTimer;
  327. ULONGLONG NetTcpTimerPeriod;
  328. volatile ULONG NetTcpTimerReferenceCount;
  329. //
  330. // Store a pointer to the global TCP keep alive timer.
  331. //
  332. PQUEUED_LOCK NetTcpKeepAliveTimerLock;
  333. PKTIMER NetTcpKeepAliveTimer;
  334. //
  335. // Store the global list of sockets.
  336. //
  337. LIST_ENTRY NetTcpSocketList;
  338. PQUEUED_LOCK NetTcpSocketListLock;
  339. //
  340. // Store the TCP debug flags, which print out a bunch more information.
  341. //
  342. BOOL NetTcpDebugPrintAllPackets = FALSE;
  343. BOOL NetTcpDebugPrintSequenceNumbers = FALSE;
  344. BOOL NetTcpDebugPrintCongestionControl = FALSE;
  345. //
  346. // This flag changes the behavior of the debug spew, turning on printing of
  347. // local addresses.
  348. //
  349. BOOL NetTcpDebugPrintLocalAddress = FALSE;
  350. NET_PROTOCOL_ENTRY NetTcpProtocol = {
  351. {NULL, NULL},
  352. NetSocketStream,
  353. SOCKET_INTERNET_PROTOCOL_TCP,
  354. NULL,
  355. NULL,
  356. {{0}, {0}, {0}},
  357. {
  358. NetpTcpCreateSocket,
  359. NetpTcpDestroySocket,
  360. NetpTcpBindToAddress,
  361. NetpTcpListen,
  362. NetpTcpAccept,
  363. NetpTcpConnect,
  364. NetpTcpClose,
  365. NetpTcpShutdown,
  366. NetpTcpSend,
  367. NetpTcpProcessReceivedData,
  368. NetpTcpProcessReceivedSocketData,
  369. NetpTcpReceive,
  370. NetpTcpGetSetInformation,
  371. NetpTcpUserControl
  372. }
  373. };
  374. TCP_SOCKET_OPTION NetTcpSocketOptions[] = {
  375. {
  376. SocketInformationBasic,
  377. SocketBasicOptionLinger,
  378. sizeof(SOCKET_LINGER),
  379. TRUE
  380. },
  381. {
  382. SocketInformationBasic,
  383. SocketBasicOptionSendBufferSize,
  384. sizeof(ULONG),
  385. TRUE
  386. },
  387. {
  388. SocketInformationBasic,
  389. SocketBasicOptionSendMinimum,
  390. sizeof(ULONG),
  391. FALSE
  392. },
  393. {
  394. SocketInformationBasic,
  395. SocketBasicOptionSendTimeout,
  396. sizeof(SOCKET_TIME),
  397. TRUE
  398. },
  399. {
  400. SocketInformationBasic,
  401. SocketBasicOptionReceiveBufferSize,
  402. sizeof(ULONG),
  403. TRUE
  404. },
  405. {
  406. SocketInformationBasic,
  407. SocketBasicOptionReceiveMinimum,
  408. sizeof(ULONG),
  409. TRUE
  410. },
  411. {
  412. SocketInformationBasic,
  413. SocketBasicOptionReceiveTimeout,
  414. sizeof(SOCKET_TIME),
  415. TRUE
  416. },
  417. {
  418. SocketInformationBasic,
  419. SocketBasicOptionAcceptConnections,
  420. sizeof(ULONG),
  421. FALSE
  422. },
  423. {
  424. SocketInformationBasic,
  425. SocketBasicOptionKeepAlive,
  426. sizeof(ULONG),
  427. TRUE
  428. },
  429. {
  430. SocketInformationBasic,
  431. SocketBasicOptionInlineOutOfBand,
  432. sizeof(ULONG),
  433. TRUE
  434. },
  435. {
  436. SocketInformationTcp,
  437. SocketTcpOptionNoDelay,
  438. sizeof(ULONG),
  439. TRUE
  440. },
  441. {
  442. SocketInformationTcp,
  443. SocketTcpOptionKeepAliveTimeout,
  444. sizeof(ULONG),
  445. TRUE
  446. },
  447. {
  448. SocketInformationTcp,
  449. SocketTcpOptionKeepAlivePeriod,
  450. sizeof(ULONG),
  451. TRUE
  452. },
  453. {
  454. SocketInformationTcp,
  455. SocketTcpOptionKeepAliveProbeLimit,
  456. sizeof(ULONG),
  457. TRUE
  458. },
  459. };
  460. //
  461. // ------------------------------------------------------------------ Functions
  462. //
  463. VOID
  464. NetpTcpInitialize (
  465. VOID
  466. )
  467. /*++
  468. Routine Description:
  469. This routine initializes support for TCP sockets.
  470. Arguments:
  471. None.
  472. Return Value:
  473. None.
  474. --*/
  475. {
  476. KSTATUS Status;
  477. //
  478. // Allow debugging to get more verbose, but leave it alone if some
  479. // developer has already turned it on.
  480. //
  481. if (NetTcpDebugPrintAllPackets == FALSE) {
  482. NetTcpDebugPrintAllPackets = NetGetGlobalDebugFlag();
  483. }
  484. if (NetTcpDebugPrintSequenceNumbers == FALSE) {
  485. NetTcpDebugPrintSequenceNumbers = NetGetGlobalDebugFlag();
  486. }
  487. INITIALIZE_LIST_HEAD(&NetTcpSocketList);
  488. //
  489. // Create the global periodic timer and list lock.
  490. //
  491. ASSERT(NetTcpSocketListLock == NULL);
  492. NetTcpSocketListLock = KeCreateQueuedLock();
  493. if (NetTcpSocketListLock == NULL) {
  494. Status = STATUS_INSUFFICIENT_RESOURCES;
  495. goto TcpInitializeEnd;
  496. }
  497. ASSERT(NetTcpTimer == NULL);
  498. NetTcpTimer = KeCreateTimer(TCP_ALLOCATION_TAG);
  499. if (NetTcpTimer == NULL) {
  500. Status = STATUS_INSUFFICIENT_RESOURCES;
  501. goto TcpInitializeEnd;
  502. }
  503. ASSERT(NetTcpKeepAliveTimerLock == NULL);
  504. NetTcpKeepAliveTimerLock = KeCreateQueuedLock();
  505. if (NetTcpKeepAliveTimerLock == NULL) {
  506. Status = STATUS_INSUFFICIENT_RESOURCES;
  507. goto TcpInitializeEnd;
  508. }
  509. NetTcpTimerPeriod = KeConvertMicrosecondsToTimeTicks(TCP_TIMER_PERIOD);
  510. ASSERT(NetTcpKeepAliveTimer == NULL);
  511. NetTcpKeepAliveTimer = KeCreateTimer(TCP_ALLOCATION_TAG);
  512. if (NetTcpKeepAliveTimer == NULL) {
  513. Status = STATUS_INSUFFICIENT_RESOURCES;
  514. goto TcpInitializeEnd;
  515. }
  516. //
  517. // Create the worker thread.
  518. //
  519. Status = PsCreateKernelThread(NetpTcpWorkerThread, NULL, "TcpWorkerThread");
  520. if (!KSUCCESS(Status)) {
  521. goto TcpInitializeEnd;
  522. }
  523. //
  524. // Register the TCP socket handlers with the core networking library.
  525. //
  526. Status = NetRegisterProtocol(&NetTcpProtocol, NULL);
  527. if (!KSUCCESS(Status)) {
  528. goto TcpInitializeEnd;
  529. }
  530. TcpInitializeEnd:
  531. if (!KSUCCESS(Status)) {
  532. ASSERT(FALSE);
  533. if (NetTcpSocketListLock != NULL) {
  534. KeDestroyQueuedLock(NetTcpSocketListLock);
  535. NetTcpSocketListLock = NULL;
  536. }
  537. if (NetTcpTimer != NULL) {
  538. KeDestroyTimer(NetTcpTimer);
  539. NetTcpTimer = NULL;
  540. }
  541. if (NetTcpKeepAliveTimerLock != NULL) {
  542. KeDestroyQueuedLock(NetTcpKeepAliveTimerLock);
  543. NetTcpKeepAliveTimerLock = NULL;
  544. }
  545. if (NetTcpKeepAliveTimer != NULL) {
  546. KeDestroyTimer(NetTcpKeepAliveTimer);
  547. NetTcpKeepAliveTimer = NULL;
  548. }
  549. }
  550. return;
  551. }
  552. KSTATUS
  553. NetpTcpCreateSocket (
  554. PNET_PROTOCOL_ENTRY ProtocolEntry,
  555. PNET_NETWORK_ENTRY NetworkEntry,
  556. ULONG NetworkProtocol,
  557. PNET_SOCKET *NewSocket
  558. )
  559. /*++
  560. Routine Description:
  561. This routine allocates resources associated with a new socket. The protocol
  562. driver is responsible for allocating the structure (with additional length
  563. for any of its context). The core networking library will fill in the
  564. common header when this routine returns.
  565. Arguments:
  566. ProtocolEntry - Supplies a pointer to the protocol information.
  567. NetworkEntry - Supplies a pointer to the network information.
  568. NetworkProtocol - Supplies the raw protocol value for this socket used on
  569. the network. This value is network specific.
  570. NewSocket - Supplies a pointer where a pointer to a newly allocated
  571. socket structure will be returned. The caller is responsible for
  572. allocating the socket (and potentially a larger structure for its own
  573. context). The core network library will fill in the standard socket
  574. structure after this routine returns.
  575. Return Value:
  576. Status code.
  577. --*/
  578. {
  579. PIO_OBJECT_STATE IoState;
  580. PNET_PACKET_SIZE_INFORMATION PacketSizeInformation;
  581. KSTATUS Status;
  582. PTCP_SOCKET TcpSocket;
  583. ASSERT(ProtocolEntry->Type == NetSocketStream);
  584. ASSERT((ProtocolEntry->ParentProtocolNumber ==
  585. SOCKET_INTERNET_PROTOCOL_TCP) &&
  586. (NetworkProtocol == ProtocolEntry->ParentProtocolNumber));
  587. IoState = NULL;
  588. TcpSocket = MmAllocatePagedPool(sizeof(TCP_SOCKET), TCP_ALLOCATION_TAG);
  589. if (TcpSocket == NULL) {
  590. Status = STATUS_INSUFFICIENT_RESOURCES;
  591. goto TcpCreateSocketEnd;
  592. }
  593. RtlZeroMemory(TcpSocket, sizeof(TCP_SOCKET));
  594. TcpSocket->NetSocket.KernelSocket.Protocol = NetworkProtocol;
  595. TcpSocket->NetSocket.KernelSocket.ReferenceCount = 1;
  596. INITIALIZE_LIST_HEAD(&(TcpSocket->ReceivedSegmentList));
  597. INITIALIZE_LIST_HEAD(&(TcpSocket->OutgoingSegmentList));
  598. INITIALIZE_LIST_HEAD(&(TcpSocket->FreeSegmentList));
  599. INITIALIZE_LIST_HEAD(&(TcpSocket->IncomingConnectionList));
  600. NetpTcpSetState(TcpSocket, TcpStateInitialized);
  601. TcpSocket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  602. TcpSocket->ReceiveWindowTotalSize = TCP_DEFAULT_WINDOW_SIZE;
  603. TcpSocket->ReceiveWindowFreeSize = TcpSocket->ReceiveWindowTotalSize;
  604. TcpSocket->ReceiveWindowScale = TCP_DEFAULT_WINDOW_SCALE;
  605. TcpSocket->ReceiveTimeout = WAIT_TIME_INDEFINITE;
  606. TcpSocket->ReceiveMinimum = TCP_DEFAULT_RECEIVE_MINIMUM;
  607. TcpSocket->SendBufferTotalSize = TCP_DEFAULT_SEND_BUFFER_SIZE;
  608. TcpSocket->SendBufferFreeSize = TcpSocket->SendBufferTotalSize;
  609. TcpSocket->SendInitialSequence = (ULONG)HlQueryTimeCounter();
  610. TcpSocket->SendUnacknowledgedSequence = TcpSocket->SendInitialSequence;
  611. TcpSocket->SendNextBufferSequence = TcpSocket->SendInitialSequence;
  612. TcpSocket->SendNextNetworkSequence = TcpSocket->SendInitialSequence;
  613. TcpSocket->SendTimeout = WAIT_TIME_INDEFINITE;
  614. TcpSocket->KeepAliveTimeout = TCP_DEFAULT_KEEP_ALIVE_TIMEOUT;
  615. TcpSocket->KeepAlivePeriod = TCP_DEFAULT_KEEP_ALIVE_PERIOD;
  616. TcpSocket->KeepAliveProbeLimit = TCP_DEFAULT_KEEP_ALIVE_PROBE_LIMIT;
  617. TcpSocket->OutOfBandData = -1;
  618. TcpSocket->Lock = KeCreateQueuedLock();
  619. if (TcpSocket->Lock == NULL) {
  620. Status = STATUS_INSUFFICIENT_RESOURCES;
  621. goto TcpCreateSocketEnd;
  622. }
  623. IoState = IoCreateIoObjectState(TRUE);
  624. if (IoState == NULL) {
  625. Status = STATUS_INSUFFICIENT_RESOURCES;
  626. goto TcpCreateSocketEnd;
  627. }
  628. ASSERT(TcpSocket->Flags == 0);
  629. NetpTcpCongestionInitializeSocket(TcpSocket);
  630. //
  631. // Start by assuming the remote supports the desired options.
  632. //
  633. TcpSocket->Flags |= TCP_SOCKET_FLAG_WINDOW_SCALING;
  634. //
  635. // Initialize the socket on the lower layers.
  636. //
  637. PacketSizeInformation = &(TcpSocket->NetSocket.PacketSizeInformation);
  638. PacketSizeInformation->MaxPacketSize = MAX_ULONG;
  639. Status = NetworkEntry->Interface.InitializeSocket(ProtocolEntry,
  640. NetworkEntry,
  641. NetworkProtocol,
  642. &(TcpSocket->NetSocket));
  643. if (!KSUCCESS(Status)) {
  644. goto TcpCreateSocketEnd;
  645. }
  646. //
  647. // TCP has no maximum packet limit as the header does not store a length.
  648. // The maximum packet size, calculated by the lower layers, should have
  649. // enough room for a TCP header and a one byte of data.
  650. //
  651. ASSERT((PacketSizeInformation->MaxPacketSize -
  652. PacketSizeInformation->HeaderSize -
  653. PacketSizeInformation->FooterSize) > sizeof(TCP_HEADER));
  654. //
  655. // Add the TCP header size to the protocol header size.
  656. //
  657. PacketSizeInformation->HeaderSize += sizeof(TCP_HEADER);
  658. ASSERT(TcpSocket->NetSocket.KernelSocket.IoState == NULL);
  659. TcpSocket->NetSocket.KernelSocket.IoState = IoState;
  660. KeAcquireQueuedLock(NetTcpSocketListLock);
  661. INSERT_BEFORE(&(TcpSocket->ListEntry), &NetTcpSocketList);
  662. KeReleaseQueuedLock(NetTcpSocketListLock);
  663. Status = STATUS_SUCCESS;
  664. TcpCreateSocketEnd:
  665. if (!KSUCCESS(Status)) {
  666. if (TcpSocket != NULL) {
  667. if (TcpSocket->Lock != NULL) {
  668. KeDestroyQueuedLock(TcpSocket->Lock);
  669. }
  670. MmFreePagedPool(TcpSocket);
  671. TcpSocket = NULL;
  672. }
  673. if (IoState != NULL) {
  674. IoDestroyIoObjectState(IoState);
  675. }
  676. }
  677. if (TcpSocket != NULL) {
  678. *NewSocket = &(TcpSocket->NetSocket);
  679. } else {
  680. *NewSocket = NULL;
  681. }
  682. return Status;
  683. }
  684. VOID
  685. NetpTcpDestroySocket (
  686. PNET_SOCKET Socket
  687. )
  688. /*++
  689. Routine Description:
  690. This routine destroys resources associated with an open socket, officially
  691. marking the end of the kernel and core networking library's knowledge of
  692. this structure.
  693. Arguments:
  694. Socket - Supplies a pointer to the socket to destroy. The core networking
  695. library will have already destroyed any resources inside the common
  696. header, the protocol should not reach through any pointers inside the
  697. socket header except the protocol and network entries.
  698. Return Value:
  699. None. This routine is responsible for freeing the memory associated with
  700. the socket structure itself.
  701. --*/
  702. {
  703. PTCP_SOCKET TcpSocket;
  704. TcpSocket = (PTCP_SOCKET)Socket;
  705. ASSERT(TcpSocket->State == TcpStateClosed);
  706. ASSERT(TcpSocket->ListEntry.Next == NULL);
  707. ASSERT(LIST_EMPTY(&(TcpSocket->ReceivedSegmentList)) != FALSE);
  708. ASSERT(LIST_EMPTY(&(TcpSocket->OutgoingSegmentList)) != FALSE);
  709. KeDestroyQueuedLock(TcpSocket->Lock);
  710. TcpSocket->Lock = NULL;
  711. TcpSocket->State = TcpStateInvalid;
  712. MmFreePagedPool(TcpSocket);
  713. return;
  714. }
  715. KSTATUS
  716. NetpTcpBindToAddress (
  717. PNET_SOCKET Socket,
  718. PNET_LINK Link,
  719. PNETWORK_ADDRESS Address
  720. )
  721. /*++
  722. Routine Description:
  723. This routine binds the given socket to the specified network address.
  724. Usually this is a no-op for the protocol, it's simply responsible for
  725. passing the request down to the network layer.
  726. Arguments:
  727. Socket - Supplies a pointer to the socket to bind.
  728. Link - Supplies an optional pointer to a link to bind to.
  729. Address - Supplies a pointer to the address to bind the socket to.
  730. Return Value:
  731. Status code.
  732. --*/
  733. {
  734. KSTATUS Status;
  735. //
  736. // Currently only IPv4 addresses are supported.
  737. //
  738. if (Address->Domain != NetDomainIp4) {
  739. Status = STATUS_NOT_SUPPORTED;
  740. goto TcpBindToAddressEnd;
  741. }
  742. //
  743. // Pass the request down to the network layer.
  744. //
  745. Status = Socket->Network->Interface.BindToAddress(Socket, Link, Address);
  746. if (!KSUCCESS(Status)) {
  747. goto TcpBindToAddressEnd;
  748. }
  749. TcpBindToAddressEnd:
  750. return Status;
  751. }
  752. KSTATUS
  753. NetpTcpListen (
  754. PNET_SOCKET Socket
  755. )
  756. /*++
  757. Routine Description:
  758. This routine adds a bound socket to the list of listening sockets,
  759. officially allowing clients to attempt to connect to it.
  760. Arguments:
  761. Socket - Supplies a pointer to the socket to mark as listning.
  762. Return Value:
  763. Status code.
  764. --*/
  765. {
  766. KSTATUS Status;
  767. PTCP_SOCKET TcpSocket;
  768. TcpSocket = (PTCP_SOCKET)Socket;
  769. KeAcquireQueuedLock(TcpSocket->Lock);
  770. ASSERT(TcpSocket->NetSocket.BindingType != SocketBindingInvalid);
  771. Status = STATUS_SUCCESS;
  772. if (TcpSocket->State != TcpStateListening) {
  773. if (TcpSocket->State != TcpStateInitialized) {
  774. Status = STATUS_INVALID_PARAMETER;
  775. goto TcpListenEnd;
  776. }
  777. NetpTcpSetState(TcpSocket, TcpStateListening);
  778. //
  779. // Begin listening for incoming connection requests.
  780. //
  781. Status = Socket->Network->Interface.Listen(Socket);
  782. if (!KSUCCESS(Status)) {
  783. goto TcpListenEnd;
  784. }
  785. }
  786. TcpListenEnd:
  787. KeReleaseQueuedLock(TcpSocket->Lock);
  788. return Status;
  789. }
  790. KSTATUS
  791. NetpTcpAccept (
  792. PNET_SOCKET Socket,
  793. PIO_HANDLE *NewConnectionSocket,
  794. PNETWORK_ADDRESS RemoteAddress
  795. )
  796. /*++
  797. Routine Description:
  798. This routine accepts an incoming connection on a listening connection-based
  799. socket.
  800. Arguments:
  801. Socket - Supplies a pointer to the socket to accept a connection from.
  802. NewConnectionSocket - Supplies a pointer where a new socket will be
  803. returned that represents the accepted connection with the remote
  804. host.
  805. RemoteAddress - Supplies a pointer where the address of the connected
  806. remote host will be returned.
  807. Return Value:
  808. Status code.
  809. --*/
  810. {
  811. PTCP_INCOMING_CONNECTION IncomingConnection;
  812. PIO_OBJECT_STATE IoState;
  813. PIO_HANDLE NewHandle;
  814. PTCP_SOCKET NewTcpSocket;
  815. ULONG OpenFlags;
  816. ULONG ReturnedEvents;
  817. KSTATUS Status;
  818. PTCP_SOCKET TcpSocket;
  819. ULONG Timeout;
  820. TcpSocket = (PTCP_SOCKET)Socket;
  821. //
  822. // The socket has to be listening first in order to accept connections.
  823. //
  824. if (TcpSocket->State != TcpStateListening) {
  825. NewHandle = NULL;
  826. Status = STATUS_INVALID_PARAMETER;
  827. goto TcpAcceptEnd;
  828. }
  829. Timeout = WAIT_TIME_INDEFINITE;
  830. OpenFlags = IoGetIoHandleOpenFlags(Socket->KernelSocket.IoHandle);
  831. if ((OpenFlags & OPEN_FLAG_NON_BLOCKING) != 0) {
  832. Timeout = 0;
  833. }
  834. //
  835. // Loop trying to get a solid established connection.
  836. //
  837. while (TRUE) {
  838. IncomingConnection = NULL;
  839. NewHandle = NULL;
  840. NewTcpSocket = NULL;
  841. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  842. //
  843. // Loop competing with other accepts trying to get an incoming
  844. // connection structure.
  845. //
  846. while (TRUE) {
  847. Status = IoWaitForIoObjectState(IoState,
  848. POLL_EVENT_IN,
  849. TRUE,
  850. Timeout,
  851. &ReturnedEvents);
  852. if (!KSUCCESS(Status)) {
  853. if (Status == STATUS_TIMEOUT) {
  854. Status = STATUS_OPERATION_WOULD_BLOCK;
  855. }
  856. goto TcpAcceptEnd;
  857. }
  858. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  859. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  860. Status = STATUS_NO_NETWORK_CONNECTION;
  861. } else {
  862. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  863. if (KSUCCESS(Status)) {
  864. Status = STATUS_DEVICE_IO_ERROR;
  865. }
  866. }
  867. goto TcpAcceptEnd;
  868. }
  869. KeAcquireQueuedLock(TcpSocket->Lock);
  870. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0) {
  871. KeReleaseQueuedLock(TcpSocket->Lock);
  872. Status = STATUS_CONNECTION_CLOSED;
  873. goto TcpAcceptEnd;
  874. }
  875. if (TcpSocket->IncomingConnectionCount != 0) {
  876. ASSERT(LIST_EMPTY(&(TcpSocket->IncomingConnectionList)) ==
  877. FALSE);
  878. IncomingConnection =
  879. LIST_VALUE(TcpSocket->IncomingConnectionList.Next,
  880. TCP_INCOMING_CONNECTION,
  881. ListEntry);
  882. LIST_REMOVE(&(IncomingConnection->ListEntry));
  883. TcpSocket->IncomingConnectionCount -= 1;
  884. }
  885. if (TcpSocket->IncomingConnectionCount == 0) {
  886. //
  887. // If the incoming connection count is zero, then there should
  888. // be nothing on that list.
  889. //
  890. ASSERT(LIST_EMPTY(&(TcpSocket->IncomingConnectionList)) !=
  891. FALSE);
  892. IoSetIoObjectState(IoState, POLL_EVENT_IN, FALSE);
  893. }
  894. KeReleaseQueuedLock(TcpSocket->Lock);
  895. if (IncomingConnection != NULL) {
  896. NewHandle = IncomingConnection->IoHandle;
  897. MmFreePagedPool(IncomingConnection);
  898. Status = STATUS_SUCCESS;
  899. break;
  900. }
  901. }
  902. ASSERT(NewHandle != NULL);
  903. Status = IoGetSocketFromHandle(NewHandle, (PVOID)&NewTcpSocket);
  904. if (!KSUCCESS(Status)) {
  905. goto TcpAcceptEnd;
  906. }
  907. //
  908. // Wait indefinitely for the connection to be established. If there is
  909. // any error (including timeouts), the new socket will be closed.
  910. //
  911. IoState = NewTcpSocket->NetSocket.KernelSocket.IoState;
  912. Status = IoWaitForIoObjectState(IoState,
  913. POLL_EVENT_OUT,
  914. TRUE,
  915. WAIT_TIME_INDEFINITE,
  916. &ReturnedEvents);
  917. if (!KSUCCESS(Status)) {
  918. goto TcpAcceptEnd;
  919. }
  920. //
  921. // If there were no errors and the socket is in an expected state,
  922. // then successfully return.
  923. //
  924. if ((ReturnedEvents & POLL_ERROR_EVENTS) == 0) {
  925. if ((NewTcpSocket->State == TcpStateEstablished) ||
  926. (NewTcpSocket->State == TcpStateCloseWait)) {
  927. if (RemoteAddress != NULL) {
  928. RtlCopyMemory(RemoteAddress,
  929. &(NewTcpSocket->NetSocket.RemoteAddress),
  930. sizeof(NETWORK_ADDRESS));
  931. }
  932. break;
  933. }
  934. //
  935. // If there were errors, then only quit the accept if the network
  936. // was disconnected. Otherwise try to get another connection.
  937. //
  938. } else {
  939. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  940. Status = STATUS_NO_NETWORK_CONNECTION;
  941. break;
  942. }
  943. }
  944. //
  945. // Destroy the new socket before trying to get another connection.
  946. //
  947. IoClose(NewHandle);
  948. }
  949. TcpAcceptEnd:
  950. if (!KSUCCESS(Status)) {
  951. if (NewHandle != NULL) {
  952. IoClose(NewHandle);
  953. NewHandle = NULL;
  954. }
  955. }
  956. *NewConnectionSocket = NewHandle;
  957. return Status;
  958. }
  959. KSTATUS
  960. NetpTcpConnect (
  961. PNET_SOCKET Socket,
  962. PNETWORK_ADDRESS Address
  963. )
  964. /*++
  965. Routine Description:
  966. This routine attempts to make an outgoing connection to a server.
  967. Arguments:
  968. Socket - Supplies a pointer to the socket to use for the connection.
  969. Address - Supplies a pointer to the address to connect to.
  970. Return Value:
  971. Status code.
  972. --*/
  973. {
  974. BOOL Connected;
  975. BOOL LockHeld;
  976. ULONG ReturnedEvents;
  977. KSTATUS Status;
  978. PTCP_SOCKET TcpSocket;
  979. Connected = FALSE;
  980. TcpSocket = (PTCP_SOCKET)Socket;
  981. KeAcquireQueuedLock(TcpSocket->Lock);
  982. LockHeld = TRUE;
  983. if (TcpSocket->State != TcpStateInitialized) {
  984. if ((TcpSocket->State == TcpStateSynSent) ||
  985. (TcpSocket->State == TcpStateSynReceived)) {
  986. Status = STATUS_ALREADY_INITIALIZED;
  987. } else {
  988. Status = STATUS_CONNECTION_EXISTS;
  989. }
  990. goto TcpConnectEnd;
  991. }
  992. //
  993. // Pass the request down to the network layer.
  994. //
  995. Status = Socket->Network->Interface.Connect(Socket, Address);
  996. if (!KSUCCESS(Status)) {
  997. goto TcpConnectEnd;
  998. }
  999. Connected = TRUE;
  1000. //
  1001. // Put the socket in the SYN sent state. This will fire off a SYN.
  1002. //
  1003. NetpTcpSetState(TcpSocket, TcpStateSynSent);
  1004. KeReleaseQueuedLock(TcpSocket->Lock);
  1005. LockHeld = FALSE;
  1006. //
  1007. // Wait indefinitely for the connection to be established. The internal
  1008. // SYN retry mechanisms will timeout and signal the events if the other
  1009. // side isn't there.
  1010. //
  1011. Status = IoWaitForIoObjectState(Socket->KernelSocket.IoState,
  1012. POLL_EVENT_OUT,
  1013. TRUE,
  1014. WAIT_TIME_INDEFINITE,
  1015. &ReturnedEvents);
  1016. if (!KSUCCESS(Status)) {
  1017. goto TcpConnectEnd;
  1018. }
  1019. //
  1020. // An event was signalled. If it was an error, then plan to fail the
  1021. // connect.
  1022. //
  1023. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1024. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1025. Status = STATUS_NO_NETWORK_CONNECTION;
  1026. } else {
  1027. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  1028. if (KSUCCESS(Status)) {
  1029. Status = STATUS_DEVICE_IO_ERROR;
  1030. }
  1031. }
  1032. //
  1033. // If there was not an error then the connection should either be
  1034. // established or in the close-wait state (the remote side may have
  1035. // quickly sent a SYN and then a FIN).
  1036. //
  1037. } else if ((TcpSocket->State != TcpStateEstablished) &&
  1038. (TcpSocket->State != TcpStateCloseWait)) {
  1039. Status = STATUS_CONNECTION_RESET;
  1040. }
  1041. TcpConnectEnd:
  1042. //
  1043. // If the connect was attempted but failed for a reason other than a
  1044. // timeout or that the wait was interrupted, stop the socket in its tracks.
  1045. // When interrupted, the connect is meant to continue in the background. On
  1046. // timeout, the mechanism that determined the timeout handled the
  1047. // appropriate clean up of the socket (i.e. disconnect and reinitialize).
  1048. //
  1049. if (!KSUCCESS(Status) && (Connected != FALSE)) {
  1050. if ((Status != STATUS_INTERRUPTED) && (Status != STATUS_TIMEOUT)) {
  1051. if (LockHeld == FALSE) {
  1052. KeAcquireQueuedLock(TcpSocket->Lock);
  1053. LockHeld = TRUE;
  1054. }
  1055. NetpTcpCloseOutSocket(TcpSocket, FALSE);
  1056. }
  1057. }
  1058. if (LockHeld != FALSE) {
  1059. KeReleaseQueuedLock(TcpSocket->Lock);
  1060. }
  1061. return Status;
  1062. }
  1063. KSTATUS
  1064. NetpTcpClose (
  1065. PNET_SOCKET Socket
  1066. )
  1067. /*++
  1068. Routine Description:
  1069. This routine closes a socket connection.
  1070. Arguments:
  1071. Socket - Supplies a pointer to the socket to shut down.
  1072. Return Value:
  1073. Status code.
  1074. --*/
  1075. {
  1076. BOOL CloseOutSocket;
  1077. PIO_OBJECT_STATE IoState;
  1078. KSTATUS Status;
  1079. PTCP_SOCKET TcpSocket;
  1080. CloseOutSocket = FALSE;
  1081. Status = STATUS_SUCCESS;
  1082. TcpSocket = (PTCP_SOCKET)Socket;
  1083. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  1084. RtlAtomicOr32(&(TcpSocket->ShutdownTypes),
  1085. SOCKET_SHUTDOWN_READ | SOCKET_SHUTDOWN_WRITE);
  1086. KeAcquireQueuedLock(TcpSocket->Lock);
  1087. switch (TcpSocket->State) {
  1088. case TcpStateInitialized:
  1089. case TcpStateClosed:
  1090. CloseOutSocket = TRUE;
  1091. break;
  1092. //
  1093. // When awaiting a FIN, if this side is about to drop some received
  1094. // packets due to this close, a RST should be sent.
  1095. //
  1096. case TcpStateFinWait1:
  1097. case TcpStateFinWait2:
  1098. NetpTcpShutdownUnlocked(TcpSocket, TcpSocket->ShutdownTypes);
  1099. break;
  1100. //
  1101. // For many states, do nothing.
  1102. //
  1103. case TcpStateClosing:
  1104. case TcpStateLastAcknowledge:
  1105. case TcpStateTimeWait:
  1106. break;
  1107. //
  1108. // For the Listening and Syn-Sent states, clean up the socket straight
  1109. // away.
  1110. //
  1111. case TcpStateListening:
  1112. case TcpStateSynSent:
  1113. CloseOutSocket = TRUE;
  1114. break;
  1115. //
  1116. // In the states with active connections, send a FIN segment (or at
  1117. // least queue that one needs to be sent. If, however, this side has not
  1118. // read everything it received, skip the FIN and just send a RST.
  1119. //
  1120. case TcpStateSynReceived:
  1121. case TcpStateEstablished:
  1122. case TcpStateCloseWait:
  1123. NetpTcpShutdownUnlocked(TcpSocket, TcpSocket->ShutdownTypes);
  1124. break;
  1125. default:
  1126. ASSERT(FALSE);
  1127. return STATUS_INVALID_CONFIGURATION;
  1128. }
  1129. //
  1130. // Potentially destroy the socket right now.
  1131. //
  1132. if (CloseOutSocket != FALSE) {
  1133. Status = NetpTcpCloseOutSocket(TcpSocket, FALSE);
  1134. ASSERT(TcpSocket->NetSocket.KernelSocket.ReferenceCount >= 1);
  1135. KeReleaseQueuedLock(TcpSocket->Lock);
  1136. } else {
  1137. //
  1138. // Handle the socket lingering option if it is enabled.
  1139. //
  1140. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_LINGER_ENABLED) != 0) {
  1141. //
  1142. // If the linger timeout is set to zero, then perform an abortive
  1143. // close by reseting and then closing.
  1144. //
  1145. if (TcpSocket->LingerTimeout == 0) {
  1146. NetpTcpSendControlPacket(TcpSocket, TCP_HEADER_FLAG_RESET);
  1147. TcpSocket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  1148. Status = NetpTcpCloseOutSocket(TcpSocket, FALSE);
  1149. KeReleaseQueuedLock(TcpSocket->Lock);
  1150. //
  1151. // Otherwise wait for the linger timeout.
  1152. //
  1153. } else {
  1154. KeReleaseQueuedLock(TcpSocket->Lock);
  1155. Status = IoWaitForIoObjectState(IoState,
  1156. POLL_EVENT_OUT,
  1157. TRUE,
  1158. TcpSocket->LingerTimeout,
  1159. NULL);
  1160. //
  1161. // If the wait failed or the error event was signaled, rather
  1162. // than the out event, then the socket needs to be abortively
  1163. // closed if it isn't already.
  1164. //
  1165. if (!KSUCCESS(Status) ||
  1166. ((IoState->Events & POLL_ERROR_EVENTS) != 0)) {
  1167. KeAcquireQueuedLock(TcpSocket->Lock);
  1168. if (TcpSocket->State != TcpStateClosed) {
  1169. NetpTcpSendControlPacket(TcpSocket,
  1170. TCP_HEADER_FLAG_RESET);
  1171. TcpSocket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  1172. Status = NetpTcpCloseOutSocket(TcpSocket, FALSE);
  1173. }
  1174. KeReleaseQueuedLock(TcpSocket->Lock);
  1175. }
  1176. }
  1177. //
  1178. // Otherwise just release the lock and let the close continue on.
  1179. //
  1180. } else {
  1181. KeReleaseQueuedLock(TcpSocket->Lock);
  1182. }
  1183. }
  1184. return Status;
  1185. }
  1186. KSTATUS
  1187. NetpTcpShutdown (
  1188. PNET_SOCKET Socket,
  1189. ULONG ShutdownType
  1190. )
  1191. /*++
  1192. Routine Description:
  1193. This routine shuts down communication with a given socket.
  1194. Arguments:
  1195. Socket - Supplies a pointer to the socket.
  1196. ShutdownType - Supplies the shutdown type to perform. See the
  1197. SOCKET_SHUTDOWN_* definitions.
  1198. Return Value:
  1199. Status code.
  1200. --*/
  1201. {
  1202. PTCP_SOCKET TcpSocket;
  1203. //
  1204. // Shutdown is not supported unless the socket is connected.
  1205. //
  1206. if (Socket->RemoteAddress.Domain == NetDomainInvalid) {
  1207. return STATUS_NOT_CONNECTED;
  1208. }
  1209. TcpSocket = (PTCP_SOCKET)Socket;
  1210. RtlAtomicOr32(&(TcpSocket->ShutdownTypes), ShutdownType);
  1211. //
  1212. // As long as a shutdown type was provided, take action unless only read is
  1213. // meant to be shut down. Shutting down read may result in a RST if not
  1214. // all the data in the socket's receive list has been read, but the caller
  1215. // may still want to write.
  1216. //
  1217. if ((ShutdownType != 0) && (ShutdownType != SOCKET_SHUTDOWN_READ)) {
  1218. KeAcquireQueuedLock(TcpSocket->Lock);
  1219. NetpTcpShutdownUnlocked(TcpSocket, ShutdownType);
  1220. KeReleaseQueuedLock(TcpSocket->Lock);
  1221. }
  1222. return STATUS_SUCCESS;
  1223. }
  1224. KSTATUS
  1225. NetpTcpSend (
  1226. BOOL FromKernelMode,
  1227. PNET_SOCKET Socket,
  1228. PSOCKET_IO_PARAMETERS Parameters,
  1229. PIO_BUFFER IoBuffer
  1230. )
  1231. /*++
  1232. Routine Description:
  1233. This routine sends the given data buffer through the network using a
  1234. specific protocol.
  1235. Arguments:
  1236. FromKernelMode - Supplies a boolean indicating whether the request is
  1237. coming from kernel mode (TRUE) or user mode (FALSE).
  1238. Socket - Supplies a pointer to the socket to send the data to.
  1239. Parameters - Supplies a pointer to the socket I/O parameters. This will
  1240. always be a kernel mode pointer.
  1241. IoBuffer - Supplies a pointer to the I/O buffer containing the data to
  1242. send.
  1243. Return Value:
  1244. Status code.
  1245. --*/
  1246. {
  1247. ULONG AllocationSize;
  1248. ULONG AvailableSize;
  1249. UINTN BytesComplete;
  1250. ULONGLONG CurrentTime;
  1251. ULONGLONG EndTime;
  1252. ULONG Flags;
  1253. PIO_OBJECT_STATE IoState;
  1254. PTCP_SEND_SEGMENT LastSegment;
  1255. ULONG LastSegmentLength;
  1256. BOOL LockHeld;
  1257. PTCP_SEND_SEGMENT NewSegment;
  1258. BOOL OutgoingSegmentListWasEmpty;
  1259. BOOL PushNeeded;
  1260. ULONG RequiredOpening;
  1261. ULONG ReturnedEvents;
  1262. ULONG SegmentSize;
  1263. UINTN Size;
  1264. KSTATUS Status;
  1265. PTCP_SOCKET TcpSocket;
  1266. ULONGLONG TimeCounterFrequency;
  1267. ULONG Timeout;
  1268. ULONG WaitTime;
  1269. BytesComplete = 0;
  1270. EndTime = 0;
  1271. Flags = Parameters->SocketIoFlags;
  1272. Parameters->SocketIoFlags = 0;
  1273. LockHeld = FALSE;
  1274. NewSegment = NULL;
  1275. OutgoingSegmentListWasEmpty = FALSE;
  1276. PushNeeded = TRUE;
  1277. TcpSocket = (PTCP_SOCKET)Socket;
  1278. TimeCounterFrequency = 0;
  1279. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  1280. if (TcpSocket->State < TcpStateEstablished) {
  1281. Status = STATUS_BROKEN_PIPE;
  1282. goto TcpSendEnd;
  1283. }
  1284. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_WRITE) != 0) {
  1285. Status = STATUS_BROKEN_PIPE;
  1286. goto TcpSendEnd;
  1287. }
  1288. if ((TcpSocket->State != TcpStateEstablished) &&
  1289. (TcpSocket->State != TcpStateCloseWait)) {
  1290. Status = STATUS_BROKEN_PIPE;
  1291. goto TcpSendEnd;
  1292. }
  1293. //
  1294. // Fail if there's ancillary data.
  1295. //
  1296. if (Parameters->ControlDataSize != 0) {
  1297. Status = STATUS_NOT_SUPPORTED;
  1298. goto TcpSendEnd;
  1299. }
  1300. Size = Parameters->Size;
  1301. if (Size == 0) {
  1302. Status = STATUS_SUCCESS;
  1303. goto TcpSendEnd;
  1304. }
  1305. //
  1306. // Set a timeout timer to give up on. The socket stores the maximum timeout.
  1307. //
  1308. Timeout = Parameters->TimeoutInMilliseconds;
  1309. if (Timeout > TcpSocket->SendTimeout) {
  1310. Timeout = TcpSocket->SendTimeout;
  1311. }
  1312. if ((Timeout != 0) && (Timeout != WAIT_TIME_INDEFINITE)) {
  1313. EndTime = KeGetRecentTimeCounter();
  1314. EndTime += KeConvertMicrosecondsToTimeTicks(
  1315. Timeout * MICROSECONDS_PER_MILLISECOND);
  1316. TimeCounterFrequency = HlQueryTimeCounterFrequency();
  1317. }
  1318. //
  1319. // First look to see if this data can be at least partially glommed on to
  1320. // the last packet.
  1321. //
  1322. while (TRUE) {
  1323. if (Timeout == 0) {
  1324. WaitTime = 0;
  1325. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  1326. CurrentTime = KeGetRecentTimeCounter();
  1327. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  1328. TimeCounterFrequency;
  1329. } else {
  1330. WaitTime = WAIT_TIME_INDEFINITE;
  1331. }
  1332. Status = IoWaitForIoObjectState(IoState,
  1333. POLL_EVENT_OUT,
  1334. TRUE,
  1335. WaitTime,
  1336. &ReturnedEvents);
  1337. if (!KSUCCESS(Status)) {
  1338. if ((Status == STATUS_TIMEOUT) && (Timeout == 0)) {
  1339. Status = STATUS_OPERATION_WOULD_BLOCK;
  1340. }
  1341. goto TcpSendEnd;
  1342. }
  1343. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1344. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1345. Status = STATUS_NO_NETWORK_CONNECTION;
  1346. } else {
  1347. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  1348. if (KSUCCESS(Status)) {
  1349. Status = STATUS_DEVICE_IO_ERROR;
  1350. }
  1351. }
  1352. goto TcpSendEnd;
  1353. }
  1354. KeAcquireQueuedLock(TcpSocket->Lock);
  1355. LockHeld = TRUE;
  1356. //
  1357. // If the user called shutdown and is now trying to write, that's a
  1358. // dufus maneuver.
  1359. //
  1360. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_WRITE) != 0) {
  1361. Status = STATUS_BROKEN_PIPE;
  1362. goto TcpSendEnd;
  1363. }
  1364. //
  1365. // Watch out for the connection shutting down.
  1366. //
  1367. if ((TcpSocket->State != TcpStateEstablished) &&
  1368. (TcpSocket->State != TcpStateCloseWait)) {
  1369. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_CONNECTION_RESET) != 0) {
  1370. Status = STATUS_CONNECTION_RESET;
  1371. } else {
  1372. Status = STATUS_BROKEN_PIPE;
  1373. }
  1374. goto TcpSendEnd;
  1375. }
  1376. if (TcpSocket->SendBufferFreeSize == 0) {
  1377. IoSetIoObjectState(IoState, POLL_EVENT_OUT, FALSE);
  1378. KeReleaseQueuedLock(TcpSocket->Lock);
  1379. LockHeld = FALSE;
  1380. NetpTcpSendPendingSegments(TcpSocket, NULL);
  1381. continue;
  1382. }
  1383. //
  1384. // If the list of things to send is empty, a new packet will definitely
  1385. // need to be created.
  1386. //
  1387. if (LIST_EMPTY(&(TcpSocket->OutgoingSegmentList)) != FALSE) {
  1388. break;
  1389. }
  1390. //
  1391. // If the last packet has already been sent off or is jam packed, then
  1392. // forget it, make a new packet.
  1393. //
  1394. LastSegment = LIST_VALUE(TcpSocket->OutgoingSegmentList.Previous,
  1395. TCP_SEND_SEGMENT,
  1396. Header.ListEntry);
  1397. LastSegmentLength = LastSegment->Length - LastSegment->Offset;
  1398. if ((LastSegment->SendAttemptCount != 0) ||
  1399. (LastSegmentLength == TcpSocket->SendMaxSegmentSize)) {
  1400. break;
  1401. }
  1402. //
  1403. // Create a new segment to replace this last one. This size starts out
  1404. // at the maximum segment size, and is taken down by the actual size
  1405. // of the data, as well as the size of the send buffer.
  1406. //
  1407. SegmentSize = TcpSocket->SendMaxSegmentSize;
  1408. if (SegmentSize > (LastSegmentLength + Size)) {
  1409. SegmentSize = LastSegmentLength + Size;
  1410. }
  1411. AvailableSize = TcpSocket->SendBufferFreeSize + LastSegmentLength;
  1412. if (SegmentSize > AvailableSize) {
  1413. SegmentSize = AvailableSize;
  1414. }
  1415. AllocationSize = sizeof(TCP_SEND_SEGMENT) + SegmentSize;
  1416. NewSegment = (PTCP_SEND_SEGMENT)NetpTcpAllocateSegment(TcpSocket,
  1417. AllocationSize);
  1418. if (NewSegment == NULL) {
  1419. Status = STATUS_INSUFFICIENT_RESOURCES;
  1420. goto TcpSendEnd;
  1421. }
  1422. //
  1423. // Copy the old last segment plus part of the new data.
  1424. //
  1425. RtlCopyMemory(NewSegment + 1,
  1426. (PUCHAR)(LastSegment + 1) + LastSegment->Offset,
  1427. LastSegmentLength);
  1428. Status = MmCopyIoBufferData(
  1429. IoBuffer,
  1430. (PUCHAR)(NewSegment + 1) + LastSegmentLength,
  1431. BytesComplete,
  1432. SegmentSize - LastSegmentLength,
  1433. FALSE);
  1434. if (!KSUCCESS(Status)) {
  1435. NetpTcpFreeSegment(TcpSocket, (PTCP_SEGMENT_HEADER)NewSegment);
  1436. goto TcpSendEnd;
  1437. }
  1438. NewSegment->SequenceNumber = LastSegment->SequenceNumber +
  1439. LastSegment->Offset;
  1440. NewSegment->LastSendTime = 0;
  1441. NewSegment->Length = SegmentSize;
  1442. NewSegment->Offset = 0;
  1443. NewSegment->SendAttemptCount = 0;
  1444. NewSegment->TimeoutInterval = 0;
  1445. NewSegment->Flags = LastSegment->Flags;
  1446. //
  1447. // If all the new data fit into this existing segment, then add the
  1448. // push flag.
  1449. //
  1450. ASSERT((SegmentSize - LastSegment->Length) <= Size);
  1451. if ((SegmentSize - LastSegment->Length) == Size) {
  1452. NewSegment->Flags |= TCP_SEND_SEGMENT_FLAG_PUSH;
  1453. PushNeeded = FALSE;
  1454. //
  1455. // Otherwise remove the push flag from this segment as there is more
  1456. // data to send.
  1457. //
  1458. } else {
  1459. NewSegment->Flags &= ~TCP_SEND_SEGMENT_FLAG_PUSH;
  1460. }
  1461. //
  1462. // Replace the last segment with this one, and move the counters
  1463. // forward.
  1464. //
  1465. INSERT_AFTER(&(NewSegment->Header.ListEntry),
  1466. &(LastSegment->Header.ListEntry));
  1467. LIST_REMOVE(&(LastSegment->Header.ListEntry));
  1468. BytesComplete += SegmentSize - LastSegment->Length;
  1469. TcpSocket->SendBufferFreeSize -= BytesComplete;
  1470. ASSERT(TcpSocket->SendNextBufferSequence ==
  1471. LastSegment->SequenceNumber + LastSegment->Length);
  1472. TcpSocket->SendNextBufferSequence =
  1473. NewSegment->SequenceNumber + SegmentSize;
  1474. NetpTcpFreeSegment(TcpSocket, &(LastSegment->Header));
  1475. break;
  1476. }
  1477. //
  1478. // Loop creating packets.
  1479. //
  1480. while (BytesComplete < Size) {
  1481. if (LockHeld == FALSE) {
  1482. KeAcquireQueuedLock(TcpSocket->Lock);
  1483. LockHeld = TRUE;
  1484. }
  1485. //
  1486. // Watch out for the connection shutting down.
  1487. //
  1488. if ((TcpSocket->State != TcpStateEstablished) &&
  1489. (TcpSocket->State != TcpStateCloseWait)) {
  1490. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_CONNECTION_RESET) != 0) {
  1491. Status = STATUS_CONNECTION_RESET;
  1492. } else {
  1493. Status = STATUS_BROKEN_PIPE;
  1494. }
  1495. BytesComplete = 0;
  1496. goto TcpSendEnd;
  1497. }
  1498. //
  1499. // If there's no room to add anything reasonable to the send buffer,
  1500. // try to send what's there, and then block and try again.
  1501. //
  1502. RequiredOpening = TcpSocket->SendMaxSegmentSize;
  1503. if (RequiredOpening > (Size - BytesComplete)) {
  1504. RequiredOpening = Size - BytesComplete;
  1505. }
  1506. if (TcpSocket->SendBufferFreeSize < RequiredOpening) {
  1507. IoSetIoObjectState(IoState, POLL_EVENT_OUT, FALSE);
  1508. OutgoingSegmentListWasEmpty = FALSE;
  1509. NetpTcpSendPendingSegments(TcpSocket, NULL);
  1510. KeReleaseQueuedLock(TcpSocket->Lock);
  1511. LockHeld = FALSE;
  1512. if (Timeout == 0) {
  1513. WaitTime = 0;
  1514. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  1515. CurrentTime = KeGetRecentTimeCounter();
  1516. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  1517. TimeCounterFrequency;
  1518. } else {
  1519. WaitTime = WAIT_TIME_INDEFINITE;
  1520. }
  1521. Status = IoWaitForIoObjectState(IoState,
  1522. POLL_EVENT_OUT,
  1523. TRUE,
  1524. WaitTime,
  1525. &ReturnedEvents);
  1526. if (!KSUCCESS(Status)) {
  1527. if ((Status == STATUS_TIMEOUT) && (Timeout == 0)) {
  1528. Status = STATUS_OPERATION_WOULD_BLOCK;
  1529. }
  1530. goto TcpSendEnd;
  1531. }
  1532. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1533. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1534. Status = STATUS_NO_NETWORK_CONNECTION;
  1535. } else {
  1536. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  1537. if (KSUCCESS(Status)) {
  1538. Status = STATUS_DEVICE_IO_ERROR;
  1539. }
  1540. }
  1541. BytesComplete = 0;
  1542. goto TcpSendEnd;
  1543. }
  1544. continue;
  1545. }
  1546. ASSERT(KeIsQueuedLockHeld(TcpSocket->Lock) != FALSE);
  1547. //
  1548. // Create a new segment.
  1549. //
  1550. SegmentSize = RequiredOpening;
  1551. AllocationSize = sizeof(TCP_SEND_SEGMENT) + SegmentSize;
  1552. NewSegment = (PTCP_SEND_SEGMENT)NetpTcpAllocateSegment(TcpSocket,
  1553. AllocationSize);
  1554. if (NewSegment == NULL) {
  1555. Status = STATUS_INSUFFICIENT_RESOURCES;
  1556. goto TcpSendEnd;
  1557. }
  1558. //
  1559. // Copy the new data in.
  1560. //
  1561. Status = MmCopyIoBufferData(IoBuffer,
  1562. NewSegment + 1,
  1563. BytesComplete,
  1564. SegmentSize,
  1565. FALSE);
  1566. if (!KSUCCESS(Status)) {
  1567. NetpTcpFreeSegment(TcpSocket, (PTCP_SEGMENT_HEADER)NewSegment);
  1568. goto TcpSendEnd;
  1569. }
  1570. NewSegment->SequenceNumber = TcpSocket->SendNextBufferSequence;
  1571. NewSegment->LastSendTime = 0;
  1572. NewSegment->Length = SegmentSize;
  1573. NewSegment->Offset = 0;
  1574. NewSegment->SendAttemptCount = 0;
  1575. NewSegment->TimeoutInterval = 0;
  1576. NewSegment->Flags = 0;
  1577. //
  1578. // Add this to the list, and move the counters forward.
  1579. //
  1580. if (LIST_EMPTY(&(TcpSocket->OutgoingSegmentList)) != FALSE) {
  1581. OutgoingSegmentListWasEmpty = TRUE;
  1582. NetpTcpTimerAddReference();
  1583. }
  1584. INSERT_BEFORE(&(NewSegment->Header.ListEntry),
  1585. &(TcpSocket->OutgoingSegmentList));
  1586. BytesComplete += SegmentSize;
  1587. TcpSocket->SendBufferFreeSize -= SegmentSize;
  1588. TcpSocket->SendNextBufferSequence = NewSegment->SequenceNumber +
  1589. SegmentSize;
  1590. }
  1591. //
  1592. // If a push is still needed then add the flag to the last segment.
  1593. //
  1594. if (PushNeeded != FALSE) {
  1595. ASSERT(NewSegment != NULL);
  1596. ASSERT(TcpSocket->OutgoingSegmentList.Previous ==
  1597. &(NewSegment->Header.ListEntry));
  1598. ASSERT(BytesComplete == Size);
  1599. NewSegment->Flags |= TCP_SEND_SEGMENT_FLAG_PUSH;
  1600. }
  1601. //
  1602. // If the outgoing segment list was empty, then send the data immediately.
  1603. // The timer to coalesce future sends should already be running.
  1604. //
  1605. if ((OutgoingSegmentListWasEmpty != FALSE) ||
  1606. ((TcpSocket->Flags & TCP_SOCKET_FLAG_NO_DELAY) != 0)) {
  1607. NetpTcpSendPendingSegments(TcpSocket, NULL);
  1608. }
  1609. //
  1610. // Unsignal the write event if there is no more space.
  1611. //
  1612. if (TcpSocket->SendBufferFreeSize == 0) {
  1613. IoSetIoObjectState(IoState, POLL_EVENT_OUT, FALSE);
  1614. }
  1615. Status = STATUS_SUCCESS;
  1616. TcpSendEnd:
  1617. if (LockHeld != FALSE) {
  1618. KeReleaseQueuedLock(TcpSocket->Lock);
  1619. }
  1620. Parameters->Size = BytesComplete;
  1621. //
  1622. // If any bytes were written, then consider this a success.
  1623. //
  1624. if (BytesComplete != 0) {
  1625. Status = STATUS_SUCCESS;
  1626. } else if ((Status == STATUS_BROKEN_PIPE) &&
  1627. ((Flags & SOCKET_IO_NO_SIGNAL) != 0)) {
  1628. Status = STATUS_BROKEN_PIPE_SILENT;
  1629. }
  1630. return Status;
  1631. }
  1632. VOID
  1633. NetpTcpProcessReceivedData (
  1634. PNET_LINK Link,
  1635. PNET_PACKET_BUFFER Packet,
  1636. PNETWORK_ADDRESS SourceAddress,
  1637. PNETWORK_ADDRESS DestinationAddress,
  1638. PNET_PROTOCOL_ENTRY ProtocolEntry
  1639. )
  1640. /*++
  1641. Routine Description:
  1642. This routine is called to process a received packet.
  1643. Arguments:
  1644. Link - Supplies a pointer to the link that received the packet.
  1645. Packet - Supplies a pointer to a structure describing the incoming packet.
  1646. This structure may be used as a scratch space while this routine
  1647. executes and the packet travels up the stack, but will not be accessed
  1648. after this routine returns.
  1649. SourceAddress - Supplies a pointer to the source (remote) address that the
  1650. packet originated from. This memory will not be referenced once the
  1651. function returns, it can be stack allocated.
  1652. DestinationAddress - Supplies a pointer to the destination (local) address
  1653. that the packet is heading to. This memory will not be referenced once
  1654. the function returns, it can be stack allocated.
  1655. ProtocolEntry - Supplies a pointer to this protocol's protocol entry.
  1656. Return Value:
  1657. None. When the function returns, the memory associated with the packet may
  1658. be reclaimed and reused.
  1659. --*/
  1660. {
  1661. USHORT Checksum;
  1662. PTCP_HEADER Header;
  1663. ULONG HeaderLength;
  1664. ULONG Length;
  1665. ULONG RelativeAcknowledgeNumber;
  1666. ULONG RelativeSequenceNumber;
  1667. PNET_SOCKET Socket;
  1668. PTCP_SOCKET TcpSocket;
  1669. ULONG WindowSize;
  1670. ASSERT(KeGetRunLevel() == RunLevelLow);
  1671. //
  1672. // Validate the packet is at least as long as the header plus its options.
  1673. //
  1674. Length = Packet->FooterOffset - Packet->DataOffset;
  1675. if (Length < sizeof(TCP_HEADER)) {
  1676. RtlDebugPrint("TCP: Skipping packet shorter than length of TCP "
  1677. "Header. Length = %d\n",
  1678. Length);
  1679. return;
  1680. }
  1681. Header = (PTCP_HEADER)(Packet->Buffer + Packet->DataOffset);
  1682. HeaderLength = ((Header->HeaderLength & TCP_HEADER_LENGTH_MASK) >>
  1683. TCP_HEADER_LENGTH_SHIFT) * sizeof(ULONG);
  1684. if (HeaderLength < sizeof(TCP_HEADER)) {
  1685. RtlDebugPrint("TCP: Malformed packet has header length %d less than "
  1686. "minimum 20.\n",
  1687. HeaderLength);
  1688. return;
  1689. }
  1690. if (Length < HeaderLength) {
  1691. RtlDebugPrint("TCP: Skipping packet whose length %d is less than the "
  1692. "header length %d.\n",
  1693. Length,
  1694. HeaderLength);
  1695. return;
  1696. }
  1697. Packet->DataOffset += HeaderLength;
  1698. //
  1699. // Fill out the source and destination ports and look for an eligible socket
  1700. // before doing any more work.
  1701. //
  1702. SourceAddress->Port = NETWORK_TO_CPU16(Header->SourcePort);
  1703. DestinationAddress->Port = NETWORK_TO_CPU16(Header->DestinationPort);
  1704. Socket = NetFindSocket(ProtocolEntry, DestinationAddress, SourceAddress);
  1705. if (Socket == NULL) {
  1706. NetpTcpHandleUnconnectedPacket(Link,
  1707. Header,
  1708. Packet,
  1709. SourceAddress,
  1710. DestinationAddress);
  1711. return;
  1712. }
  1713. TcpSocket = (PTCP_SOCKET)Socket;
  1714. //
  1715. // Ensure the checksum comes out correctly. Skip this if checksum was
  1716. // offloaded and it was valid.
  1717. //
  1718. if (((Packet->Flags & NET_PACKET_FLAG_TCP_CHECKSUM_OFFLOAD) == 0) ||
  1719. ((Packet->Flags & NET_PACKET_FLAG_TCP_CHECKSUM_FAILED) != 0)) {
  1720. Checksum = NetpTcpChecksumData(Header,
  1721. Length,
  1722. SourceAddress,
  1723. DestinationAddress);
  1724. if (Checksum != 0) {
  1725. RtlDebugPrint("TCP ignoring packet with bad checksum 0x%04x headed "
  1726. "for port %d from port %d.\n",
  1727. Checksum,
  1728. DestinationAddress->Port,
  1729. SourceAddress->Port);
  1730. return;
  1731. }
  1732. }
  1733. //
  1734. // This is a valid TCP packet. Handle it.
  1735. //
  1736. KeAcquireQueuedLock(TcpSocket->Lock);
  1737. //
  1738. // Print this packet if debugging is enabled.
  1739. //
  1740. if (NetTcpDebugPrintAllPackets != FALSE) {
  1741. NetpTcpPrintSocketEndpoints(TcpSocket, FALSE);
  1742. RtlDebugPrint(" RX [");
  1743. if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  1744. RtlDebugPrint("FIN ");
  1745. }
  1746. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  1747. RtlDebugPrint("SYN ");
  1748. }
  1749. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  1750. RtlDebugPrint("RST ");
  1751. }
  1752. if ((Header->Flags & TCP_HEADER_FLAG_PUSH) != 0) {
  1753. RtlDebugPrint("PSH ");
  1754. }
  1755. if ((Header->Flags & TCP_HEADER_FLAG_URGENT) != 0) {
  1756. RtlDebugPrint("URG");
  1757. }
  1758. RelativeAcknowledgeNumber = 0;
  1759. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  1760. RtlDebugPrint("ACK");
  1761. RelativeAcknowledgeNumber =
  1762. NETWORK_TO_CPU32(Header->AcknowledgmentNumber) -
  1763. TcpSocket->SendInitialSequence;
  1764. }
  1765. RelativeSequenceNumber = 0;
  1766. if (TcpSocket->ReceiveInitialSequence != 0) {
  1767. RelativeSequenceNumber = NETWORK_TO_CPU32(Header->SequenceNumber) -
  1768. TcpSocket->ReceiveInitialSequence;
  1769. }
  1770. WindowSize = NETWORK_TO_CPU16(Header->WindowSize) <<
  1771. TcpSocket->SendWindowScale;
  1772. RtlDebugPrint("] \n Seq=%d Ack=%d Win=%d Len=%d\n",
  1773. RelativeSequenceNumber,
  1774. RelativeAcknowledgeNumber,
  1775. WindowSize,
  1776. Length - HeaderLength);
  1777. }
  1778. NetpTcpProcessPacket(TcpSocket,
  1779. Link,
  1780. Header,
  1781. Packet,
  1782. SourceAddress,
  1783. DestinationAddress);
  1784. KeReleaseQueuedLock(TcpSocket->Lock);
  1785. //
  1786. // Release the reference on the socket added by the find socket call.
  1787. //
  1788. IoSocketReleaseReference(&(Socket->KernelSocket));
  1789. return;
  1790. }
  1791. KSTATUS
  1792. NetpTcpProcessReceivedSocketData (
  1793. PNET_LINK Link,
  1794. PNET_SOCKET Socket,
  1795. PNET_PACKET_BUFFER Packet,
  1796. PNETWORK_ADDRESS SourceAddress,
  1797. PNETWORK_ADDRESS DestinationAddress
  1798. )
  1799. /*++
  1800. Routine Description:
  1801. This routine is called for a particular socket to process a received packet
  1802. that was sent to it.
  1803. Arguments:
  1804. Link - Supplies a pointer to the network link that received the packet.
  1805. Socket - Supplies a pointer to the socket that received the packet.
  1806. Packet - Supplies a pointer to a structure describing the incoming packet.
  1807. Use of this structure depends on its flags. If it is a multicast
  1808. packet, then it cannot be modified by this routine. Otherwise it can
  1809. be used as scratch space and modified.
  1810. SourceAddress - Supplies a pointer to the source (remote) address that the
  1811. packet originated from. This memory will not be referenced once the
  1812. function returns, it can be stack allocated.
  1813. DestinationAddress - Supplies a pointer to the destination (local) address
  1814. that the packet is heading to. This memory will not be referenced once
  1815. the function returns, it can be stack allocated.
  1816. Return Value:
  1817. Status code.
  1818. --*/
  1819. {
  1820. //
  1821. // This packet processing routine is used by the network core for multicast
  1822. // packets. Since TCP is a connection based stream protocol, multicast
  1823. // packets should not be arriving here.
  1824. //
  1825. ASSERT(FALSE);
  1826. return STATUS_NOT_SUPPORTED;
  1827. }
  1828. KSTATUS
  1829. NetpTcpReceive (
  1830. BOOL FromKernelMode,
  1831. PNET_SOCKET Socket,
  1832. PSOCKET_IO_PARAMETERS Parameters,
  1833. PIO_BUFFER IoBuffer
  1834. )
  1835. /*++
  1836. Routine Description:
  1837. This routine is called by the user to receive data from the socket on a
  1838. particular protocol.
  1839. Arguments:
  1840. FromKernelMode - Supplies a boolean indicating whether the request is
  1841. coming from kernel mode (TRUE) or user mode (FALSE).
  1842. Socket - Supplies a pointer to the socket to receive data from.
  1843. Parameters - Supplies a pointer to the socket I/O parameters.
  1844. IoBuffer - Supplies a pointer to the I/O buffer where the received data
  1845. will be returned.
  1846. Return Value:
  1847. STATUS_SUCCESS if any bytes were read.
  1848. STATUS_TIMEOUT if the request timed out.
  1849. STATUS_BUFFER_TOO_SMALL if the incoming datagram was too large for the
  1850. buffer. The remainder of the datagram is discarded in this case.
  1851. Other error codes on other failures.
  1852. --*/
  1853. {
  1854. BOOL Break;
  1855. UINTN BytesComplete;
  1856. ULONG BytesThisRound;
  1857. PLIST_ENTRY CurrentEntry;
  1858. ULONGLONG CurrentTime;
  1859. ULONGLONG EndTime;
  1860. ULONG ExpectedSequence;
  1861. ULONG FirstFlags;
  1862. ULONG Flags;
  1863. PIO_OBJECT_STATE IoState;
  1864. BOOL LockHeld;
  1865. ULONG MaxSegmentSize;
  1866. ULONG OriginalFreeSize;
  1867. ULONG ReturnedEvents;
  1868. PTCP_RECEIVED_SEGMENT Segment;
  1869. BOOL SegmentMissing;
  1870. ULONG SegmentOffset;
  1871. ULONG SegmentSize;
  1872. UINTN Size;
  1873. PULONG SocketFlags;
  1874. KSTATUS Status;
  1875. PTCP_SOCKET TcpSocket;
  1876. ULONGLONG TimeCounterFrequency;
  1877. ULONG Timeout;
  1878. ULONG WaitTime;
  1879. TcpSocket = (PTCP_SOCKET)Socket;
  1880. EndTime = 0;
  1881. FirstFlags = 0;
  1882. Flags = Parameters->SocketIoFlags;
  1883. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  1884. BytesComplete = 0;
  1885. LockHeld = FALSE;
  1886. Size = Parameters->Size;
  1887. TimeCounterFrequency = 0;
  1888. Timeout = Parameters->TimeoutInMilliseconds;
  1889. //
  1890. // The socket needs to be connected before receiving data.
  1891. //
  1892. if (TcpSocket->State < TcpStateEstablished) {
  1893. Status = STATUS_NOT_CONNECTED;
  1894. goto TcpReceiveEnd;
  1895. }
  1896. //
  1897. // If the user called shutdown and is now trying to read, exit immediately.
  1898. //
  1899. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0) {
  1900. Status = STATUS_END_OF_FILE;
  1901. goto TcpReceiveEnd;
  1902. }
  1903. //
  1904. // Fail if there's ancillary data.
  1905. //
  1906. if (Parameters->ControlDataSize != 0) {
  1907. Status = STATUS_NOT_SUPPORTED;
  1908. goto TcpReceiveEnd;
  1909. }
  1910. //
  1911. // Potentially receive out of band data. TCP really wasn't designed for
  1912. // this, but this implementation maintains parity with others out there
  1913. // that do the same thing.
  1914. //
  1915. if ((Flags & SOCKET_IO_OUT_OF_BAND) != 0) {
  1916. Status = NetpTcpReceiveOutOfBandData(FromKernelMode,
  1917. TcpSocket,
  1918. Parameters,
  1919. IoBuffer);
  1920. goto TcpReceiveEnd;
  1921. }
  1922. Parameters->SocketIoFlags = 0;
  1923. //
  1924. // Set a timeout timer to give up on. The socket stores the maximum timeout.
  1925. //
  1926. if (Timeout > TcpSocket->ReceiveTimeout) {
  1927. Timeout = TcpSocket->ReceiveTimeout;
  1928. }
  1929. if ((Timeout != 0) && (Timeout != WAIT_TIME_INDEFINITE)) {
  1930. EndTime = KeGetRecentTimeCounter();
  1931. EndTime += KeConvertMicrosecondsToTimeTicks(
  1932. Timeout * MICROSECONDS_PER_MILLISECOND);
  1933. TimeCounterFrequency = HlQueryTimeCounterFrequency();
  1934. }
  1935. //
  1936. // Optimistically start out trying to get all the data requested.
  1937. //
  1938. Break = FALSE;
  1939. if ((Flags & SOCKET_IO_PEEK) != 0) {
  1940. Break = TRUE;
  1941. }
  1942. do {
  1943. SegmentMissing = FALSE;
  1944. if (Timeout == 0) {
  1945. WaitTime = 0;
  1946. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  1947. CurrentTime = KeGetRecentTimeCounter();
  1948. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  1949. TimeCounterFrequency;
  1950. } else {
  1951. WaitTime = WAIT_TIME_INDEFINITE;
  1952. }
  1953. Status = IoWaitForIoObjectState(IoState,
  1954. POLL_EVENT_IN,
  1955. TRUE,
  1956. WaitTime,
  1957. &ReturnedEvents);
  1958. if (!KSUCCESS(Status)) {
  1959. goto TcpReceiveEnd;
  1960. }
  1961. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  1962. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  1963. Status = STATUS_NO_NETWORK_CONNECTION;
  1964. } else {
  1965. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  1966. if (KSUCCESS(Status)) {
  1967. Status = STATUS_DEVICE_IO_ERROR;
  1968. }
  1969. }
  1970. BytesComplete = 0;
  1971. goto TcpReceiveEnd;
  1972. }
  1973. KeAcquireQueuedLock(TcpSocket->Lock);
  1974. LockHeld = TRUE;
  1975. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0) {
  1976. Status = STATUS_END_OF_FILE;
  1977. goto TcpReceiveEnd;
  1978. }
  1979. OriginalFreeSize = TcpSocket->ReceiveWindowFreeSize;
  1980. CurrentEntry = TcpSocket->ReceivedSegmentList.Next;
  1981. ExpectedSequence = TcpSocket->ReceiveUnreadSequence;
  1982. SegmentOffset = TcpSocket->ReceiveSegmentOffset;
  1983. while ((BytesComplete != Size) &&
  1984. (CurrentEntry != &(TcpSocket->ReceivedSegmentList))) {
  1985. Segment = LIST_VALUE(CurrentEntry,
  1986. TCP_RECEIVED_SEGMENT,
  1987. Header.ListEntry);
  1988. CurrentEntry = CurrentEntry->Next;
  1989. ASSERT(SegmentOffset < Segment->Length);
  1990. //
  1991. // If this segment is not the next segment, then a segment is
  1992. // missing.
  1993. //
  1994. if (Segment->SequenceNumber != ExpectedSequence) {
  1995. ASSERT(TCP_SEQUENCE_GREATER_THAN(Segment->SequenceNumber,
  1996. ExpectedSequence));
  1997. SegmentMissing = TRUE;
  1998. break;
  1999. }
  2000. //
  2001. // Don't cross over urgent flag changes. The zero check is okay
  2002. // because ACK should always be set.
  2003. //
  2004. if (FirstFlags == 0) {
  2005. FirstFlags = Segment->Flags;
  2006. } else if (((FirstFlags ^ Segment->Flags) &
  2007. TCP_RECEIVE_SEGMENT_FLAG_URGENT) != 0) {
  2008. if (BytesComplete != 0) {
  2009. break;
  2010. //
  2011. // Sure the urgent flags changed, but the user didn't get
  2012. // anything, so keep going. This happens if the user starts
  2013. // reading at a zero-length segment.
  2014. //
  2015. } else {
  2016. FirstFlags = Segment->Flags;
  2017. }
  2018. }
  2019. //
  2020. // Determine how many bytes to copy from this segment.
  2021. //
  2022. SegmentSize = Segment->Length - SegmentOffset;
  2023. BytesThisRound = SegmentSize;
  2024. if (BytesThisRound > (Size - BytesComplete)) {
  2025. BytesThisRound = Size - BytesComplete;
  2026. }
  2027. //
  2028. // Copy the data from the segment into the buffer.
  2029. //
  2030. Status = MmCopyIoBufferData(IoBuffer,
  2031. (PUCHAR)(Segment + 1) + SegmentOffset,
  2032. BytesComplete,
  2033. BytesThisRound,
  2034. TRUE);
  2035. if (!KSUCCESS(Status)) {
  2036. goto TcpReceiveEnd;
  2037. }
  2038. //
  2039. // Unless the "wait for everything" flag was set, the user got
  2040. // something, and can break out. The push flag is essentially
  2041. // ignored.
  2042. //
  2043. if ((Flags & SOCKET_IO_WAIT_ALL) == 0) {
  2044. Break = TRUE;
  2045. }
  2046. //
  2047. // If the entire remainder of the segment was copied, then remove
  2048. // and free that segment.
  2049. //
  2050. if (BytesThisRound == SegmentSize) {
  2051. SegmentOffset = 0;
  2052. if ((Flags & SOCKET_IO_PEEK) == 0) {
  2053. LIST_REMOVE(&(Segment->Header.ListEntry));
  2054. //
  2055. // The buffer is being freed, so up the receive window to
  2056. // allow the remote host to send more data.
  2057. //
  2058. TcpSocket->ReceiveWindowFreeSize += Segment->Length;
  2059. if (TcpSocket->ReceiveWindowFreeSize >
  2060. TcpSocket->ReceiveWindowTotalSize) {
  2061. TcpSocket->ReceiveWindowFreeSize =
  2062. TcpSocket->ReceiveWindowTotalSize;
  2063. }
  2064. //
  2065. // The next thing to read better be just after this
  2066. // segment. A failure here indicates bad receive buffering
  2067. // (e.g. saving duplicate packets into the buffer).
  2068. //
  2069. ASSERT(ExpectedSequence == Segment->SequenceNumber);
  2070. ExpectedSequence = Segment->NextSequence;
  2071. NetpTcpFreeSegment(TcpSocket, &(Segment->Header));
  2072. }
  2073. //
  2074. // Only a portion of the segment was consumed, so just increase the
  2075. // offset.
  2076. //
  2077. } else {
  2078. ASSERT((BytesComplete + BytesThisRound) == Size);
  2079. SegmentOffset += BytesThisRound;
  2080. }
  2081. BytesComplete += BytesThisRound;
  2082. }
  2083. //
  2084. // Advance the current segment offset and sequence. Also send an ACK if
  2085. // space was tight and enough for another segment became available.
  2086. //
  2087. if ((Flags & SOCKET_IO_PEEK) == 0) {
  2088. TcpSocket->ReceiveSegmentOffset = SegmentOffset;
  2089. ASSERT((ExpectedSequence == TcpSocket->ReceiveUnreadSequence) ||
  2090. (TCP_SEQUENCE_GREATER_THAN(ExpectedSequence,
  2091. TcpSocket->ReceiveUnreadSequence)));
  2092. TcpSocket->ReceiveUnreadSequence = ExpectedSequence;
  2093. //
  2094. // If there is enough free space for a new segment, consider
  2095. // sending a window update. If the original free window size could
  2096. // not hold a max packet then immediately alert the remote side
  2097. // that there is space. Otherwise if there is space for only 1
  2098. // packet, it is still expected to come in from the remote side,
  2099. // but set the timer to send a window update in case the packet is
  2100. // loss and so that the toggle will trigger an immediate ACK if it
  2101. // does arrive.
  2102. //
  2103. MaxSegmentSize = TcpSocket->ReceiveMaxSegmentSize;
  2104. if (TcpSocket->ReceiveWindowFreeSize >= MaxSegmentSize) {
  2105. if (OriginalFreeSize < MaxSegmentSize) {
  2106. if ((TcpSocket->Flags &
  2107. TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) != 0) {
  2108. TcpSocket->Flags &= ~TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  2109. NetpTcpTimerReleaseReference();
  2110. }
  2111. NetpTcpSendControlPacket(TcpSocket, 0);
  2112. } else if (OriginalFreeSize < (2 * MaxSegmentSize)) {
  2113. if ((TcpSocket->Flags &
  2114. TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0) {
  2115. TcpSocket->Flags |= TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  2116. NetpTcpTimerAddReference();
  2117. }
  2118. }
  2119. }
  2120. }
  2121. //
  2122. // If the received segment list is now empty, or a segment is missing,
  2123. // unsignal the receive ready event.
  2124. //
  2125. if ((SegmentMissing != FALSE) ||
  2126. (LIST_EMPTY(&(TcpSocket->ReceivedSegmentList)))) {
  2127. //
  2128. // Watch out for the socket closing down.
  2129. //
  2130. if (TcpSocket->State != TcpStateEstablished) {
  2131. ASSERT(TcpSocket->State > TcpStateEstablished);
  2132. //
  2133. // A reset connection fails as soon as it's known.
  2134. //
  2135. SocketFlags = &(TcpSocket->Flags);
  2136. if ((*SocketFlags & TCP_SOCKET_FLAG_CONNECTION_RESET) != 0) {
  2137. Status = STATUS_CONNECTION_RESET;
  2138. BytesComplete = 0;
  2139. //
  2140. // Otherwise, the request was not at all satisfied, and no more
  2141. // data is coming in.
  2142. //
  2143. } else {
  2144. Status = STATUS_END_OF_FILE;
  2145. }
  2146. goto TcpReceiveEnd;
  2147. }
  2148. IoSetIoObjectState(IoState, POLL_EVENT_IN, FALSE);
  2149. }
  2150. KeReleaseQueuedLock(TcpSocket->Lock);
  2151. LockHeld = FALSE;
  2152. } while ((Break == FALSE) && (BytesComplete != Size));
  2153. Status = STATUS_SUCCESS;
  2154. TcpReceiveEnd:
  2155. if (LockHeld != FALSE) {
  2156. KeReleaseQueuedLock(TcpSocket->Lock);
  2157. }
  2158. //
  2159. // If any bytes were read, then consider this a success.
  2160. //
  2161. if (BytesComplete != 0) {
  2162. Status = STATUS_SUCCESS;
  2163. }
  2164. Parameters->Size = BytesComplete;
  2165. return Status;
  2166. }
  2167. KSTATUS
  2168. NetpTcpGetSetInformation (
  2169. PNET_SOCKET Socket,
  2170. SOCKET_INFORMATION_TYPE InformationType,
  2171. UINTN Option,
  2172. PVOID Data,
  2173. PUINTN DataSize,
  2174. BOOL Set
  2175. )
  2176. /*++
  2177. Routine Description:
  2178. This routine gets or sets properties of the given socket.
  2179. Arguments:
  2180. Socket - Supplies a pointer to the socket to get or set information for.
  2181. InformationType - Supplies the socket information type category to which
  2182. specified option belongs.
  2183. Option - Supplies the option to get or set, which is specific to the
  2184. information type. The type of this value is generally
  2185. SOCKET_<information_type>_OPTION.
  2186. Data - Supplies a pointer to the data buffer where the data is either
  2187. returned for a get operation or given for a set operation.
  2188. DataSize - Supplies a pointer that on input constains the size of the data
  2189. buffer. On output, this contains the required size of the data buffer.
  2190. Set - Supplies a boolean indicating if this is a get operation (FALSE) or
  2191. a set operation (TRUE).
  2192. Return Value:
  2193. STATUS_SUCCESS on success.
  2194. STATUS_INVALID_PARAMETER if the information type is incorrect.
  2195. STATUS_BUFFER_TOO_SMALL if the data buffer is too small to receive the
  2196. requested option.
  2197. STATUS_NOT_SUPPORTED_BY_PROTOCOL if the socket option is not supported by
  2198. the socket.
  2199. STATUS_NOT_HANDLED if the protocol does not override the default behavior
  2200. for a basic socket option.
  2201. --*/
  2202. {
  2203. SOCKET_BASIC_OPTION BasicOption;
  2204. ULONG BooleanOption;
  2205. ULONG Count;
  2206. ULONGLONG DueTime;
  2207. ULONG Index;
  2208. ULONG KeepAliveOption;
  2209. ULONG LeadingZeros;
  2210. ULONG LingerMilliseconds;
  2211. PSOCKET_LINGER LingerOption;
  2212. SOCKET_LINGER LingerOptionBuffer;
  2213. ULONG LingerSeconds;
  2214. LONGLONG Milliseconds;
  2215. ULONG SizeDelta;
  2216. ULONG SizeOption;
  2217. PSOCKET_TIME SocketTime;
  2218. SOCKET_TIME SocketTimeBuffer;
  2219. PVOID Source;
  2220. KSTATUS Status;
  2221. SOCKET_TCP_OPTION TcpOption;
  2222. PTCP_SOCKET TcpSocket;
  2223. PTCP_SOCKET_OPTION TcpSocketOption;
  2224. PULONG TcpTimeout;
  2225. ULONG WindowScale;
  2226. ULONG WindowSize;
  2227. TcpSocket = (PTCP_SOCKET)Socket;
  2228. if ((InformationType != SocketInformationBasic) &&
  2229. (InformationType != SocketInformationTcp)) {
  2230. Status = STATUS_NOT_SUPPORTED;
  2231. goto TcpGetSetInformationEnd;
  2232. }
  2233. //
  2234. // Search to see if the socket option is supported by the TCP protocol.
  2235. //
  2236. Count = sizeof(NetTcpSocketOptions) / sizeof(NetTcpSocketOptions[0]);
  2237. for (Index = 0; Index < Count; Index += 1) {
  2238. TcpSocketOption = &(NetTcpSocketOptions[Index]);
  2239. if ((TcpSocketOption->InformationType == InformationType) &&
  2240. (TcpSocketOption->Option == Option)) {
  2241. break;
  2242. }
  2243. }
  2244. if (Index == Count) {
  2245. if (InformationType == SocketInformationBasic) {
  2246. Status = STATUS_NOT_HANDLED;
  2247. } else {
  2248. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  2249. }
  2250. goto TcpGetSetInformationEnd;
  2251. }
  2252. //
  2253. // Handle failure cases common to all options.
  2254. //
  2255. if (Set != FALSE) {
  2256. if (TcpSocketOption->SetAllowed == FALSE) {
  2257. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  2258. goto TcpGetSetInformationEnd;
  2259. }
  2260. if (*DataSize < TcpSocketOption->Size) {
  2261. *DataSize = TcpSocketOption->Size;
  2262. Status = STATUS_BUFFER_TOO_SMALL;
  2263. goto TcpGetSetInformationEnd;
  2264. }
  2265. }
  2266. //
  2267. // Parse the socket option to actually get or set the TCP socket
  2268. // information.
  2269. //
  2270. Source = NULL;
  2271. Status = STATUS_SUCCESS;
  2272. if (InformationType == SocketInformationBasic) {
  2273. BasicOption = (SOCKET_BASIC_OPTION)Option;
  2274. switch (BasicOption) {
  2275. case SocketBasicOptionLinger:
  2276. if (Set != FALSE) {
  2277. LingerOption = (PSOCKET_LINGER)Data;
  2278. LingerSeconds = LingerOption->LingerTimeout;
  2279. if (LingerSeconds > SOCKET_OPTION_MAX_ULONG) {
  2280. LingerSeconds = SOCKET_OPTION_MAX_ULONG;
  2281. }
  2282. LingerMilliseconds = LingerSeconds * MILLISECONDS_PER_SECOND;
  2283. if (LingerMilliseconds < LingerSeconds) {
  2284. Status = STATUS_INVALID_PARAMETER;
  2285. break;
  2286. }
  2287. KeAcquireQueuedLock(TcpSocket->Lock);
  2288. TcpSocket->LingerTimeout = LingerMilliseconds;
  2289. if (LingerOption->LingerEnabled != FALSE) {
  2290. TcpSocket->Flags |= TCP_SOCKET_FLAG_LINGER_ENABLED;
  2291. } else {
  2292. TcpSocket->Flags &= ~TCP_SOCKET_FLAG_LINGER_ENABLED;
  2293. }
  2294. KeReleaseQueuedLock(TcpSocket->Lock);
  2295. } else {
  2296. LingerOptionBuffer.LingerEnabled = FALSE;
  2297. KeAcquireQueuedLock(TcpSocket->Lock);
  2298. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_LINGER_ENABLED) != 0) {
  2299. LingerOptionBuffer.LingerEnabled = TRUE;
  2300. }
  2301. LingerOptionBuffer.LingerTimeout = TcpSocket->LingerTimeout /
  2302. MILLISECONDS_PER_SECOND;
  2303. KeReleaseQueuedLock(TcpSocket->Lock);
  2304. Source = &LingerOptionBuffer;
  2305. }
  2306. break;
  2307. case SocketBasicOptionSendBufferSize:
  2308. if (Set != FALSE) {
  2309. SizeOption = *((PULONG)Data);
  2310. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  2311. SizeOption = SOCKET_OPTION_MAX_ULONG;
  2312. }
  2313. KeAcquireQueuedLock(TcpSocket->Lock);
  2314. //
  2315. // Don't let the send buffer size get smaller than the max
  2316. // packet size.
  2317. //
  2318. if (SizeOption < TcpSocket->SendMaxSegmentSize) {
  2319. SizeOption = TcpSocket->SendMaxSegmentSize;
  2320. }
  2321. //
  2322. // If the send buffer is getting bigger, the difference needs
  2323. // to be added as free space.
  2324. //
  2325. if (TcpSocket->SendBufferTotalSize < SizeOption) {
  2326. SizeDelta = SizeOption - TcpSocket->SendBufferTotalSize;
  2327. TcpSocket->SendBufferTotalSize = SizeOption;
  2328. TcpSocket->SendBufferFreeSize += SizeDelta;
  2329. //
  2330. // If the send buffer is shrinking, only decrease the free size
  2331. // if it is bigger than the new total. The code that releases
  2332. // buffer space makes sure the free size is below the total.
  2333. //
  2334. } else {
  2335. TcpSocket->SendBufferTotalSize = SizeOption;
  2336. if (TcpSocket->SendBufferFreeSize > SizeOption) {
  2337. TcpSocket->SendBufferFreeSize = SizeOption;
  2338. }
  2339. }
  2340. KeReleaseQueuedLock(TcpSocket->Lock);
  2341. } else {
  2342. SizeOption = TcpSocket->SendBufferTotalSize;
  2343. Source = &SizeOption;
  2344. }
  2345. break;
  2346. case SocketBasicOptionSendMinimum:
  2347. ASSERT(Set == FALSE);
  2348. SizeOption = TCP_DEFAULT_SEND_MINIMUM;
  2349. Source = &SizeOption;
  2350. break;
  2351. case SocketBasicOptionSendTimeout:
  2352. case SocketBasicOptionReceiveTimeout:
  2353. if (BasicOption == SocketBasicOptionSendTimeout) {
  2354. TcpTimeout = &(TcpSocket->SendTimeout);
  2355. } else {
  2356. TcpTimeout = &(TcpSocket->ReceiveTimeout);
  2357. }
  2358. if (Set != FALSE) {
  2359. SocketTime = (PSOCKET_TIME)Data;
  2360. if (SocketTime->Seconds < 0) {
  2361. Status = STATUS_DOMAIN_ERROR;
  2362. break;
  2363. }
  2364. Milliseconds = SocketTime->Seconds * MILLISECONDS_PER_SECOND;
  2365. if (Milliseconds < SocketTime->Seconds) {
  2366. Status = STATUS_DOMAIN_ERROR;
  2367. break;
  2368. }
  2369. Milliseconds += SocketTime->Microseconds /
  2370. MICROSECONDS_PER_MILLISECOND;
  2371. if ((Milliseconds < 0) || (Milliseconds > MAX_LONG)) {
  2372. Status = STATUS_DOMAIN_ERROR;
  2373. break;
  2374. }
  2375. *TcpTimeout = (ULONG)(LONG)Milliseconds;
  2376. } else {
  2377. Source = &SocketTimeBuffer;
  2378. if (*TcpTimeout == WAIT_TIME_INDEFINITE) {
  2379. SocketTimeBuffer.Seconds = 0;
  2380. SocketTimeBuffer.Microseconds = 0;
  2381. } else {
  2382. SocketTimeBuffer.Seconds =
  2383. *TcpTimeout / MILLISECONDS_PER_SECOND;
  2384. SocketTimeBuffer.Microseconds =
  2385. (*TcpTimeout % MILLISECONDS_PER_SECOND) *
  2386. MICROSECONDS_PER_MILLISECOND;
  2387. }
  2388. }
  2389. break;
  2390. case SocketBasicOptionReceiveBufferSize:
  2391. if (Set != FALSE) {
  2392. SizeOption = *((PULONG)Data);
  2393. if ((SizeOption > TCP_MAXIMUM_WINDOW_SIZE) ||
  2394. (SizeOption < TCP_MINIMUM_WINDOW_SIZE)) {
  2395. Status = STATUS_INVALID_PARAMETER;
  2396. break;
  2397. }
  2398. ASSERT(SizeOption <= SOCKET_OPTION_MAX_ULONG);
  2399. KeAcquireQueuedLock(TcpSocket->Lock);
  2400. //
  2401. // If the socket is in the initialized or listening state, then
  2402. // its receive window maybe changed along with the scale.
  2403. //
  2404. if ((TcpSocket->State == TcpStateInitialized) ||
  2405. (TcpSocket->State == TcpStateListening)) {
  2406. ASSERT(TcpSocket->ReceiveWindowTotalSize ==
  2407. TcpSocket->ReceiveWindowFreeSize);
  2408. ASSERT((TcpSocket->Flags &
  2409. TCP_SOCKET_FLAG_WINDOW_SCALING) != 0);
  2410. //
  2411. // If the upper word is not zero, count the leading zeros
  2412. // to figure out a good scale. Getting as close as possible
  2413. // to the requested window.
  2414. //
  2415. if ((SizeOption & ~TCP_WINDOW_MASK) != 0) {
  2416. LeadingZeros = RtlCountLeadingZeros32(SizeOption);
  2417. WindowScale = (sizeof(USHORT) * BITS_PER_BYTE) -
  2418. LeadingZeros;
  2419. TcpSocket->ReceiveWindowScale = WindowScale;
  2420. WindowSize = (SizeOption >> WindowScale);
  2421. ASSERT(WindowSize != 0);
  2422. WindowSize <<= WindowScale;
  2423. TcpSocket->ReceiveWindowTotalSize = WindowSize;
  2424. TcpSocket->ReceiveWindowFreeSize = WindowSize;
  2425. ASSERT(WindowScale <= TCP_MAXIMUM_WINDOW_SCALE);
  2426. //
  2427. // Otherwise no scaling is necessary.
  2428. //
  2429. } else {
  2430. TcpSocket->ReceiveWindowScale = 0;
  2431. TcpSocket->ReceiveWindowTotalSize = SizeOption;
  2432. TcpSocket->ReceiveWindowFreeSize = SizeOption;
  2433. }
  2434. //
  2435. // Otherwise updates to the window size are bounded by the
  2436. // scale that was communicated to the remote side when the SYN
  2437. // was sent. If the requested size is too large or too small
  2438. // for the current scale, return failure.
  2439. //
  2440. } else {
  2441. WindowSize = SizeOption >> TcpSocket->ReceiveWindowScale;
  2442. if ((WindowSize == 0) ||
  2443. ((WindowSize & ~TCP_WINDOW_MASK) != 0)) {
  2444. Status = STATUS_INVALID_PARAMETER;
  2445. } else {
  2446. //
  2447. // If the receive window is getting bigger, the
  2448. // difference needs to be added as free space.
  2449. //
  2450. if (TcpSocket->ReceiveWindowTotalSize < SizeOption) {
  2451. SizeDelta = SizeOption -
  2452. TcpSocket->ReceiveWindowTotalSize;
  2453. TcpSocket->ReceiveWindowTotalSize = SizeOption;
  2454. TcpSocket->ReceiveWindowFreeSize += SizeDelta;
  2455. //
  2456. // If the receive window is shrinking, only decrease
  2457. // the free size if it is bigger than the new total.
  2458. // The receive code makes sure that buffer space
  2459. // reclaim doesn't set the free space above the total.
  2460. //
  2461. } else {
  2462. TcpSocket->ReceiveWindowTotalSize = SizeOption;
  2463. if (TcpSocket->ReceiveWindowFreeSize > SizeOption) {
  2464. TcpSocket->ReceiveWindowFreeSize = SizeOption;
  2465. }
  2466. }
  2467. }
  2468. }
  2469. //
  2470. // Make sure the receive minimum is up to date.
  2471. //
  2472. if (TcpSocket->ReceiveMinimum >
  2473. TcpSocket->ReceiveWindowTotalSize) {
  2474. TcpSocket->ReceiveMinimum =
  2475. TcpSocket->ReceiveWindowTotalSize;
  2476. }
  2477. KeReleaseQueuedLock(TcpSocket->Lock);
  2478. } else {
  2479. SizeOption = TcpSocket->ReceiveWindowTotalSize;
  2480. Source = &SizeOption;
  2481. }
  2482. break;
  2483. case SocketBasicOptionReceiveMinimum:
  2484. if (Set != FALSE) {
  2485. SizeOption = *((PULONG)Data);
  2486. if (SizeOption > SOCKET_OPTION_MAX_ULONG) {
  2487. SizeOption = SOCKET_OPTION_MAX_ULONG;
  2488. }
  2489. KeAcquireQueuedLock(TcpSocket->Lock);
  2490. if (SizeOption > TcpSocket->ReceiveWindowTotalSize) {
  2491. SizeOption = TcpSocket->ReceiveWindowTotalSize;
  2492. }
  2493. TcpSocket->ReceiveMinimum = SizeOption;
  2494. KeReleaseQueuedLock(TcpSocket->Lock);
  2495. } else {
  2496. SizeOption = TcpSocket->ReceiveMinimum;
  2497. Source = &SizeOption;
  2498. }
  2499. break;
  2500. case SocketBasicOptionAcceptConnections:
  2501. ASSERT(Set == FALSE);
  2502. Source = &BooleanOption;
  2503. BooleanOption = FALSE;
  2504. if (TcpSocket->State == TcpStateListening) {
  2505. BooleanOption = TRUE;
  2506. }
  2507. break;
  2508. case SocketBasicOptionKeepAlive:
  2509. if (Set != FALSE) {
  2510. BooleanOption = *((PULONG)Data);
  2511. KeAcquireQueuedLock(TcpSocket->Lock);
  2512. if (BooleanOption != FALSE) {
  2513. //
  2514. // If keep alive is being enabled and the socket is in a
  2515. // keep alive state, then arm the timer.
  2516. //
  2517. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_KEEP_ALIVE) == 0) {
  2518. if (TCP_IS_KEEP_ALIVE_STATE(TcpSocket->State)) {
  2519. DueTime = KeGetRecentTimeCounter();
  2520. DueTime += KeConvertMicrosecondsToTimeTicks(
  2521. TcpSocket->KeepAliveTimeout *
  2522. MICROSECONDS_PER_SECOND);
  2523. TcpSocket->KeepAliveTime = DueTime;
  2524. TcpSocket->KeepAliveProbeCount = 0;
  2525. NetpTcpArmKeepAliveTimer(DueTime);
  2526. }
  2527. TcpSocket->Flags |= TCP_SOCKET_FLAG_KEEP_ALIVE;
  2528. }
  2529. } else {
  2530. TcpSocket->Flags &= ~TCP_SOCKET_FLAG_KEEP_ALIVE;
  2531. TcpSocket->KeepAliveTime = 0;
  2532. TcpSocket->KeepAliveProbeCount = 0;
  2533. }
  2534. KeReleaseQueuedLock(TcpSocket->Lock);
  2535. } else {
  2536. Source = &BooleanOption;
  2537. BooleanOption = FALSE;
  2538. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_KEEP_ALIVE) != 0) {
  2539. BooleanOption = TRUE;
  2540. }
  2541. }
  2542. break;
  2543. case SocketBasicOptionInlineOutOfBand:
  2544. if (Set != FALSE) {
  2545. BooleanOption = *((PULONG)Data);
  2546. KeAcquireQueuedLock(TcpSocket->Lock);
  2547. if (BooleanOption != FALSE) {
  2548. TcpSocket->Flags |= TCP_SOCKET_FLAG_URGENT_INLINE;
  2549. } else {
  2550. TcpSocket->Flags &= ~TCP_SOCKET_FLAG_URGENT_INLINE;
  2551. }
  2552. KeReleaseQueuedLock(TcpSocket->Lock);
  2553. } else {
  2554. Source = &BooleanOption;
  2555. BooleanOption = FALSE;
  2556. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_URGENT_INLINE) != 0) {
  2557. BooleanOption = TRUE;
  2558. }
  2559. }
  2560. break;
  2561. default:
  2562. ASSERT(FALSE);
  2563. Status = STATUS_NOT_HANDLED;
  2564. break;
  2565. }
  2566. } else {
  2567. ASSERT(InformationType == SocketInformationTcp);
  2568. TcpOption = (SOCKET_TCP_OPTION)Option;
  2569. switch (TcpOption) {
  2570. case SocketTcpOptionNoDelay:
  2571. if (Set != FALSE) {
  2572. BooleanOption = *((PULONG)Data);
  2573. KeAcquireQueuedLock(TcpSocket->Lock);
  2574. TcpSocket->Flags &= ~TCP_SOCKET_FLAG_NO_DELAY;
  2575. if (BooleanOption != FALSE) {
  2576. TcpSocket->Flags |= TCP_SOCKET_FLAG_NO_DELAY;
  2577. }
  2578. KeReleaseQueuedLock(TcpSocket->Lock);
  2579. } else {
  2580. Source = &BooleanOption;
  2581. BooleanOption = FALSE;
  2582. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_NO_DELAY) != 0) {
  2583. BooleanOption = TRUE;
  2584. }
  2585. }
  2586. break;
  2587. case SocketTcpOptionKeepAliveTimeout:
  2588. if (Set != FALSE) {
  2589. KeepAliveOption = *((PULONG)Data);
  2590. if (KeepAliveOption > SOCKET_OPTION_MAX_ULONG) {
  2591. KeepAliveOption = SOCKET_OPTION_MAX_ULONG;
  2592. }
  2593. TcpSocket->KeepAliveTimeout = KeepAliveOption;
  2594. } else {
  2595. Source = &KeepAliveOption;
  2596. KeepAliveOption = TcpSocket->KeepAliveTimeout;
  2597. }
  2598. break;
  2599. case SocketTcpOptionKeepAlivePeriod:
  2600. if (Set != FALSE) {
  2601. KeepAliveOption = *((PULONG)Data);
  2602. if (KeepAliveOption > SOCKET_OPTION_MAX_ULONG) {
  2603. KeepAliveOption = SOCKET_OPTION_MAX_ULONG;
  2604. }
  2605. TcpSocket->KeepAlivePeriod = KeepAliveOption;
  2606. } else {
  2607. Source = &KeepAliveOption;
  2608. KeepAliveOption = TcpSocket->KeepAlivePeriod;
  2609. }
  2610. break;
  2611. case SocketTcpOptionKeepAliveProbeLimit:
  2612. if (Set != FALSE) {
  2613. KeepAliveOption = *((PULONG)Data);
  2614. if (KeepAliveOption > SOCKET_OPTION_MAX_ULONG) {
  2615. KeepAliveOption = SOCKET_OPTION_MAX_ULONG;
  2616. }
  2617. TcpSocket->KeepAliveProbeLimit = KeepAliveOption;
  2618. } else {
  2619. Source = &KeepAliveOption;
  2620. KeepAliveOption = TcpSocket->KeepAliveProbeLimit;
  2621. }
  2622. break;
  2623. default:
  2624. ASSERT(FALSE);
  2625. Status = STATUS_NOT_SUPPORTED_BY_PROTOCOL;
  2626. break;
  2627. }
  2628. }
  2629. if (!KSUCCESS(Status)) {
  2630. goto TcpGetSetInformationEnd;
  2631. }
  2632. //
  2633. // Truncate all copies for get requests down to the required size and only
  2634. // return the required size on set requests.
  2635. //
  2636. if (*DataSize > TcpSocketOption->Size) {
  2637. *DataSize = TcpSocketOption->Size;
  2638. }
  2639. //
  2640. // For get requests, copy the gathered information to the supplied data
  2641. // buffer.
  2642. //
  2643. if (Set == FALSE) {
  2644. ASSERT(Source != NULL);
  2645. RtlCopyMemory(Data, Source, *DataSize);
  2646. //
  2647. // If the copy truncated the data, report that the given buffer was too
  2648. // small. The caller can choose to ignore this if the truncated data is
  2649. // enough.
  2650. //
  2651. if (*DataSize < TcpSocketOption->Size) {
  2652. *DataSize = TcpSocketOption->Size;
  2653. Status = STATUS_BUFFER_TOO_SMALL;
  2654. goto TcpGetSetInformationEnd;
  2655. }
  2656. }
  2657. TcpGetSetInformationEnd:
  2658. return Status;
  2659. }
  2660. KSTATUS
  2661. NetpTcpUserControl (
  2662. PNET_SOCKET Socket,
  2663. ULONG CodeNumber,
  2664. BOOL FromKernelMode,
  2665. PVOID ContextBuffer,
  2666. UINTN ContextBufferSize
  2667. )
  2668. /*++
  2669. Routine Description:
  2670. This routine handles user control requests destined for a socket.
  2671. Arguments:
  2672. Socket - Supplies a pointer to the socket.
  2673. CodeNumber - Supplies the minor code of the request.
  2674. FromKernelMode - Supplies a boolean indicating whether or not this request
  2675. (and the buffer associated with it) originates from user mode (FALSE)
  2676. or kernel mode (TRUE).
  2677. ContextBuffer - Supplies a pointer to the context buffer allocated by the
  2678. caller for the request.
  2679. ContextBufferSize - Supplies the size of the supplied context buffer.
  2680. Return Value:
  2681. Status code.
  2682. --*/
  2683. {
  2684. ULONG Integer;
  2685. PTCP_RECEIVED_SEGMENT Segment;
  2686. KSTATUS Status;
  2687. PTCP_SOCKET TcpSocket;
  2688. TcpSocket = (PTCP_SOCKET)Socket;
  2689. KeAcquireQueuedLock(TcpSocket->Lock);
  2690. switch (CodeNumber) {
  2691. //
  2692. // Determine if the next segment has the urgent flag set.
  2693. //
  2694. case TcpUserControlAtUrgentMark:
  2695. if (ContextBufferSize < sizeof(ULONG)) {
  2696. Status = STATUS_DATA_LENGTH_MISMATCH;
  2697. break;
  2698. }
  2699. Integer = FALSE;
  2700. if (LIST_EMPTY(&(TcpSocket->ReceivedSegmentList)) == FALSE) {
  2701. Segment = LIST_VALUE(TcpSocket->ReceivedSegmentList.Next,
  2702. TCP_RECEIVED_SEGMENT,
  2703. Header.ListEntry);
  2704. if ((Segment->Flags & TCP_RECEIVE_SEGMENT_FLAG_URGENT) != 0) {
  2705. //
  2706. // TCP urgent packets are only 1 byte in length. If they were
  2707. // more, then this code would need to check the offset to see
  2708. // if the next receive is at the beginning of this segment.
  2709. //
  2710. ASSERT(Segment->Length <= 1);
  2711. Integer = TRUE;
  2712. }
  2713. }
  2714. if (FromKernelMode != FALSE) {
  2715. RtlCopyMemory(ContextBuffer, &Integer, sizeof(ULONG));
  2716. } else {
  2717. MmCopyToUserMode(ContextBuffer, &Integer, sizeof(ULONG));
  2718. }
  2719. Status = STATUS_SUCCESS;
  2720. break;
  2721. default:
  2722. Status = STATUS_NOT_SUPPORTED;
  2723. break;
  2724. }
  2725. KeReleaseQueuedLock(TcpSocket->Lock);
  2726. return Status;
  2727. }
  2728. VOID
  2729. NetpTcpPrintSocketEndpoints (
  2730. PTCP_SOCKET Socket,
  2731. BOOL Transmit
  2732. )
  2733. /*++
  2734. Routine Description:
  2735. This routine prints the socket local and remote addresses.
  2736. Arguments:
  2737. Socket - Supplies a pointer to the socket whose addresses should be printed.
  2738. Transmit - Supplies a boolean indicating if the print is requested for a
  2739. transmit (TRUE) or receive (FALSE).
  2740. Return Value:
  2741. None.
  2742. --*/
  2743. {
  2744. ULONGLONG Milliseconds;
  2745. Milliseconds = (HlQueryTimeCounter() * MILLISECONDS_PER_SECOND) /
  2746. HlQueryTimeCounterFrequency();
  2747. RtlDebugPrint("TCP %I64dms: ", Milliseconds);
  2748. if (Transmit != FALSE) {
  2749. if (NetTcpDebugPrintLocalAddress != FALSE) {
  2750. NetDebugPrintAddress(&(Socket->NetSocket.LocalAddress));
  2751. RtlDebugPrint(" to ");
  2752. }
  2753. }
  2754. NetDebugPrintAddress(&(Socket->NetSocket.RemoteAddress));
  2755. if (Transmit == FALSE) {
  2756. if (NetTcpDebugPrintLocalAddress != FALSE) {
  2757. RtlDebugPrint(" to ");
  2758. NetDebugPrintAddress(&(Socket->NetSocket.LocalAddress));
  2759. }
  2760. }
  2761. return;
  2762. }
  2763. VOID
  2764. NetpTcpRetransmit (
  2765. PTCP_SOCKET Socket
  2766. )
  2767. /*++
  2768. Routine Description:
  2769. This routine immediately transmits the oldest pending packet. This routine
  2770. assumes the socket lock is already held.
  2771. Arguments:
  2772. Socket - Supplies a pointer to the socket whose segment should be
  2773. retransmitted.
  2774. Return Value:
  2775. None.
  2776. --*/
  2777. {
  2778. PTCP_SEND_SEGMENT Segment;
  2779. if (LIST_EMPTY(&(Socket->OutgoingSegmentList)) != FALSE) {
  2780. return;
  2781. }
  2782. Segment = LIST_VALUE(Socket->OutgoingSegmentList.Next,
  2783. TCP_SEND_SEGMENT,
  2784. Header.ListEntry);
  2785. NetpTcpSendSegment(Socket, Segment);
  2786. return;
  2787. }
  2788. //
  2789. // --------------------------------------------------------- Internal Functions
  2790. //
  2791. VOID
  2792. NetpTcpWorkerThread (
  2793. PVOID Parameter
  2794. )
  2795. /*++
  2796. Routine Description:
  2797. This routine implements periodic maintenance work required by TCP.
  2798. Arguments:
  2799. Parameter - Supplies an unused parameter.
  2800. Return Value:
  2801. None. Unless TCP is altogether shut down, this thread never exits.
  2802. --*/
  2803. {
  2804. PLIST_ENTRY CurrentEntry;
  2805. PTCP_SOCKET CurrentSocket;
  2806. ULONGLONG CurrentTime;
  2807. PULONG Flags;
  2808. PIO_OBJECT_STATE IoState;
  2809. ULONGLONG KeepAliveTime;
  2810. BOOL KeepAliveTimeout;
  2811. PSOCKET KernelSocket;
  2812. BOOL LinkUp;
  2813. ULONG OldReferenceCount;
  2814. ULONGLONG RecentTime;
  2815. PVOID SignalingObject;
  2816. PVOID WaitObjectArray[2];
  2817. BOOL WithAcknowledge;
  2818. ASSERT(2 < BUILTIN_WAIT_BLOCK_ENTRY_COUNT);
  2819. KeepAliveTime = MAX_ULONGLONG;
  2820. WaitObjectArray[0] = NetTcpTimer;
  2821. WaitObjectArray[1] = NetTcpKeepAliveTimer;
  2822. while ((NetTcpTimer != NULL) && (NetTcpKeepAliveTimer != NULL)) {
  2823. //
  2824. // Sleep until the periodic or keep alive timer fires again.
  2825. //
  2826. ObWaitOnObjects(WaitObjectArray,
  2827. 2,
  2828. 0,
  2829. WAIT_TIME_INDEFINITE,
  2830. NULL,
  2831. &SignalingObject);
  2832. //
  2833. // If the keep alive timer signaled, then check the keep alive states.
  2834. //
  2835. KeepAliveTimeout = FALSE;
  2836. if (SignalingObject == NetTcpKeepAliveTimer) {
  2837. KeepAliveTimeout = TRUE;
  2838. KeepAliveTime = MAX_ULONGLONG;
  2839. KeSignalTimer(NetTcpKeepAliveTimer, SignalOptionUnsignal);
  2840. //
  2841. // If the TCP time signaled, determine whether or not work needs to be
  2842. // done. Start by decrementing a reference for the now expired timer.
  2843. // If the old reference count is 1 then none of the sockets need
  2844. // processing. If there is still more than 1 reference, however, at
  2845. // least one socket is hanging around. Queue the timer and process the
  2846. // sockets.
  2847. //
  2848. } else {
  2849. ASSERT(SignalingObject == NetTcpTimer);
  2850. KeSignalTimer(NetTcpTimer, SignalOptionUnsignal);
  2851. OldReferenceCount = NetpTcpTimerReleaseReference();
  2852. if (OldReferenceCount == 1) {
  2853. continue;
  2854. }
  2855. NetpTcpQueueTcpTimer();
  2856. }
  2857. //
  2858. // Loop through every socket.
  2859. //
  2860. CurrentTime = 0;
  2861. KeAcquireQueuedLock(NetTcpSocketListLock);
  2862. CurrentEntry = NetTcpSocketList.Next;
  2863. while (CurrentEntry != &NetTcpSocketList) {
  2864. CurrentSocket = LIST_VALUE(CurrentEntry, TCP_SOCKET, ListEntry);
  2865. CurrentEntry = CurrentEntry->Next;
  2866. KernelSocket = &(CurrentSocket->NetSocket.KernelSocket);
  2867. ASSERT(KernelSocket->ReferenceCount >= 1);
  2868. //
  2869. // Check the link state for all bound sockets. If the link is down,
  2870. // then close the socket.
  2871. //
  2872. if (CurrentSocket->NetSocket.Link != NULL) {
  2873. NetGetLinkState(CurrentSocket->NetSocket.Link, &LinkUp, NULL);
  2874. if (LinkUp == FALSE) {
  2875. IoSocketAddReference(KernelSocket);
  2876. KeAcquireQueuedLock(CurrentSocket->Lock);
  2877. NetpTcpCloseOutSocket(CurrentSocket, TRUE);
  2878. KeReleaseQueuedLock(CurrentSocket->Lock);
  2879. IoSocketReleaseReference(KernelSocket);
  2880. continue;
  2881. }
  2882. }
  2883. //
  2884. // If the socket is not waiting on anything, move on. Manipulation
  2885. // of any of these criteria require manipulating the TCP timer
  2886. // reference count.
  2887. //
  2888. Flags = &(CurrentSocket->Flags);
  2889. if ((LIST_EMPTY(&(CurrentSocket->OutgoingSegmentList))) &&
  2890. ((*Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0) &&
  2891. (((*Flags & TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID) == 0) ||
  2892. ((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) != 0)) &&
  2893. (CurrentSocket->State != TcpStateTimeWait) &&
  2894. (TCP_IS_SYN_RETRY_STATE(CurrentSocket->State) == FALSE) &&
  2895. (((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) != 0) ||
  2896. (TCP_IS_FIN_RETRY_STATE(CurrentSocket->State) == FALSE)) &&
  2897. ((KeepAliveTimeout == FALSE) ||
  2898. ((*Flags & TCP_SOCKET_FLAG_KEEP_ALIVE) == 0) ||
  2899. (TCP_IS_KEEP_ALIVE_STATE(CurrentSocket->State) == FALSE))) {
  2900. continue;
  2901. }
  2902. IoSocketAddReference(KernelSocket);
  2903. KeAcquireQueuedLock(CurrentSocket->Lock);
  2904. NetpTcpSendPendingSegments(CurrentSocket, &CurrentTime);
  2905. //
  2906. // If the media was disconnected, close out the socket and move on.
  2907. //
  2908. IoState = CurrentSocket->NetSocket.KernelSocket.IoState;
  2909. if ((IoState->Events & POLL_EVENT_DISCONNECTED) != 0) {
  2910. NetpTcpCloseOutSocket(CurrentSocket, TRUE);
  2911. KeReleaseQueuedLock(CurrentSocket->Lock);
  2912. IoSocketReleaseReference(KernelSocket);
  2913. continue;
  2914. }
  2915. //
  2916. // If the socket is in the time wait state and the timer has
  2917. // expired then close out the socket.
  2918. //
  2919. if (CurrentSocket->State == TcpStateTimeWait) {
  2920. if (KeGetRecentTimeCounter() > CurrentSocket->TimeoutEnd) {
  2921. ASSERT(CurrentSocket->TimeoutEnd != 0);
  2922. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  2923. RtlDebugPrint("TCP: Time-wait finished.\n");
  2924. }
  2925. NetpTcpCloseOutSocket(CurrentSocket, TRUE);
  2926. }
  2927. //
  2928. // If the socket is waiting for a SYN to be ACK'd, then resend the
  2929. // SYN if the retry has been reached. If the timeout has been
  2930. // reached then send a reset and signal the error event to wake up
  2931. // connect or accept.
  2932. //
  2933. } else if (TCP_IS_SYN_RETRY_STATE(CurrentSocket->State)) {
  2934. RecentTime = KeGetRecentTimeCounter();
  2935. if (RecentTime > CurrentSocket->TimeoutEnd) {
  2936. NetpTcpSendControlPacket(CurrentSocket,
  2937. TCP_HEADER_FLAG_RESET);
  2938. NET_SOCKET_SET_LAST_ERROR(&(CurrentSocket->NetSocket),
  2939. STATUS_TIMEOUT);
  2940. IoSetIoObjectState(IoState, POLL_EVENT_ERROR, TRUE);
  2941. NetpTcpSetState(CurrentSocket, TcpStateInitialized);
  2942. } else if (RecentTime >= CurrentSocket->RetryTime) {
  2943. WithAcknowledge = FALSE;
  2944. if (CurrentSocket->State == TcpStateSynReceived) {
  2945. WithAcknowledge = TRUE;
  2946. }
  2947. NetpTcpSendSyn(CurrentSocket, WithAcknowledge);
  2948. TCP_UPDATE_RETRY_TIME(CurrentSocket);
  2949. }
  2950. //
  2951. // If the socket is waiting for a FIN to be ACK'd, then resend the
  2952. // FIN if the retry time has been reached. If the timeout has
  2953. // expired, send a reset and close the socket.
  2954. //
  2955. } else if (((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) &&
  2956. TCP_IS_FIN_RETRY_STATE(CurrentSocket->State)) {
  2957. RecentTime = KeGetRecentTimeCounter();
  2958. if (RecentTime > CurrentSocket->TimeoutEnd) {
  2959. NetpTcpSendControlPacket(CurrentSocket,
  2960. TCP_HEADER_FLAG_RESET);
  2961. *Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  2962. NET_SOCKET_SET_LAST_ERROR(&(CurrentSocket->NetSocket),
  2963. STATUS_DESTINATION_UNREACHABLE);
  2964. IoSetIoObjectState(IoState, POLL_EVENT_ERROR, TRUE);
  2965. NetpTcpCloseOutSocket(CurrentSocket, TRUE);
  2966. } else if (RecentTime >= CurrentSocket->RetryTime) {
  2967. NetpTcpSendControlPacket(CurrentSocket,
  2968. TCP_HEADER_FLAG_FIN);
  2969. TCP_UPDATE_RETRY_TIME(CurrentSocket);
  2970. }
  2971. //
  2972. // If the socket is in the keep alive state and the keep alive
  2973. // timer woke up the thread, then check on that timeout.
  2974. //
  2975. } else if ((KeepAliveTimeout != FALSE) &&
  2976. ((*Flags & TCP_SOCKET_FLAG_KEEP_ALIVE) != 0) &&
  2977. TCP_IS_KEEP_ALIVE_STATE(CurrentSocket->State)) {
  2978. //
  2979. // If too many probes have been sent without a response then
  2980. // this socket is dead. Be nice, send a reset and then close it
  2981. // out.
  2982. //
  2983. if (CurrentSocket->KeepAliveProbeCount >
  2984. CurrentSocket->KeepAliveProbeLimit) {
  2985. NetpTcpSendControlPacket(CurrentSocket,
  2986. TCP_HEADER_FLAG_RESET);
  2987. *Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  2988. NET_SOCKET_SET_LAST_ERROR(&(CurrentSocket->NetSocket),
  2989. STATUS_DESTINATION_UNREACHABLE);
  2990. IoSetIoObjectState(IoState, POLL_EVENT_ERROR, TRUE);
  2991. NetpTcpCloseOutSocket(CurrentSocket, TRUE);
  2992. //
  2993. // Otherwise, if the keep alive time has been reached, then
  2994. // send another ping and then re-arm the keep alive time.
  2995. //
  2996. } else {
  2997. RecentTime = KeGetRecentTimeCounter();
  2998. if (RecentTime >= CurrentSocket->KeepAliveTime) {
  2999. NetpTcpSendControlPacket(CurrentSocket,
  3000. TCP_HEADER_FLAG_KEEP_ALIVE);
  3001. CurrentSocket->KeepAliveProbeCount += 1;
  3002. CurrentSocket->KeepAliveTime = RecentTime;
  3003. CurrentSocket->KeepAliveTime +=
  3004. CurrentSocket->KeepAlivePeriod *
  3005. HlQueryTimeCounterFrequency();
  3006. }
  3007. if (CurrentSocket->KeepAliveTime < KeepAliveTime) {
  3008. KeepAliveTime = CurrentSocket->KeepAliveTime;
  3009. }
  3010. }
  3011. }
  3012. //
  3013. // If an acknowledge needs to be sent and it wasn't already sent
  3014. // above, then send just an acknowledge along.
  3015. //
  3016. if ((*Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) != 0) {
  3017. *Flags &= ~TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  3018. NetpTcpTimerReleaseReference();
  3019. NetpTcpSendControlPacket(CurrentSocket, 0);
  3020. }
  3021. KeReleaseQueuedLock(CurrentSocket->Lock);
  3022. IoSocketReleaseReference(KernelSocket);
  3023. }
  3024. KeReleaseQueuedLock(NetTcpSocketListLock);
  3025. //
  3026. // If the keep alive timer needs to be re-armed, then do so with the
  3027. // next lowest time.
  3028. //
  3029. if ((KeepAliveTimeout != FALSE) && (KeepAliveTime != MAX_ULONGLONG)) {
  3030. NetpTcpArmKeepAliveTimer(KeepAliveTime);
  3031. }
  3032. }
  3033. return;
  3034. }
  3035. VOID
  3036. NetpTcpProcessPacket (
  3037. PTCP_SOCKET Socket,
  3038. PNET_LINK Link,
  3039. PTCP_HEADER Header,
  3040. PNET_PACKET_BUFFER Packet,
  3041. PNETWORK_ADDRESS SourceAddress,
  3042. PNETWORK_ADDRESS DestinationAddress
  3043. )
  3044. /*++
  3045. Routine Description:
  3046. This routine is called to process a valid received packet. This routine
  3047. assumes the socket lock is already held.
  3048. Arguments:
  3049. Socket - Supplies a pointer to the TCP socket.
  3050. Link - Supplies a pointer to the link the packet was received on.
  3051. Header - Supplies a pointer to the TCP header.
  3052. Packet - Supplies a pointer to the received packet information.
  3053. SourceAddress - Supplies a pointer to the source (remote) address that the
  3054. packet originated from. This memory will not be referenced once the
  3055. function returns, it can be stack allocated.
  3056. DestinationAddress - Supplies a pointer to the destination (local) address
  3057. that the packet is heading to. This memory will not be referenced once
  3058. the function returns, it can be stack allocated.
  3059. Return Value:
  3060. None.
  3061. --*/
  3062. {
  3063. ULONG AcknowledgeNumber;
  3064. ULONGLONG DueTime;
  3065. PIO_OBJECT_STATE IoState;
  3066. ULONG RemoteFinalSequence;
  3067. ULONG RemoteSequence;
  3068. ULONG ResetFlags;
  3069. ULONG ResetSequenceNumber;
  3070. BOOL SegmentAcceptable;
  3071. PVOID SegmentData;
  3072. ULONG SegmentLength;
  3073. KSTATUS Status;
  3074. BOOL SynHandled;
  3075. ASSERT(Socket->NetSocket.KernelSocket.ReferenceCount >= 1);
  3076. IoState = Socket->NetSocket.KernelSocket.IoState;
  3077. SynHandled = FALSE;
  3078. ASSERT(Socket->State > TcpStateInitialized);
  3079. RemoteSequence = NETWORK_TO_CPU32(Header->SequenceNumber);
  3080. AcknowledgeNumber = NETWORK_TO_CPU32(Header->AcknowledgmentNumber);
  3081. //
  3082. // If the socket is closed, then anything other than a reset generates a
  3083. // reset packet. For the reset, use the acknowledge number supplied by the
  3084. // incoming packet if the flag is set.
  3085. //
  3086. if (Socket->State == TcpStateClosed) {
  3087. if ((Header->Flags & TCP_HEADER_FLAG_RESET) == 0) {
  3088. //
  3089. // Always send a reset.
  3090. //
  3091. ResetFlags = TCP_HEADER_FLAG_RESET;
  3092. //
  3093. // If an ACK was received, the acknoledgement number is used as the
  3094. // sequence number and no ACK is sent.
  3095. //
  3096. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3097. ResetFlags |= TCP_HEADER_FLAG_ACKNOWLEDGE;
  3098. ResetSequenceNumber = AcknowledgeNumber;
  3099. //
  3100. // Otherwise the sequence number is zero and an ACK is sent with
  3101. // the sender's sequence number plus length as the acknowledgement
  3102. // number.
  3103. //
  3104. } else {
  3105. ResetSequenceNumber = 0;
  3106. SegmentLength = Packet->FooterOffset - Packet->DataOffset;
  3107. //
  3108. // Remember to count SYNs and FINs as part of the data length.
  3109. //
  3110. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  3111. SegmentLength += 1;
  3112. }
  3113. if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  3114. SegmentLength += 1;
  3115. }
  3116. Socket->ReceiveNextSequence = RemoteSequence + SegmentLength;
  3117. }
  3118. Socket->SendUnacknowledgedSequence = ResetSequenceNumber;
  3119. NetpTcpSendControlPacket(Socket, ResetFlags);
  3120. }
  3121. return;
  3122. }
  3123. //
  3124. // Perform special handling for a listening socket.
  3125. //
  3126. if (Socket->State == TcpStateListening) {
  3127. //
  3128. // Incoming resets should be ignored, just return.
  3129. //
  3130. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  3131. return;
  3132. }
  3133. //
  3134. // It's too early for any acknowledgements, send a reset if one is
  3135. // found.
  3136. //
  3137. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3138. ResetSequenceNumber = AcknowledgeNumber;
  3139. ResetFlags = TCP_HEADER_FLAG_RESET | TCP_HEADER_FLAG_ACKNOWLEDGE;
  3140. Socket->SendUnacknowledgedSequence = ResetSequenceNumber;
  3141. NetpTcpSendControlPacket(Socket, ResetFlags);
  3142. return;
  3143. }
  3144. //
  3145. // Check for a SYN, someone wants to connect!
  3146. //
  3147. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  3148. NetpTcpHandleIncomingConnection(Socket,
  3149. Header,
  3150. Packet,
  3151. Link,
  3152. DestinationAddress,
  3153. SourceAddress);
  3154. }
  3155. return;
  3156. //
  3157. // Perform special handling for the Syn-sent state.
  3158. //
  3159. } else if (Socket->State == TcpStateSynSent) {
  3160. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3161. //
  3162. // Check the acknowledge number, it had better match the initial
  3163. // sequence number. If it doesn't, send a reset (unless this packet
  3164. // already is a reset).
  3165. //
  3166. if (AcknowledgeNumber != Socket->SendNextNetworkSequence) {
  3167. if ((Header->Flags & TCP_HEADER_FLAG_RESET) == 0) {
  3168. ResetSequenceNumber = AcknowledgeNumber;
  3169. ResetFlags = TCP_HEADER_FLAG_RESET |
  3170. TCP_HEADER_FLAG_ACKNOWLEDGE;
  3171. Socket->SendUnacknowledgedSequence = ResetSequenceNumber;
  3172. NetpTcpSendControlPacket(Socket, ResetFlags);
  3173. Socket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  3174. NET_SOCKET_SET_LAST_ERROR(&(Socket->NetSocket),
  3175. STATUS_CONNECTION_RESET);
  3176. NetpTcpCloseOutSocket(Socket, FALSE);
  3177. }
  3178. return;
  3179. }
  3180. //
  3181. // Update the unacknowledged sequence number directly because an
  3182. // acknowledge may be sent directly below. Because this was done,
  3183. // the window update also needs to be done explicitly.
  3184. //
  3185. Socket->SendUnacknowledgedSequence = AcknowledgeNumber;
  3186. Socket->SendWindowSize = NETWORK_TO_CPU16(Header->WindowSize) <<
  3187. Socket->SendWindowScale;
  3188. Socket->SendWindowUpdateSequence = RemoteSequence;
  3189. Socket->SendWindowUpdateAcknowledge = AcknowledgeNumber;
  3190. }
  3191. //
  3192. // In the Syn-sent state, a reset is only valid if an ACK is present
  3193. // and it acknowledges the the sent SYN. Abort the connection if this
  3194. // is the case. Otherwise drop the packet.
  3195. //
  3196. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  3197. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3198. ASSERT(AcknowledgeNumber == Socket->SendNextNetworkSequence);
  3199. Socket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  3200. NET_SOCKET_SET_LAST_ERROR(&(Socket->NetSocket),
  3201. STATUS_CONNECTION_RESET);
  3202. NetpTcpCloseOutSocket(Socket, FALSE);
  3203. }
  3204. return;
  3205. //
  3206. // The ACK bit is either not there or is valid. Check for the SYN bit.
  3207. // Initialize the remote sequence number variables if so.
  3208. //
  3209. } else if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  3210. Socket->ReceiveInitialSequence = RemoteSequence;
  3211. Socket->ReceiveNextSequence = RemoteSequence + 1;
  3212. Socket->ReceiveUnreadSequence = Socket->ReceiveNextSequence;
  3213. //
  3214. // Process the options to get the max segment size and window scale
  3215. // that likely came with the SYN.
  3216. //
  3217. NetpTcpProcessPacketOptions(Socket, Header, Packet);
  3218. //
  3219. // If the local unacknowledged number is not equal to the initial
  3220. // sequence, then a SYN was sent and acknowledged. Move directly to
  3221. // the established state in this case and send an ACK. Send an ACK
  3222. // directly to expedite this critical phase (at the expense of not
  3223. // coalescing this ACK with pending data).
  3224. //
  3225. if (Socket->SendUnacknowledgedSequence !=
  3226. Socket->SendInitialSequence) {
  3227. NetpTcpSetState(Socket, TcpStateEstablished);
  3228. NetpTcpSendControlPacket(Socket, 0);
  3229. //
  3230. // The remote host isn't ACKing the SYN, it just happened to send
  3231. // its own at the same time. Send a SYN+ACK and move to the syn-
  3232. // received state.
  3233. //
  3234. } else {
  3235. NetpTcpSetState(Socket, TcpStateSynReceived);
  3236. return;
  3237. }
  3238. SynHandled = TRUE;
  3239. //
  3240. // If neither the FIN nor RESET flags were set, drop the packet.
  3241. //
  3242. } else {
  3243. return;
  3244. }
  3245. }
  3246. //
  3247. // Perform general processing for all states. Check to see if the sequence
  3248. // number is acceptable.
  3249. //
  3250. SegmentLength = Packet->FooterOffset - Packet->DataOffset;
  3251. SegmentData = Packet->Buffer + Packet->DataOffset;
  3252. SegmentAcceptable = NetpTcpIsReceiveSegmentAcceptable(Socket,
  3253. RemoteSequence,
  3254. SegmentLength);
  3255. //
  3256. // If the segment is not acceptable at all, send an ACK, unless the reset
  3257. // bit is set, in which case the packet is dropped.
  3258. //
  3259. if ((SegmentAcceptable == FALSE) && (SynHandled == FALSE)) {
  3260. if ((Header->Flags & TCP_HEADER_FLAG_RESET) == 0) {
  3261. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0) {
  3262. Socket->Flags |= TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  3263. NetpTcpTimerAddReference();
  3264. }
  3265. }
  3266. return;
  3267. }
  3268. //
  3269. // Next up, check the reset bit. If it is set, close the connection. The
  3270. // exception in the TCP specification is if the socket is in the
  3271. // Syn-received state and was previously in the Listening state. If that's
  3272. // the case, then the socket should return the listening state. Note,
  3273. // however, that incoming connections spawn a new socket. So, even in this
  3274. // case, close out the socket; there is another socket still listening.
  3275. //
  3276. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  3277. Socket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  3278. NET_SOCKET_SET_LAST_ERROR(&(Socket->NetSocket),
  3279. STATUS_CONNECTION_RESET);
  3280. NetpTcpCloseOutSocket(Socket, FALSE);
  3281. return;
  3282. }
  3283. //
  3284. // Check the SYN bit, which should really not be set at this point. If it
  3285. // is, send a reset and close the connection. Note that if the SYN were not
  3286. // in the valid window this code would not be reached, an ACK would be
  3287. // sent instead above. Send a reset, flush all queues, and close out the
  3288. // socket.
  3289. //
  3290. if (((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) && (SynHandled == FALSE)) {
  3291. ResetFlags = TCP_HEADER_FLAG_RESET | TCP_HEADER_FLAG_ACKNOWLEDGE;
  3292. NetpTcpSendControlPacket(Socket, ResetFlags);
  3293. Socket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  3294. NET_SOCKET_SET_LAST_ERROR(&(Socket->NetSocket),
  3295. STATUS_CONNECTION_RESET);
  3296. NetpTcpCloseOutSocket(Socket, FALSE);
  3297. return;
  3298. }
  3299. //
  3300. // If the ACK bit is not set here, drop the packet and return.
  3301. //
  3302. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) == 0) {
  3303. return;
  3304. }
  3305. //
  3306. // The ACK bit is definitely sent, process the acknowledge number. If this
  3307. // fails, it is because the socket was closed via reset or the last ACK was
  3308. // received. Exit. Don't touch the socket again.
  3309. //
  3310. Status = NetpTcpProcessAcknowledge(Socket,
  3311. AcknowledgeNumber,
  3312. RemoteSequence,
  3313. SegmentLength,
  3314. Header->WindowSize);
  3315. if (!KSUCCESS(Status)) {
  3316. ASSERT((Status == STATUS_CONNECTION_CLOSED) ||
  3317. (Status == STATUS_CONNECTION_RESET));
  3318. return;
  3319. }
  3320. //
  3321. // If the acknowledge was not enough to bring the SYN-Received state
  3322. // forward to the established state, then the connection was reset.
  3323. //
  3324. ASSERT(Socket->State != TcpStateSynReceived);
  3325. //
  3326. // At last, process any received data.
  3327. //
  3328. if ((Socket->State == TcpStateEstablished) ||
  3329. (Socket->State == TcpStateFinWait1) ||
  3330. (Socket->State == TcpStateFinWait2)) {
  3331. NetpTcpProcessReceivedDataSegment(Socket,
  3332. RemoteSequence,
  3333. SegmentData,
  3334. SegmentLength,
  3335. Header);
  3336. }
  3337. //
  3338. // Finally, take a look at the FIN bit.
  3339. //
  3340. if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  3341. //
  3342. // Don't process the FIN bit if the state is Closed, Listening, or
  3343. // Syn-Sent, as the incoming sequence number cannot be validated in
  3344. // these states.
  3345. //
  3346. if ((Socket->State == TcpStateClosed) ||
  3347. (Socket->State == TcpStateListening) ||
  3348. (Socket->State == TcpStateSynSent)) {
  3349. return;
  3350. }
  3351. //
  3352. // Calculate the final remote sequence.
  3353. //
  3354. RemoteFinalSequence = RemoteSequence + SegmentLength;
  3355. //
  3356. // The final sequence number has been received. Save it. Don't move the
  3357. // state machine forward just yet; all the data needs to be received
  3358. // first. Also, don't give the remote side a second chance at sending
  3359. // the final sequence. If the remote is being a good citizen then it
  3360. // should match the recorded final sequence.
  3361. //
  3362. if ((Socket->Flags & TCP_SOCKET_FLAG_RECEIVE_FINAL_SEQUENCE_VALID) ==
  3363. 0) {
  3364. Socket->ReceiveFinalSequence = RemoteFinalSequence;
  3365. Socket->Flags |= TCP_SOCKET_FLAG_RECEIVE_FINAL_SEQUENCE_VALID;
  3366. } else if ((NetTcpDebugPrintSequenceNumbers != FALSE) &&
  3367. (Socket->ReceiveFinalSequence != RemoteFinalSequence)) {
  3368. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  3369. RtlDebugPrint(" RX second FIN segment sequence %d. Expected %d.\n",
  3370. (RemoteFinalSequence -
  3371. Socket->ReceiveInitialSequence),
  3372. (Socket->ReceiveFinalSequence -
  3373. Socket->ReceiveInitialSequence));
  3374. }
  3375. }
  3376. //
  3377. // If a FIN has been received and all the data up to that FIN has been
  3378. // received, then it's time to acknowledge the FIN and move the state
  3379. // machine. This also handles the case of a second FIN.
  3380. //
  3381. if (((Socket->Flags & TCP_SOCKET_FLAG_RECEIVE_FINAL_SEQUENCE_VALID) != 0) &&
  3382. (Socket->ReceiveNextSequence >= Socket->ReceiveFinalSequence)) {
  3383. //
  3384. // This is the first time the FIN has been seen. Step over it and
  3385. // release anybody waiting to read as there's no more data coming in.
  3386. //
  3387. if (Socket->ReceiveNextSequence == Socket->ReceiveFinalSequence) {
  3388. Socket->ReceiveNextSequence += 1;
  3389. IoSetIoObjectState(IoState,
  3390. POLL_EVENT_IN | POLL_EVENT_IN_HIGH_PRIORITY,
  3391. TRUE);
  3392. //
  3393. // From the established state, enter the close-wait state. Note
  3394. // that if the socket was in the SYN-Received state when the packet
  3395. // arrived that it transitioned to the established state when the
  3396. // ACK was processed.
  3397. //
  3398. if (Socket->State == TcpStateEstablished) {
  3399. NetpTcpSetState(Socket, TcpStateCloseWait);
  3400. //
  3401. // If a FIN was received but the state is still Fin-Wait-1, then
  3402. // the remote side started closing the connection but hasn't seen
  3403. // the sent FIN yet. Move to the closing state.
  3404. //
  3405. } else if (Socket->State == TcpStateFinWait1) {
  3406. NetpTcpSetState(Socket, TcpStateClosing);
  3407. //
  3408. // In the Fin-Wait-2 state, enter the time-wait state.
  3409. //
  3410. } else if (Socket->State == TcpStateFinWait2) {
  3411. NetpTcpSetState(Socket, TcpStateTimeWait);
  3412. //
  3413. // Other states are not expected to received the first FIN.
  3414. //
  3415. } else {
  3416. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  3417. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  3418. RtlDebugPrint(" RX unexpected FIN in state %d.\n",
  3419. Socket->State);
  3420. }
  3421. return;
  3422. }
  3423. //
  3424. // If the FIN has already been received and acknowledged and another
  3425. // FIN has come in then process it. This ignores non-FIN packets.
  3426. //
  3427. } else if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  3428. //
  3429. // In the time-wait state, restart the timer.
  3430. //
  3431. if (Socket->State == TcpStateTimeWait) {
  3432. TCP_SET_DEFAULT_TIMEOUT(Socket);
  3433. //
  3434. // Both the closing state and last acknowledge state are waiting on
  3435. // an ACK for the sent FIN. If the other side sends a FIN (without
  3436. // the correct ACK), just reset the FIN resend retry and timeout.
  3437. // At least it is still responding.
  3438. //
  3439. } else if ((Socket->State == TcpStateClosing) ||
  3440. (Socket->State == TcpStateLastAcknowledge)) {
  3441. Socket->RetryTime = 0;
  3442. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  3443. TCP_UPDATE_RETRY_TIME(Socket);
  3444. TCP_SET_DEFAULT_TIMEOUT(Socket);
  3445. //
  3446. // The close-wait state could also get a second FIN, but there is
  3447. // nothing to do other than ACK it.
  3448. //
  3449. } else if (Socket->State != TcpStateCloseWait) {
  3450. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  3451. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  3452. RtlDebugPrint(" RX unexpected FIN in state %d.\n",
  3453. Socket->State);
  3454. }
  3455. return;
  3456. }
  3457. //
  3458. // Drop packets received after the FIN that do not contain a FIN.
  3459. //
  3460. } else {
  3461. return;
  3462. }
  3463. //
  3464. // Schedule an ACK to respond to the FIN.
  3465. //
  3466. if ((Socket->State & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0) {
  3467. Socket->Flags |= TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  3468. NetpTcpTimerAddReference();
  3469. }
  3470. }
  3471. //
  3472. // If the socket is in a keep alive state then update the keep alive time
  3473. // and arm the keep alive timer. The remote side is still alive!
  3474. //
  3475. if (((Socket->Flags & TCP_SOCKET_FLAG_KEEP_ALIVE) != 0) &&
  3476. (TCP_IS_KEEP_ALIVE_STATE(Socket->State) != FALSE)) {
  3477. DueTime = KeGetRecentTimeCounter();
  3478. DueTime += KeConvertMicrosecondsToTimeTicks(Socket->KeepAliveTimeout *
  3479. MICROSECONDS_PER_SECOND);
  3480. Socket->KeepAliveTime = DueTime;
  3481. Socket->KeepAliveProbeCount = 0;
  3482. NetpTcpArmKeepAliveTimer(DueTime);
  3483. }
  3484. return;
  3485. }
  3486. VOID
  3487. NetpTcpHandleUnconnectedPacket (
  3488. PNET_LINK Link,
  3489. PTCP_HEADER Header,
  3490. PNET_PACKET_BUFFER Packet,
  3491. PNETWORK_ADDRESS SourceAddress,
  3492. PNETWORK_ADDRESS DestinationAddress
  3493. )
  3494. /*++
  3495. Routine Description:
  3496. This routine is called to handle an invalid received packet that is not
  3497. part of any connection.
  3498. Arguments:
  3499. Link - Supplies a pointer to the link the packet was received on.
  3500. Header - Supplies a pointer to the TCP header.
  3501. Packet - Supplies a pointer to the received packet information.
  3502. SourceAddress - Supplies a pointer to the source (remote) address that the
  3503. packet originated from. This memory will not be referenced once the
  3504. function returns, it can be stack allocated.
  3505. DestinationAddress - Supplies a pointer to the destination (local) address
  3506. that the packet is heading to. This memory will not be referenced once
  3507. the function returns, it can be stack allocated.
  3508. Return Value:
  3509. None.
  3510. --*/
  3511. {
  3512. BOOL LockHeld;
  3513. ULONGLONG Milliseconds;
  3514. PIO_HANDLE NewIoHandle;
  3515. PTCP_SOCKET NewTcpSocket;
  3516. ULONG ResetAcknowledgeNumber;
  3517. ULONG ResetFlags;
  3518. ULONG ResetSequenceNumber;
  3519. ULONG SegmentLength;
  3520. KSTATUS Status;
  3521. ASSERT(Link != NULL);
  3522. LockHeld = FALSE;
  3523. //
  3524. // Notify the debugger of this rogue packet.
  3525. //
  3526. if (NetTcpDebugPrintAllPackets != FALSE) {
  3527. Milliseconds = (HlQueryTimeCounter() * MILLISECONDS_PER_SECOND) /
  3528. HlQueryTimeCounterFrequency();
  3529. RtlDebugPrint("TCP %I64dms: ", Milliseconds);
  3530. NetDebugPrintAddress(SourceAddress);
  3531. if (NetTcpDebugPrintLocalAddress != FALSE) {
  3532. RtlDebugPrint(" to ");
  3533. NetDebugPrintAddress(DestinationAddress);
  3534. }
  3535. }
  3536. //
  3537. // Do nothing if this is a reset packet.
  3538. //
  3539. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  3540. if (NetTcpDebugPrintAllPackets != FALSE) {
  3541. RtlDebugPrint(" TCP RST packet from port %d for port %d has no "
  3542. "socket, ignoring packet.\n",
  3543. SourceAddress->Port,
  3544. DestinationAddress->Port);
  3545. }
  3546. return;
  3547. }
  3548. //
  3549. // Otherwise, send a reset back to the sender.
  3550. //
  3551. if (NetTcpDebugPrintAllPackets != FALSE) {
  3552. RtlDebugPrint(" TCP packet from port %d for port %d has no socket, "
  3553. "sending reset.\n",
  3554. SourceAddress->Port,
  3555. DestinationAddress->Port);
  3556. }
  3557. //
  3558. // Always send a reset.
  3559. //
  3560. ResetFlags = TCP_HEADER_FLAG_RESET;
  3561. //
  3562. // If an ACK was received, the acknoledgement number is used as the
  3563. // sequence number and no ACK is sent.
  3564. //
  3565. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3566. ResetFlags |= TCP_HEADER_FLAG_ACKNOWLEDGE;
  3567. ResetSequenceNumber = NETWORK_TO_CPU32(Header->AcknowledgmentNumber);
  3568. ResetAcknowledgeNumber = 0;
  3569. //
  3570. // Otherwise the sequence number is zero and an ACK is sent with
  3571. // the sender's sequence number plus length as the acknowledgement
  3572. // number.
  3573. //
  3574. } else {
  3575. ResetSequenceNumber = 0;
  3576. SegmentLength = Packet->FooterOffset - Packet->DataOffset;
  3577. //
  3578. // Remember to count SYNs and FINs as part of the data length.
  3579. //
  3580. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  3581. SegmentLength += 1;
  3582. }
  3583. if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  3584. SegmentLength += 1;
  3585. }
  3586. ResetAcknowledgeNumber = NETWORK_TO_CPU32(Header->SequenceNumber) +
  3587. SegmentLength;
  3588. }
  3589. //
  3590. // Create a socket that will be used to send this transmission.
  3591. //
  3592. ASSERT(SourceAddress->Domain == DestinationAddress->Domain);
  3593. Status = IoSocketCreate(DestinationAddress->Domain,
  3594. NetSocketStream,
  3595. SOCKET_INTERNET_PROTOCOL_TCP,
  3596. 0,
  3597. &NewIoHandle);
  3598. if (!KSUCCESS(Status)) {
  3599. goto TcpHandleUnconnectedPacketEnd;
  3600. }
  3601. Status = IoGetSocketFromHandle(NewIoHandle, (PVOID)&NewTcpSocket);
  3602. if (!KSUCCESS(Status)) {
  3603. goto TcpHandleUnconnectedPacketEnd;
  3604. }
  3605. IoSocketAddReference(&(NewTcpSocket->NetSocket.KernelSocket));
  3606. KeAcquireQueuedLock(NewTcpSocket->Lock);
  3607. LockHeld = TRUE;
  3608. //
  3609. // Bind the new socket to the destination (local) address. In most cases
  3610. // this should not conflict with an existing socket's binding to a local
  3611. // address. The system only ended up here because no suitable socket was
  3612. // found to handle the packet. If the bind ends up failing, tough luck. The
  3613. // packet gets dropped without a response.
  3614. //
  3615. Status = NewTcpSocket->NetSocket.Network->Interface.BindToAddress(
  3616. &(NewTcpSocket->NetSocket),
  3617. Link,
  3618. DestinationAddress);
  3619. if (!KSUCCESS(Status)) {
  3620. goto TcpHandleUnconnectedPacketEnd;
  3621. }
  3622. //
  3623. // Connect the new socket to the remote address.
  3624. //
  3625. Status = NewTcpSocket->NetSocket.Network->Interface.Connect(
  3626. (PNET_SOCKET)NewTcpSocket,
  3627. SourceAddress);
  3628. if (!KSUCCESS(Status)) {
  3629. goto TcpHandleUnconnectedPacketEnd;
  3630. }
  3631. //
  3632. // Initialize the correct sequence and acknowledgement numbers and then
  3633. // send the reset.
  3634. //
  3635. NewTcpSocket->SendUnacknowledgedSequence = ResetSequenceNumber;
  3636. NewTcpSocket->ReceiveNextSequence = ResetAcknowledgeNumber;
  3637. NetpTcpSendControlPacket(NewTcpSocket, ResetFlags);
  3638. TcpHandleUnconnectedPacketEnd:
  3639. //
  3640. // Always close out the new socket. It should not remain open for
  3641. // transmissions.
  3642. //
  3643. if (NewTcpSocket != NULL) {
  3644. ASSERT(LockHeld != FALSE);
  3645. NetpTcpCloseOutSocket(NewTcpSocket, FALSE);
  3646. }
  3647. if (LockHeld != FALSE) {
  3648. ASSERT(NewTcpSocket != NULL);
  3649. KeReleaseQueuedLock(NewTcpSocket->Lock);
  3650. IoSocketReleaseReference(&(NewTcpSocket->NetSocket.KernelSocket));
  3651. }
  3652. if (NewIoHandle != INVALID_HANDLE) {
  3653. IoClose(NewIoHandle);
  3654. }
  3655. return;
  3656. }
  3657. VOID
  3658. NetpTcpFillOutHeader (
  3659. PTCP_SOCKET Socket,
  3660. PNET_PACKET_BUFFER Packet,
  3661. ULONG SequenceNumber,
  3662. USHORT ExtraFlags,
  3663. ULONG OptionsLength,
  3664. USHORT NonUrgentOffset,
  3665. ULONG DataLength
  3666. )
  3667. /*++
  3668. Routine Description:
  3669. This routine fills out a TCP header that's going to be sent. This routine
  3670. assumes the socket lock is already held.
  3671. Arguments:
  3672. Socket - Supplies a pointer to the TCP socket owning the connection.
  3673. Packet - Supplies a pointer to the packet for which the header should be
  3674. filled out.
  3675. SequenceNumber - Supplies the sequence number to use for this packet.
  3676. ExtraFlags - Supplies any flags to set in the header. Since the ACK flag is
  3677. always set, it will be set by default unless it is specified in this
  3678. parameter, in which case it won't be. Said differently, the semantics
  3679. for the ACK flag are backwards of all the other flags, for convenience.
  3680. OptionsLength - Supplies the length of any header options (this is usually
  3681. 0).
  3682. NonUrgentOffset - Supplies the offset of the non-urgent data. Usually this
  3683. is zero as there is no urgent data.
  3684. DataLength - Supplies the length of the data field.
  3685. Return Value:
  3686. None.
  3687. --*/
  3688. {
  3689. PVOID Buffer;
  3690. USHORT Checksum;
  3691. PTCP_HEADER Header;
  3692. ULONG PacketSize;
  3693. ULONG RelativeAcknowledgeNumber;
  3694. ULONG RelativeSequenceNumber;
  3695. ULONG WindowSize;
  3696. //
  3697. // Acknowledges come with every header (except the first, but this flag is
  3698. // never going to be set then anyway).
  3699. //
  3700. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) != 0) {
  3701. Socket->Flags &= ~TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  3702. NetpTcpTimerReleaseReference();
  3703. }
  3704. Buffer = Packet->Buffer + Packet->DataOffset;
  3705. Header = (PTCP_HEADER)Buffer;
  3706. Header->SourcePort = CPU_TO_NETWORK16(Socket->NetSocket.LocalAddress.Port);
  3707. Header->DestinationPort =
  3708. CPU_TO_NETWORK16(Socket->NetSocket.RemoteAddress.Port);
  3709. Header->SequenceNumber = CPU_TO_NETWORK32(SequenceNumber);
  3710. Header->HeaderLength = ((sizeof(TCP_HEADER) + OptionsLength) >> 2) <<
  3711. TCP_HEADER_LENGTH_SHIFT;
  3712. Header->Flags = ExtraFlags ^ TCP_HEADER_FLAG_ACKNOWLEDGE;
  3713. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3714. Header->AcknowledgmentNumber =
  3715. CPU_TO_NETWORK32(Socket->ReceiveNextSequence);
  3716. } else {
  3717. Header->AcknowledgmentNumber = 0;
  3718. }
  3719. //
  3720. // The window size is the original window size minus the amount of data
  3721. // in the buffer.
  3722. //
  3723. WindowSize = Socket->ReceiveWindowFreeSize >> Socket->ReceiveWindowScale;
  3724. Header->WindowSize = CPU_TO_NETWORK16((USHORT)WindowSize);
  3725. Header->NonUrgentOffset = NonUrgentOffset;
  3726. Header->Checksum = 0;
  3727. PacketSize = sizeof(TCP_HEADER) + OptionsLength + DataLength;
  3728. if ((Socket->NetSocket.Link->Properties.ChecksumFlags &
  3729. NET_LINK_CHECKSUM_FLAG_TRANSMIT_TCP_OFFLOAD) == 0) {
  3730. Checksum = NetpTcpChecksumData(Header,
  3731. PacketSize,
  3732. &(Socket->NetSocket.LocalAddress),
  3733. &(Socket->NetSocket.RemoteAddress));
  3734. Header->Checksum = Checksum;
  3735. } else {
  3736. Packet->Flags |= NET_PACKET_FLAG_TCP_CHECKSUM_OFFLOAD;
  3737. }
  3738. //
  3739. // Print this packet if debugging is enabled.
  3740. //
  3741. if (NetTcpDebugPrintAllPackets != FALSE) {
  3742. NetpTcpPrintSocketEndpoints(Socket, TRUE);
  3743. RtlDebugPrint(" TX [");
  3744. if ((Header->Flags & TCP_HEADER_FLAG_FIN) != 0) {
  3745. RtlDebugPrint("FIN ");
  3746. }
  3747. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  3748. RtlDebugPrint("SYN ");
  3749. }
  3750. if ((Header->Flags & TCP_HEADER_FLAG_RESET) != 0) {
  3751. RtlDebugPrint("RST ");
  3752. }
  3753. if ((Header->Flags & TCP_HEADER_FLAG_PUSH) != 0) {
  3754. RtlDebugPrint("PSH ");
  3755. }
  3756. if ((Header->Flags & TCP_HEADER_FLAG_URGENT) != 0) {
  3757. RtlDebugPrint("URG");
  3758. }
  3759. RelativeAcknowledgeNumber = 0;
  3760. if ((Header->Flags & TCP_HEADER_FLAG_ACKNOWLEDGE) != 0) {
  3761. RtlDebugPrint("ACK");
  3762. RelativeAcknowledgeNumber = Socket->ReceiveNextSequence -
  3763. Socket->ReceiveInitialSequence;
  3764. }
  3765. RelativeSequenceNumber = SequenceNumber - Socket->SendInitialSequence;
  3766. RtlDebugPrint("] \n Seq=%d Ack=%d Win=%d Len=%d\n",
  3767. RelativeSequenceNumber,
  3768. RelativeAcknowledgeNumber,
  3769. WindowSize << Socket->ReceiveWindowScale,
  3770. DataLength);
  3771. }
  3772. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  3773. NetpTcpPrintSocketEndpoints(Socket, TRUE);
  3774. RtlDebugPrint(" TX Segment %d, length %d.\n",
  3775. SequenceNumber - Socket->SendInitialSequence,
  3776. DataLength);
  3777. }
  3778. return;
  3779. }
  3780. USHORT
  3781. NetpTcpChecksumData (
  3782. PVOID Data,
  3783. ULONG DataLength,
  3784. PNETWORK_ADDRESS SourceAddress,
  3785. PNETWORK_ADDRESS DestinationAddress
  3786. )
  3787. /*++
  3788. Routine Description:
  3789. This routine computes the checksum for a TCP packet and returns it in
  3790. network byte order.
  3791. Arguments:
  3792. Data - Supplies a pointer to the beginning of the TCP header.
  3793. DataLength - Supplies the length of the header, options, and data, in bytes.
  3794. SourceAddress - Supplies a pointer to the source address of the packet,
  3795. used to compute the pseudo header.
  3796. DestinationAddress - Supplies a pointer to the destination address of the
  3797. packet, used to compute the pseudo header used in the checksum.
  3798. Return Value:
  3799. Returns the checksum for the given packet.
  3800. --*/
  3801. {
  3802. PUCHAR BytePointer;
  3803. PIP4_ADDRESS Ip4Address;
  3804. PULONG LongPointer;
  3805. ULONG NextValue;
  3806. USHORT ShortOne;
  3807. PUSHORT ShortPointer;
  3808. USHORT ShortTwo;
  3809. ULONG Sum;
  3810. Sum = 0;
  3811. ASSERT(SourceAddress->Domain == NetDomainIp4);
  3812. ASSERT(DestinationAddress->Domain == SourceAddress->Domain);
  3813. Ip4Address = (PIP4_ADDRESS)SourceAddress;
  3814. Sum = Ip4Address->Address;
  3815. Ip4Address = (PIP4_ADDRESS)DestinationAddress;
  3816. Sum += Ip4Address->Address;
  3817. if (Sum < Ip4Address->Address) {
  3818. Sum += 1;
  3819. }
  3820. ASSERT(DataLength < MAX_USHORT);
  3821. NextValue = (RtlByteSwapUshort((USHORT)DataLength) << 16) |
  3822. (SOCKET_INTERNET_PROTOCOL_TCP << 8);
  3823. Sum += NextValue;
  3824. if (Sum < NextValue) {
  3825. Sum += 1;
  3826. }
  3827. LongPointer = (PULONG)Data;
  3828. while (DataLength >= sizeof(ULONG)) {
  3829. NextValue = *LongPointer;
  3830. LongPointer += 1;
  3831. Sum += NextValue;
  3832. if (Sum < NextValue) {
  3833. Sum += 1;
  3834. }
  3835. DataLength -= sizeof(ULONG);
  3836. }
  3837. BytePointer = (PUCHAR)LongPointer;
  3838. if ((DataLength & sizeof(USHORT)) != 0) {
  3839. ShortPointer = (PUSHORT)BytePointer;
  3840. NextValue = (USHORT)*ShortPointer;
  3841. Sum += NextValue;
  3842. if (Sum < NextValue) {
  3843. Sum += 1;
  3844. }
  3845. BytePointer += sizeof(USHORT);
  3846. }
  3847. if ((DataLength & sizeof(UCHAR)) != 0) {
  3848. NextValue = (UCHAR)*BytePointer;
  3849. Sum += NextValue;
  3850. if (Sum < NextValue) {
  3851. Sum += 1;
  3852. }
  3853. }
  3854. //
  3855. // Fold the 32-bit value down to 16-bits.
  3856. //
  3857. ShortOne = (USHORT)Sum;
  3858. ShortTwo = (USHORT)(Sum >> 16);
  3859. ShortTwo += ShortOne;
  3860. if (ShortTwo < ShortOne) {
  3861. ShortTwo += 1;
  3862. }
  3863. return (USHORT)~ShortTwo;
  3864. }
  3865. BOOL
  3866. NetpTcpIsReceiveSegmentAcceptable (
  3867. PTCP_SOCKET Socket,
  3868. ULONG SequenceNumber,
  3869. ULONG SegmentLength
  3870. )
  3871. /*++
  3872. Routine Description:
  3873. This routine determines if any part of the segment is in the window of
  3874. acceptable sequence numbers for the socket. This routine assumes the socket
  3875. lock is already held.
  3876. Arguments:
  3877. Socket - Supplies a pointer to the socket.
  3878. SequenceNumber - Supplies a pointer to the sequence number to query for
  3879. validity.
  3880. SegmentLength - Supplies the number of bytes in the incoming segment.
  3881. Return Value:
  3882. TRUE if the segment falls at least partially in the receive window.
  3883. FALSE if the segment is outside the receive window.
  3884. --*/
  3885. {
  3886. BOOL SegmentAcceptable;
  3887. ULONG SegmentEnd;
  3888. ULONG WindowBegin;
  3889. ULONG WindowEnd;
  3890. SegmentAcceptable = FALSE;
  3891. WindowBegin = Socket->ReceiveNextSequence;
  3892. WindowEnd = WindowBegin + Socket->ReceiveWindowFreeSize;
  3893. //
  3894. // Handle zero-length segments.
  3895. //
  3896. if (SegmentLength == 0) {
  3897. //
  3898. // If the window size is zero, then the sequence number must match the
  3899. // expected number exactly.
  3900. //
  3901. if (Socket->ReceiveWindowFreeSize == 0) {
  3902. if (SequenceNumber == Socket->ReceiveNextSequence) {
  3903. SegmentAcceptable = TRUE;
  3904. }
  3905. //
  3906. // If the window size is valid, then sequence number must be within the
  3907. // window.
  3908. //
  3909. } else if (WindowEnd > WindowBegin) {
  3910. if ((SequenceNumber >= WindowBegin) &&
  3911. (SequenceNumber < WindowEnd)) {
  3912. SegmentAcceptable = TRUE;
  3913. }
  3914. //
  3915. // If the window size is valid, but wrapped, then sequence number must
  3916. // be within the window.
  3917. //
  3918. } else {
  3919. ASSERT(WindowBegin != WindowEnd);
  3920. if ((SequenceNumber >= WindowBegin) ||
  3921. (SequenceNumber < WindowEnd)) {
  3922. SegmentAcceptable = TRUE;
  3923. }
  3924. }
  3925. //
  3926. // If the segment is non-zero, then the segment is valid if the beginning
  3927. // or the end falls within the window.
  3928. //
  3929. } else {
  3930. SegmentAcceptable = FALSE;
  3931. SegmentEnd = SequenceNumber + SegmentLength - 1;
  3932. //
  3933. // It's acceptable if at least one of these conditions is met:
  3934. // 1) The starting sequence number is within the window.
  3935. // 2) The ending sequence number is within the window.
  3936. // Watch out here for the window straddling the rollover.
  3937. //
  3938. if (WindowEnd >= WindowBegin) {
  3939. if ((SequenceNumber >= WindowBegin) &&
  3940. (SequenceNumber < WindowEnd)) {
  3941. SegmentAcceptable = TRUE;
  3942. }
  3943. if ((SegmentEnd >= WindowBegin) && (SegmentEnd < WindowEnd)) {
  3944. SegmentAcceptable = TRUE;
  3945. }
  3946. //
  3947. // Yikes, the window straddles the rollover. Do the same logic as above
  3948. // but a bit more carefully.
  3949. //
  3950. } else {
  3951. if ((SequenceNumber >= WindowBegin) ||
  3952. (SequenceNumber < WindowEnd)) {
  3953. SegmentAcceptable = TRUE;
  3954. }
  3955. if ((SegmentEnd >= WindowBegin) || (SegmentEnd < WindowEnd)) {
  3956. SegmentAcceptable = TRUE;
  3957. }
  3958. }
  3959. if (((SequenceNumber >= Socket->ReceiveNextSequence) &&
  3960. (SequenceNumber < WindowEnd)) ||
  3961. ((SegmentEnd >= Socket->ReceiveNextSequence) &&
  3962. (SegmentEnd < WindowEnd))) {
  3963. SegmentAcceptable = TRUE;
  3964. }
  3965. //
  3966. // If the segment length is non-zero but the window is zero, then this
  3967. // is no good.
  3968. //
  3969. if (Socket->ReceiveWindowFreeSize == 0) {
  3970. SegmentAcceptable = FALSE;
  3971. }
  3972. }
  3973. return SegmentAcceptable;
  3974. }
  3975. KSTATUS
  3976. NetpTcpProcessAcknowledge (
  3977. PTCP_SOCKET Socket,
  3978. ULONG AcknowledgeNumber,
  3979. ULONG SequenceNumber,
  3980. ULONG DataLength,
  3981. USHORT WindowSize
  3982. )
  3983. /*++
  3984. Routine Description:
  3985. This routine handles the update of TCP state based on the incoming
  3986. acknowledge number. This routine assumes the socket lock is already held.
  3987. Arguments:
  3988. Socket - Supplies a pointer to the socket.
  3989. AcknowledgeNumber - Supplies the acknowledge number sent by the remote
  3990. host (after being converted back into CPU endianness).
  3991. SequenceNumber - Supplies the remote sequence number that came along with
  3992. this acknowledge number.
  3993. DataLength - Supplies the number of bytes of data that came along with this
  3994. acknowledge number.
  3995. WindowSize - Supplies the window size that came along with this packet,
  3996. which may or may not get saved as the new send window. This value is
  3997. expected to be straight from the header, in network order.
  3998. Return Value:
  3999. Status code.
  4000. --*/
  4001. {
  4002. BOOL AcknowledgeValid;
  4003. ULONGLONG CurrentTime;
  4004. PIO_OBJECT_STATE IoState;
  4005. ULONG ReceiveWindowEnd;
  4006. ULONG RelativeAcknowledgeNumber;
  4007. ULONG ResetFlags;
  4008. ULONG ScaledWindowSize;
  4009. BOOL UpdateValid;
  4010. ASSERT(Socket->NetSocket.KernelSocket.ReferenceCount >= 1);
  4011. CurrentTime = 0;
  4012. IoState = Socket->NetSocket.KernelSocket.IoState;
  4013. ScaledWindowSize = NETWORK_TO_CPU16(WindowSize) <<
  4014. Socket->SendWindowScale;
  4015. //
  4016. // If this is the Syn-Received state, then an ACK is what's needed to bring
  4017. // this socket to the established state.
  4018. //
  4019. if (Socket->State == TcpStateSynReceived) {
  4020. //
  4021. // If the acnowledge number is valid, move to the established state. At
  4022. // this point, only a SYN should have been sent.
  4023. //
  4024. ASSERT((Socket->SendUnacknowledgedSequence + 1) ==
  4025. Socket->SendNextNetworkSequence);
  4026. ASSERT(Socket->SendNextNetworkSequence ==
  4027. Socket->SendNextBufferSequence);
  4028. if (AcknowledgeNumber == Socket->SendNextNetworkSequence) {
  4029. NetpTcpSetState(Socket, TcpStateEstablished);
  4030. //
  4031. // The acknowledge number is not valid, send a reset using the
  4032. // acknowledge number as the sequence number.
  4033. //
  4034. } else {
  4035. Socket->SendUnacknowledgedSequence = AcknowledgeNumber;
  4036. ResetFlags = TCP_HEADER_FLAG_RESET | TCP_HEADER_FLAG_ACKNOWLEDGE;
  4037. NetpTcpSendControlPacket(Socket, ResetFlags);
  4038. Socket->Flags |= TCP_SOCKET_FLAG_CONNECTION_RESET;
  4039. NET_SOCKET_SET_LAST_ERROR(&(Socket->NetSocket),
  4040. STATUS_CONNECTION_RESET);
  4041. NetpTcpCloseOutSocket(Socket, FALSE);
  4042. return STATUS_CONNECTION_RESET;
  4043. }
  4044. }
  4045. //
  4046. // Determine if the acknowledge number is within the send window. Watch out
  4047. // if the send window is partially wrapped around.
  4048. //
  4049. AcknowledgeValid = FALSE;
  4050. if (Socket->SendNextNetworkSequence >= Socket->SendUnacknowledgedSequence) {
  4051. if ((AcknowledgeNumber >= Socket->SendUnacknowledgedSequence) &&
  4052. (AcknowledgeNumber <= Socket->SendNextNetworkSequence)) {
  4053. AcknowledgeValid = TRUE;
  4054. }
  4055. //
  4056. // The send window is wrapped around.
  4057. //
  4058. } else {
  4059. if ((AcknowledgeNumber >= Socket->SendUnacknowledgedSequence) ||
  4060. (AcknowledgeNumber <= Socket->SendNextNetworkSequence)) {
  4061. AcknowledgeValid = TRUE;
  4062. }
  4063. }
  4064. //
  4065. // If the acknowledge number is valid, then update the window state and
  4066. // list of packets that need acknowledgment.
  4067. //
  4068. if (AcknowledgeValid != FALSE) {
  4069. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4070. RelativeAcknowledgeNumber = Socket->SendUnacknowledgedSequence -
  4071. Socket->SendInitialSequence;
  4072. if (RelativeAcknowledgeNumber !=
  4073. AcknowledgeNumber - Socket->SendInitialSequence) {
  4074. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  4075. RtlDebugPrint(" ACK moved up from %d to %d.\n",
  4076. RelativeAcknowledgeNumber,
  4077. AcknowledgeNumber - Socket->SendInitialSequence);
  4078. }
  4079. }
  4080. Socket->SendUnacknowledgedSequence = AcknowledgeNumber;
  4081. ReceiveWindowEnd = Socket->ReceiveNextSequence +
  4082. Socket->ReceiveWindowFreeSize;
  4083. UpdateValid = FALSE;
  4084. //
  4085. // If the sequence number hasn't moved forward, then the update is good
  4086. // to take. RFC 1122 Section 4.2.2.20 has a correction to RFC 793's
  4087. // rules for taking a window update. The rule is that the update is
  4088. // valid if the sequence numbers are equal and the ACK is greater than
  4089. // or equal than the old ACK. RFC 793 statis that only ACKs greater
  4090. // than the old value are acceptable. So, given that the ACK was
  4091. // validated to fit in the send window above, it does not need to be
  4092. // checked here.
  4093. //
  4094. if (SequenceNumber == Socket->SendWindowUpdateSequence) {
  4095. UpdateValid = TRUE;
  4096. }
  4097. //
  4098. // In the normal window arrangement, take the highest sequence number
  4099. // in the window.
  4100. //
  4101. if (ReceiveWindowEnd > Socket->SendWindowUpdateSequence) {
  4102. if ((SequenceNumber > Socket->SendWindowUpdateSequence) &&
  4103. (SequenceNumber < ReceiveWindowEnd)) {
  4104. UpdateValid = TRUE;
  4105. }
  4106. //
  4107. // The eligible window wraps around, be a bit more careful.
  4108. //
  4109. } else {
  4110. if ((SequenceNumber > Socket->SendWindowUpdateSequence) ||
  4111. (SequenceNumber < ReceiveWindowEnd)) {
  4112. UpdateValid = TRUE;
  4113. }
  4114. }
  4115. //
  4116. // If the remote sequence number or the remote acknowledge
  4117. // number has moved forward from the last time the window was
  4118. // updated, then update the window (and the record of the last
  4119. // time the window was updated). This prevents old reordered
  4120. // segments from updating the window size.
  4121. //
  4122. if (UpdateValid != FALSE) {
  4123. Socket->SendWindowSize = ScaledWindowSize;
  4124. Socket->SendWindowUpdateSequence = SequenceNumber;
  4125. Socket->SendWindowUpdateAcknowledge = AcknowledgeNumber;
  4126. Socket->RetryTime = 0;
  4127. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  4128. }
  4129. //
  4130. // Clean up the send buffer based on this new acknowledgment.
  4131. //
  4132. NetpTcpFreeSentSegments(Socket, &CurrentTime);
  4133. //
  4134. // If the ACK is ahead of schedule, take note and send a response.
  4135. //
  4136. } else if (TCP_SEQUENCE_GREATER_THAN(AcknowledgeNumber,
  4137. Socket->SendNextNetworkSequence)) {
  4138. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4139. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  4140. RelativeAcknowledgeNumber = Socket->SendUnacknowledgedSequence -
  4141. Socket->SendInitialSequence;
  4142. RtlDebugPrint(" Invalid ACK %d, window was %d size %d.\n",
  4143. AcknowledgeNumber - Socket->SendInitialSequence,
  4144. RelativeAcknowledgeNumber,
  4145. Socket->SendWindowSize);
  4146. }
  4147. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0) {
  4148. Socket->Flags |= TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  4149. NetpTcpTimerAddReference();
  4150. }
  4151. //
  4152. // This ACK was not valid, take a note of it.
  4153. //
  4154. } else if (Socket->SendUnacknowledgedSequence !=
  4155. Socket->SendNextNetworkSequence) {
  4156. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4157. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  4158. RelativeAcknowledgeNumber = Socket->SendUnacknowledgedSequence -
  4159. Socket->SendInitialSequence;
  4160. RtlDebugPrint(" Invalid ACK %d, window was %d size %d.\n",
  4161. AcknowledgeNumber - Socket->SendInitialSequence,
  4162. RelativeAcknowledgeNumber,
  4163. Socket->SendWindowSize);
  4164. }
  4165. }
  4166. //
  4167. // Check to see if this is a duplicate acknowledgment, excluding any ACKs
  4168. // piggybacking on data, window size updates, and cases where this no data
  4169. // waiting to be sent.
  4170. //
  4171. if ((DataLength == 0) &&
  4172. (AcknowledgeNumber == Socket->PreviousAcknowledgeNumber) &&
  4173. (Socket->SendUnacknowledgedSequence !=
  4174. Socket->SendNextNetworkSequence) &&
  4175. (Socket->SendWindowSize == ScaledWindowSize)) {
  4176. Socket->DuplicateAcknowledgeCount += 1;
  4177. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4178. RtlDebugPrint("Duplicate ACK #%d for sequence %d.\n",
  4179. Socket->DuplicateAcknowledgeCount,
  4180. AcknowledgeNumber - Socket->SendInitialSequence);
  4181. }
  4182. } else {
  4183. Socket->DuplicateAcknowledgeCount = 0;
  4184. }
  4185. //
  4186. // Allow congestion control to process the acknowledgment.
  4187. //
  4188. NetpTcpCongestionAcknowledgeReceived(Socket, AcknowledgeNumber);
  4189. Socket->PreviousAcknowledgeNumber = AcknowledgeNumber;
  4190. //
  4191. // Try to send more data immediately. Do this after the congenstion control
  4192. // has processed the acknowledge number to give it a chance to update the
  4193. // congestion window size.
  4194. //
  4195. if ((AcknowledgeValid != FALSE) && (Socket->SendWindowSize != 0)) {
  4196. NetpTcpSendPendingSegments(Socket, &CurrentTime);
  4197. }
  4198. //
  4199. // If the connection is shutting down and the sent FIN was acknowledged,
  4200. // then advance to the second wait state.
  4201. //
  4202. if (Socket->State == TcpStateFinWait1) {
  4203. if (Socket->SendUnacknowledgedSequence ==
  4204. Socket->SendNextNetworkSequence) {
  4205. ASSERT(Socket->SendNextNetworkSequence ==
  4206. Socket->SendNextBufferSequence);
  4207. NetpTcpSetState(Socket, TcpStateFinWait2);
  4208. }
  4209. }
  4210. //
  4211. // In FIN wait 2, if the retransmission queue is empty the close can be
  4212. // acknowledged, but the socket isn't destroyed yet.
  4213. //
  4214. if (Socket->State == TcpStateFinWait2) {
  4215. ASSERT(Socket->SendUnacknowledgedSequence ==
  4216. Socket->SendNextNetworkSequence);
  4217. ASSERT(Socket->SendNextNetworkSequence ==
  4218. Socket->SendNextBufferSequence);
  4219. //
  4220. // Release the blocked close call.
  4221. //
  4222. IoSetIoObjectState(IoState, POLL_EVENT_OUT, TRUE);
  4223. }
  4224. //
  4225. // If the connection is closing and the sent FIN was acknowledged, then
  4226. // advance to the time-wait state.
  4227. //
  4228. if (Socket->State == TcpStateClosing) {
  4229. if (Socket->SendUnacknowledgedSequence ==
  4230. Socket->SendNextNetworkSequence) {
  4231. ASSERT(Socket->SendNextNetworkSequence ==
  4232. Socket->SendNextBufferSequence);
  4233. NetpTcpSetState(Socket, TcpStateTimeWait);
  4234. }
  4235. }
  4236. //
  4237. // If the acknowledge was received for the FIN that was sent, then move
  4238. // directly to the closed state and clean up.
  4239. //
  4240. if (Socket->State == TcpStateLastAcknowledge) {
  4241. ASSERT((Socket->Flags & TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID) !=
  4242. 0);
  4243. if (AcknowledgeNumber == Socket->SendFinalSequence + 1) {
  4244. NetpTcpCloseOutSocket(Socket, FALSE);
  4245. return STATUS_CONNECTION_CLOSED;
  4246. }
  4247. }
  4248. return STATUS_SUCCESS;
  4249. }
  4250. VOID
  4251. NetpTcpProcessPacketOptions (
  4252. PTCP_SOCKET Socket,
  4253. PTCP_HEADER Header,
  4254. PNET_PACKET_BUFFER Packet
  4255. )
  4256. /*++
  4257. Routine Description:
  4258. This routine is called to process TCP packet options.
  4259. Arguments:
  4260. Socket - Supplies a pointer to the TCP socket.
  4261. Header - Supplies a pointer to the TCP header.
  4262. Packet - Supplies a pointer to the received packet information.
  4263. SourceAddress - Supplies a pointer to the source (remote) address that the
  4264. packet originated from. This memory will not be referenced once the
  4265. function returns, it can be stack allocated.
  4266. Return Value:
  4267. None.
  4268. --*/
  4269. {
  4270. ULONG LocalMaxSegmentSize;
  4271. ULONG OptionIndex;
  4272. UCHAR OptionLength;
  4273. PUCHAR Options;
  4274. ULONG OptionsLength;
  4275. UCHAR OptionType;
  4276. PNET_PACKET_SIZE_INFORMATION SizeInformation;
  4277. BOOL WindowScaleSupported;
  4278. WindowScaleSupported = FALSE;
  4279. //
  4280. // Parse the options in the packet.
  4281. //
  4282. OptionsLength = Packet->DataOffset -
  4283. ((UINTN)Header - (UINTN)(Packet->Buffer));
  4284. OptionIndex = 0;
  4285. Options = (PUCHAR)(Header + 1);
  4286. while (OptionIndex < OptionsLength) {
  4287. OptionType = Options[OptionIndex];
  4288. OptionIndex += 1;
  4289. if (OptionType == TCP_OPTION_END) {
  4290. break;
  4291. }
  4292. if (OptionType == TCP_OPTION_NOP) {
  4293. continue;
  4294. }
  4295. if (OptionIndex >= OptionsLength) {
  4296. break;
  4297. }
  4298. //
  4299. // The option length accounts for the type and length fields themselves.
  4300. //
  4301. OptionLength = Options[OptionIndex] - 2;
  4302. OptionIndex += 1;
  4303. if (OptionIndex + OptionLength > OptionsLength) {
  4304. break;
  4305. }
  4306. //
  4307. // Watch for the maximum segment size option, but only if the SYN flag
  4308. // is set.
  4309. //
  4310. if (OptionType == TCP_OPTION_MAXIMUM_SEGMENT_SIZE) {
  4311. if (((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) &&
  4312. (OptionLength == 2)) {
  4313. Socket->SendMaxSegmentSize =
  4314. NETWORK_TO_CPU16(*((PUSHORT)&(Options[OptionIndex])));
  4315. SizeInformation = &(Socket->NetSocket.PacketSizeInformation);
  4316. LocalMaxSegmentSize = SizeInformation->MaxPacketSize -
  4317. SizeInformation->HeaderSize -
  4318. SizeInformation->FooterSize;
  4319. if (LocalMaxSegmentSize < Socket->SendMaxSegmentSize) {
  4320. Socket->SendMaxSegmentSize = LocalMaxSegmentSize;
  4321. }
  4322. }
  4323. //
  4324. // Watch for the window scale option, but only if the SYN flag is set.
  4325. //
  4326. } else if (OptionType == TCP_OPTION_WINDOW_SCALE) {
  4327. if (((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) &&
  4328. (OptionLength == 1)) {
  4329. Socket->SendWindowScale = Options[OptionIndex];
  4330. WindowScaleSupported = TRUE;
  4331. }
  4332. }
  4333. //
  4334. // Zoom past the object value.
  4335. //
  4336. OptionIndex += OptionLength;
  4337. }
  4338. if ((Header->Flags & TCP_HEADER_FLAG_SYN) != 0) {
  4339. //
  4340. // Disable window scaling locally if the remote doesn't understand it.
  4341. //
  4342. if (WindowScaleSupported == FALSE) {
  4343. Socket->Flags &= ~TCP_SOCKET_FLAG_WINDOW_SCALING;
  4344. //
  4345. // No data should have been sent yet.
  4346. //
  4347. ASSERT(Socket->ReceiveWindowFreeSize ==
  4348. Socket->ReceiveWindowTotalSize);
  4349. if (Socket->ReceiveWindowTotalSize > MAX_USHORT) {
  4350. Socket->ReceiveWindowTotalSize = MAX_USHORT;
  4351. Socket->ReceiveWindowFreeSize = MAX_USHORT;
  4352. }
  4353. Socket->ReceiveWindowScale = 0;
  4354. }
  4355. }
  4356. return;
  4357. }
  4358. VOID
  4359. NetpTcpSendControlPacket (
  4360. PTCP_SOCKET Socket,
  4361. ULONG Flags
  4362. )
  4363. /*++
  4364. Routine Description:
  4365. This routine sends a packet to the remote host that contains no data. This
  4366. routine assumes the socket lock is already held.
  4367. Arguments:
  4368. Socket - Supplies a pointer to the socket to send the acnkowledge packet on.
  4369. Flags - Supplies the bitfield of flags to set. The exception is the
  4370. acknowledge flag, which is always set by default, but is cleared if the
  4371. bit is set in this parameter.
  4372. Return Value:
  4373. None.
  4374. --*/
  4375. {
  4376. PNET_PACKET_BUFFER Packet;
  4377. NET_PACKET_LIST PacketList;
  4378. ULONG SequenceNumber;
  4379. PNET_PACKET_SIZE_INFORMATION SizeInformation;
  4380. KSTATUS Status;
  4381. NET_INITIALIZE_PACKET_LIST(&PacketList);
  4382. //
  4383. // If the socket has no link, then some incoming packet happened to guess
  4384. // an unbound socket. Sometimes this happens if the system resets and
  4385. // re-binds to the same port, and the remote end is left wondering what
  4386. // happened.
  4387. //
  4388. if (Socket->NetSocket.Link == NULL) {
  4389. if ((NetTcpDebugPrintAllPackets != FALSE) ||
  4390. (NetTcpDebugPrintSequenceNumbers != FALSE)) {
  4391. RtlDebugPrint("TCP: Ignoring send on unbound socket.\n");
  4392. }
  4393. return;
  4394. }
  4395. Packet = NULL;
  4396. SizeInformation = &(Socket->NetSocket.PacketSizeInformation);
  4397. Status = NetAllocateBuffer(SizeInformation->HeaderSize,
  4398. 0,
  4399. SizeInformation->FooterSize,
  4400. Socket->NetSocket.Link,
  4401. 0,
  4402. &Packet);
  4403. if (!KSUCCESS(Status)) {
  4404. goto TcpSendControlPacketEnd;
  4405. }
  4406. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  4407. ASSERT(Packet->DataOffset >= sizeof(TCP_HEADER));
  4408. Packet->DataOffset -= sizeof(TCP_HEADER);
  4409. //
  4410. // A keep alive message is just an ACK with a sequence number one less than
  4411. // the current value.
  4412. //
  4413. SequenceNumber = Socket->SendUnacknowledgedSequence;
  4414. if ((Flags & TCP_HEADER_FLAG_KEEP_ALIVE) != 0) {
  4415. SequenceNumber -= 1;
  4416. Flags &= ~TCP_HEADER_FLAG_KEEP_ALIVE;
  4417. }
  4418. NetpTcpFillOutHeader(Socket, Packet, SequenceNumber, Flags, 0, 0, 0);
  4419. //
  4420. // Send this control packet off down the network.
  4421. //
  4422. Status = Socket->NetSocket.Network->Interface.Send(
  4423. &(Socket->NetSocket),
  4424. &(Socket->NetSocket.RemoteAddress),
  4425. NULL,
  4426. &PacketList);
  4427. if (!KSUCCESS(Status)) {
  4428. goto TcpSendControlPacketEnd;
  4429. }
  4430. TcpSendControlPacketEnd:
  4431. if (!KSUCCESS(Status)) {
  4432. NetDestroyBufferList(&PacketList);
  4433. }
  4434. return;
  4435. }
  4436. VOID
  4437. NetpTcpProcessReceivedDataSegment (
  4438. PTCP_SOCKET Socket,
  4439. ULONG SequenceNumber,
  4440. PVOID Buffer,
  4441. ULONG Length,
  4442. PTCP_HEADER Header
  4443. )
  4444. /*++
  4445. Routine Description:
  4446. This routine processes incoming user data on a TCP socket. This routine
  4447. assumes the socket lock is already held.
  4448. Arguments:
  4449. Socket - Supplies a pointer to the socket involved.
  4450. SequenceNumber - Supplies the sequence number of the first byte of the data.
  4451. Buffer - Supplies a pointer to the user data.
  4452. Length - Supplies the length of the user data buffer.
  4453. Header - Supplies a pointer to the TCP header of the segment.
  4454. Return Value:
  4455. None.
  4456. --*/
  4457. {
  4458. ULONG AvailableBytes;
  4459. PLIST_ENTRY CurrentEntry;
  4460. PTCP_RECEIVED_SEGMENT CurrentSegment;
  4461. BOOL DataMissing;
  4462. BOOL InsertedSegment;
  4463. PIO_OBJECT_STATE IoState;
  4464. ULONG NextSequence;
  4465. PTCP_RECEIVED_SEGMENT PreviousSegment;
  4466. ULONG RemainingLength;
  4467. KSTATUS Status;
  4468. BOOL UpdateReceiveNextSequence;
  4469. IoState = Socket->NetSocket.KernelSocket.IoState;
  4470. //
  4471. // Don't process anything if the window is closed.
  4472. //
  4473. if ((Socket->ReceiveWindowFreeSize == 0) || (Length == 0)) {
  4474. return;
  4475. }
  4476. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4477. NetpTcpPrintSocketEndpoints(Socket, FALSE);
  4478. RtlDebugPrint(" RX Segment %d size %d.\n",
  4479. SequenceNumber - Socket->ReceiveInitialSequence,
  4480. Length);
  4481. }
  4482. //
  4483. // Loop through every segment to find a segment with a larger sequence than
  4484. // this one. If such a segment is found, then try to fill in the hole
  4485. // with the data from the provided segment. The segment will then shrink
  4486. // and the loop continues until the entire segment has been processed.
  4487. //
  4488. RemainingLength = Length;
  4489. UpdateReceiveNextSequence = FALSE;
  4490. PreviousSegment = NULL;
  4491. CurrentEntry = Socket->ReceivedSegmentList.Next;
  4492. while (CurrentEntry != &(Socket->ReceivedSegmentList)) {
  4493. CurrentSegment = LIST_VALUE(CurrentEntry,
  4494. TCP_RECEIVED_SEGMENT,
  4495. Header.ListEntry);
  4496. CurrentEntry = CurrentEntry->Next;
  4497. //
  4498. // If the starting sequence of this segment is less than or equal to
  4499. // the beginning of what remains of the received segment, skip it.
  4500. //
  4501. if ((SequenceNumber == CurrentSegment->SequenceNumber) ||
  4502. TCP_SEQUENCE_LESS_THAN(CurrentSegment->SequenceNumber,
  4503. SequenceNumber)) {
  4504. PreviousSegment = CurrentSegment;
  4505. continue;
  4506. }
  4507. ASSERT(TCP_SEQUENCE_GREATER_THAN(CurrentSegment->SequenceNumber,
  4508. SequenceNumber));
  4509. Status = NetpTcpInsertReceivedDataSegment(Socket,
  4510. PreviousSegment,
  4511. CurrentSegment,
  4512. Header,
  4513. &Buffer,
  4514. &SequenceNumber,
  4515. &RemainingLength,
  4516. &InsertedSegment);
  4517. if (!KSUCCESS(Status)) {
  4518. goto TcpProcessReceivedDataSegmentEnd;
  4519. }
  4520. //
  4521. // Record if something was inserted, indicating that the next sequence
  4522. // may need to be updated.
  4523. //
  4524. if (InsertedSegment != FALSE) {
  4525. UpdateReceiveNextSequence = TRUE;
  4526. }
  4527. //
  4528. // If there is nothing left to insert or no room to insert it, then
  4529. // exit.
  4530. //
  4531. if ((RemainingLength == 0) || (Socket->ReceiveWindowFreeSize == 0)) {
  4532. goto TcpProcessReceivedDataSegmentEnd;
  4533. }
  4534. //
  4535. // The current segment becomes the previous segment as more of the
  4536. // region gets processed.
  4537. //
  4538. PreviousSegment = CurrentSegment;
  4539. }
  4540. //
  4541. // There better be something left to insert and the previous segment should
  4542. // either not exist or be the last segment in the list.
  4543. //
  4544. ASSERT(RemainingLength != 0);
  4545. ASSERT((PreviousSegment == NULL) ||
  4546. (&(PreviousSegment->Header.ListEntry) ==
  4547. Socket->ReceivedSegmentList.Previous));
  4548. Status = NetpTcpInsertReceivedDataSegment(Socket,
  4549. PreviousSegment,
  4550. NULL,
  4551. Header,
  4552. &Buffer,
  4553. &SequenceNumber,
  4554. &RemainingLength,
  4555. &InsertedSegment);
  4556. if (!KSUCCESS(Status)) {
  4557. goto TcpProcessReceivedDataSegmentEnd;
  4558. }
  4559. //
  4560. // Record if something was inserted, indicating that the next sequence may
  4561. // need to be updated.
  4562. //
  4563. if (InsertedSegment != FALSE) {
  4564. UpdateReceiveNextSequence = TRUE;
  4565. }
  4566. TcpProcessReceivedDataSegmentEnd:
  4567. //
  4568. // Locally record if the socket was missing data and then reset that state.
  4569. // It will be updated below if data is still missing.
  4570. //
  4571. DataMissing = FALSE;
  4572. if ((Socket->Flags & TCP_SOCKET_FLAG_RECEIVE_MISSING_SEGMENTS) != 0) {
  4573. Socket->Flags &= ~TCP_SOCKET_FLAG_RECEIVE_MISSING_SEGMENTS;
  4574. DataMissing = TRUE;
  4575. }
  4576. //
  4577. // If a segment was inserted, then try to update the next expected receive
  4578. // sequence. It must be contiguous from the beginning of the unread data.
  4579. //
  4580. if (UpdateReceiveNextSequence != FALSE) {
  4581. NextSequence = Socket->ReceiveUnreadSequence;
  4582. CurrentEntry = Socket->ReceivedSegmentList.Next;
  4583. while (CurrentEntry != &(Socket->ReceivedSegmentList)) {
  4584. CurrentSegment = LIST_VALUE(CurrentEntry,
  4585. TCP_RECEIVED_SEGMENT,
  4586. Header.ListEntry);
  4587. if (NextSequence != CurrentSegment->SequenceNumber) {
  4588. Socket->Flags |= TCP_SOCKET_FLAG_RECEIVE_MISSING_SEGMENTS;
  4589. DataMissing = TRUE;
  4590. //
  4591. // It would be bad if there were something in the receive list
  4592. // that's less than the supposed start of the receive buffer.
  4593. //
  4594. ASSERT(TCP_SEQUENCE_GREATER_THAN(CurrentSegment->SequenceNumber,
  4595. NextSequence));
  4596. break;
  4597. }
  4598. NextSequence = CurrentSegment->NextSequence;
  4599. CurrentEntry = CurrentEntry->Next;
  4600. }
  4601. //
  4602. // If the sequence number was updated, then alert any readers if the
  4603. // minimum amount of data has been received.
  4604. //
  4605. if (NextSequence != Socket->ReceiveNextSequence) {
  4606. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4607. RtlDebugPrint("Moving RX next up from %d to %d.\n",
  4608. (Socket->ReceiveNextSequence -
  4609. Socket->ReceiveInitialSequence),
  4610. (NextSequence - Socket->ReceiveInitialSequence));
  4611. }
  4612. //
  4613. // Shrink the window now that new contiguous data was received.
  4614. //
  4615. Socket->ReceiveWindowFreeSize -= (NextSequence -
  4616. Socket->ReceiveNextSequence);
  4617. AvailableBytes = Socket->ReceiveWindowTotalSize -
  4618. Socket->ReceiveWindowFreeSize;
  4619. if (AvailableBytes >= Socket->ReceiveMinimum) {
  4620. IoSetIoObjectState(IoState, POLL_EVENT_IN, TRUE);
  4621. }
  4622. Socket->ReceiveNextSequence = NextSequence;
  4623. }
  4624. }
  4625. //
  4626. // Data was sent. Whether or not it's repeated data, an ACK is in order. Do
  4627. // it now that the receive sequence is up to date. But in order to not
  4628. // immediately ACK every packet sent, only ACK every other packet. On the
  4629. // odd packets, set the timer in case another packet does not come through.
  4630. // The exception is if a FIN came in with this data packet and all the
  4631. // expected data has been seen; the caller will handle sending an ACK in
  4632. // response to the FIN. If the received data came with a PUSH, then always
  4633. // acknowledge right away, as there's probably not more data coming.
  4634. //
  4635. if ((DataMissing != FALSE) ||
  4636. ((Header->Flags & TCP_HEADER_FLAG_FIN) == 0) ||
  4637. (Socket->ReceiveNextSequence != (SequenceNumber + RemainingLength))) {
  4638. if ((DataMissing == FALSE) &&
  4639. ((Header->Flags & TCP_HEADER_FLAG_PUSH) == 0) &&
  4640. (Length >= Socket->ReceiveMaxSegmentSize) &&
  4641. ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) == 0)) {
  4642. Socket->Flags |= TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  4643. NetpTcpTimerAddReference();
  4644. } else {
  4645. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) != 0) {
  4646. Socket->Flags &= ~TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  4647. NetpTcpTimerReleaseReference();
  4648. }
  4649. NetpTcpSendControlPacket(Socket, 0);
  4650. }
  4651. }
  4652. return;
  4653. }
  4654. KSTATUS
  4655. NetpTcpInsertReceivedDataSegment (
  4656. PTCP_SOCKET Socket,
  4657. PTCP_RECEIVED_SEGMENT PreviousSegment,
  4658. PTCP_RECEIVED_SEGMENT NextSegment,
  4659. PTCP_HEADER Header,
  4660. PVOID *Buffer,
  4661. PULONG SequenceNumber,
  4662. PULONG Length,
  4663. PBOOL InsertedSegment
  4664. )
  4665. /*++
  4666. Routine Description:
  4667. This routine attempts to insert the given data segment, as defined by the
  4668. sequence number and length, into the socket's list of received data
  4669. segments. The provided region should fit between the given segments or
  4670. overlap with a portion thereof. It may extend beyond the end of the given
  4671. next segment but that portion will be clipped. This routine assumes the
  4672. socket lock is held.
  4673. Arguments:
  4674. Socket - Supplies a pointer to the socket involved.
  4675. PreviousSegment - Supplies an optional pointer to the previous segment in
  4676. the socket's list of received segments. This segment may or may not
  4677. overlap with the region, but the region should not extend to cover any
  4678. portion of the sequence before this previous region.
  4679. NextSegment - Supplies an optional pointer to the next segment in the
  4680. socket's list of received segments. This segment may or may not overlap
  4681. with the region, but its beginning sequence number should be greater
  4682. than the inserting region's sequence number.
  4683. Header - Supplies a pointer to the TCP header for this received segment.
  4684. Buffer - Supplies a pointer to the buffer containing the data to insert.
  4685. If this routine reads or skips over any data at the beginning of the
  4686. buffer, it will update the buffer pointer.
  4687. SequenceNumber - Supplies a pointer to the sequence number that starts the
  4688. region to insert. If this routine clips from the beginning of the
  4689. region or inserts any portion of the region, it will move the sequence
  4690. number forward.
  4691. Length - Supplies a pointer to the length of the region to insert. If this
  4692. routine clips from the beginning of the region or inserts data from the
  4693. region, the length will be updated.
  4694. InsertedSegment - Supplies a pointer to a boolean that receives indication
  4695. of whether or not this routine successfully inserted a region.
  4696. Return Value:
  4697. Status code.
  4698. --*/
  4699. {
  4700. ULONG AllocationSize;
  4701. ULONG ClipAmount;
  4702. ULONG InsertBegin;
  4703. ULONG InsertEnd;
  4704. ULONG InsertLength;
  4705. PTCP_RECEIVED_SEGMENT NewSegment;
  4706. PLIST_ENTRY PreviousListEntry;
  4707. ULONG RelativeSequence;
  4708. ULONG SegmentEnd;
  4709. KSTATUS Status;
  4710. ULONG TailLength;
  4711. PTCP_RECEIVED_SEGMENT TailSegment;
  4712. PVOID TailSource;
  4713. USHORT UrgentPointer;
  4714. ULONG UrgentSequence;
  4715. ASSERT(*Length != 0);
  4716. ASSERT(Socket->ReceiveWindowFreeSize != 0);
  4717. ASSERT((NextSegment == NULL) ||
  4718. (TCP_SEQUENCE_GREATER_THAN(NextSegment->SequenceNumber,
  4719. *SequenceNumber)));
  4720. ASSERT((PreviousSegment == NULL) ||
  4721. (PreviousSegment->SequenceNumber == *SequenceNumber) ||
  4722. (TCP_SEQUENCE_LESS_THAN(PreviousSegment->SequenceNumber,
  4723. *SequenceNumber)));
  4724. *InsertedSegment = FALSE;
  4725. Status = STATUS_SUCCESS;
  4726. //
  4727. // Start out assuming that all of the received segment can be inserted.
  4728. //
  4729. InsertBegin = *SequenceNumber;
  4730. InsertEnd = *SequenceNumber + *Length;
  4731. InsertLength = *Length;
  4732. UrgentSequence = *SequenceNumber;
  4733. //
  4734. // Clip the segment if it is older than what's already been read.
  4735. //
  4736. if (TCP_SEQUENCE_LESS_THAN(InsertEnd, Socket->ReceiveUnreadSequence)) {
  4737. *SequenceNumber = Socket->ReceiveUnreadSequence;
  4738. *Length = 0;
  4739. goto TcpInsertReceivedDataSegmentEnd;
  4740. }
  4741. if (TCP_SEQUENCE_LESS_THAN(InsertBegin, Socket->ReceiveUnreadSequence)) {
  4742. ClipAmount = Socket->ReceiveUnreadSequence - InsertBegin;
  4743. InsertLength -= ClipAmount;
  4744. *Length -= ClipAmount;
  4745. *Buffer += ClipAmount;
  4746. InsertBegin = Socket->ReceiveUnreadSequence;
  4747. }
  4748. //
  4749. // Process the previous segment if it exists, skipping data in here that is
  4750. // already in the previous segment.
  4751. //
  4752. if (PreviousSegment != NULL) {
  4753. SegmentEnd = PreviousSegment->NextSequence;
  4754. //
  4755. // The next segment should not overlap the previous segment.
  4756. //
  4757. ASSERT((NextSegment == NULL) ||
  4758. (SegmentEnd == NextSegment->SequenceNumber) ||
  4759. (TCP_SEQUENCE_GREATER_THAN(NextSegment->SequenceNumber,
  4760. SegmentEnd)));
  4761. //
  4762. // If the previous entry overlaps, then clip the insert region and move
  4763. // the sequence number forward.
  4764. //
  4765. if (TCP_SEQUENCE_GREATER_THAN(SegmentEnd, InsertBegin)) {
  4766. //
  4767. // If the previous segment completely swallows this one, move the
  4768. // sequence number forward and exit.
  4769. //
  4770. if (TCP_SEQUENCE_GREATER_THAN(SegmentEnd, InsertEnd)) {
  4771. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4772. RelativeSequence = PreviousSegment->SequenceNumber -
  4773. Socket->ReceiveInitialSequence;
  4774. RtlDebugPrint("RX %d, %d ignored, swallowed by %d, %d\n",
  4775. (InsertBegin -
  4776. Socket->ReceiveInitialSequence),
  4777. InsertLength,
  4778. RelativeSequence,
  4779. PreviousSegment->Length);
  4780. }
  4781. ASSERT(*Length == (InsertEnd - InsertBegin));
  4782. *SequenceNumber = InsertEnd;
  4783. *Length = 0;
  4784. goto TcpInsertReceivedDataSegmentEnd;
  4785. }
  4786. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4787. RtlDebugPrint("Clipping RX begin from %d up to %d.\n",
  4788. InsertBegin - Socket->ReceiveInitialSequence,
  4789. SegmentEnd - Socket->ReceiveInitialSequence);
  4790. }
  4791. ClipAmount = SegmentEnd - InsertBegin;
  4792. *Buffer += ClipAmount;
  4793. InsertLength -= ClipAmount;
  4794. InsertBegin = SegmentEnd;
  4795. //
  4796. // This always moves the sequence number as well.
  4797. //
  4798. *SequenceNumber = SegmentEnd;
  4799. *Length -= ClipAmount;
  4800. if (*Length == 0) {
  4801. goto TcpInsertReceivedDataSegmentEnd;
  4802. }
  4803. ASSERT(InsertBegin != InsertEnd);
  4804. }
  4805. }
  4806. //
  4807. // If the next segment overlaps with the insert region, then clip the end
  4808. // of the insert region. Do not update the sequence number.
  4809. //
  4810. if (NextSegment != NULL) {
  4811. if (TCP_SEQUENCE_GREATER_THAN(InsertEnd, NextSegment->SequenceNumber)) {
  4812. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  4813. RelativeSequence = NextSegment->SequenceNumber -
  4814. Socket->ReceiveInitialSequence;
  4815. SegmentEnd = NextSegment->NextSequence;
  4816. if (TCP_SEQUENCE_GREATER_THAN(SegmentEnd, InsertEnd)) {
  4817. SegmentEnd = InsertEnd;
  4818. }
  4819. RtlDebugPrint("Clipping RX region %d, %d.\n",
  4820. RelativeSequence,
  4821. SegmentEnd - NextSegment->SequenceNumber);
  4822. }
  4823. InsertLength -= InsertEnd - NextSegment->SequenceNumber;
  4824. InsertEnd = NextSegment->SequenceNumber;
  4825. //
  4826. // If this makes the current insert length 0, then exit.
  4827. //
  4828. if (InsertEnd == InsertBegin) {
  4829. goto TcpInsertReceivedDataSegmentEnd;
  4830. }
  4831. }
  4832. }
  4833. ASSERT(InsertBegin != InsertEnd);
  4834. //
  4835. // Clip the incoming segment further by the receive window.
  4836. //
  4837. if (InsertLength > Socket->ReceiveWindowFreeSize) {
  4838. InsertEnd = InsertBegin + Socket->ReceiveWindowFreeSize;
  4839. InsertLength = Socket->ReceiveWindowFreeSize;
  4840. }
  4841. ASSERT(InsertEnd == (InsertBegin + InsertLength));
  4842. if (PreviousSegment != NULL) {
  4843. PreviousListEntry = &(PreviousSegment->Header.ListEntry);
  4844. } else {
  4845. PreviousListEntry = &(Socket->ReceivedSegmentList);
  4846. }
  4847. //
  4848. // Create the new segment.
  4849. //
  4850. AllocationSize = sizeof(TCP_RECEIVED_SEGMENT) + InsertLength;
  4851. NewSegment = (PTCP_RECEIVED_SEGMENT)NetpTcpAllocateSegment(Socket,
  4852. AllocationSize);
  4853. if (NewSegment == NULL) {
  4854. Status = STATUS_INSUFFICIENT_RESOURCES;
  4855. goto TcpInsertReceivedDataSegmentEnd;
  4856. }
  4857. NewSegment->SequenceNumber = InsertBegin;
  4858. NewSegment->Length = InsertLength;
  4859. NewSegment->NextSequence = InsertBegin + InsertLength;
  4860. NewSegment->Flags = Header->Flags & TCP_RECEIVE_SEGMENT_HEADER_FLAG_MASK;
  4861. RtlCopyMemory(NewSegment + 1, *Buffer, NewSegment->Length);
  4862. *Buffer += NewSegment->Length;
  4863. //
  4864. // If this segment contains an urgent byte, then the segment will need to
  4865. // be split into two or three segments. This is done so that the receiver
  4866. // doesn't read "through" urgent data. For OOB inline, subsequent read
  4867. // calls should return:
  4868. // 1) Data before urgent byte
  4869. // 2) Urgent byte
  4870. // 3) Data after urgent byte
  4871. //
  4872. // For non-inline urgent data, read calls would return:
  4873. // 1) Data before urgent byte
  4874. // 2) Data after urgent byte
  4875. //
  4876. if ((Header->Flags & TCP_HEADER_FLAG_URGENT) != 0) {
  4877. //
  4878. // The urgent pointer points at the first non-urgent sequence number.
  4879. // So the urgent byte is one back from that.
  4880. //
  4881. UrgentPointer = CPU_TO_NETWORK16(Header->NonUrgentOffset);
  4882. if ((UrgentPointer != 0) && (UrgentPointer != (USHORT)-1)) {
  4883. UrgentSequence += UrgentPointer - 1;
  4884. }
  4885. //
  4886. // If this segment contains the urgent byte, split it.
  4887. //
  4888. if ((!TCP_SEQUENCE_LESS_THAN(UrgentSequence,
  4889. NewSegment->SequenceNumber)) &&
  4890. (TCP_SEQUENCE_LESS_THAN(UrgentSequence,
  4891. NewSegment->NextSequence))) {
  4892. //
  4893. // The length of the remaining segment is from the non-urgent
  4894. // sequence to the end.
  4895. //
  4896. TailLength = NewSegment->NextSequence - (UrgentSequence + 1);
  4897. if (TailLength != 0) {
  4898. AllocationSize = sizeof(TCP_RECEIVED_SEGMENT) + TailLength;
  4899. TailSegment = (PTCP_RECEIVED_SEGMENT)NetpTcpAllocateSegment(
  4900. Socket,
  4901. AllocationSize);
  4902. if (TailSegment != NULL) {
  4903. TailSegment->SequenceNumber = UrgentSequence + 1;
  4904. TailSegment->Length = TailLength;
  4905. TailSegment->NextSequence = NewSegment->NextSequence;
  4906. TailSegment->Flags = NewSegment->Flags;
  4907. TailSource = NewSegment + 1;
  4908. TailSource += TailSegment->SequenceNumber -
  4909. NewSegment->SequenceNumber;
  4910. RtlCopyMemory(TailSegment + 1, TailSource, TailLength);
  4911. INSERT_AFTER(&(NewSegment->Header.ListEntry),
  4912. PreviousListEntry);
  4913. //
  4914. // On allocation failure, move the insert length back so that
  4915. // these bytes are essentially unreceived.
  4916. //
  4917. } else {
  4918. InsertLength -= TailLength;
  4919. }
  4920. }
  4921. //
  4922. // Create a segment to hold the urgent byte. This may actually
  4923. // have a length of zero if OOB data is not inline, but is still
  4924. // important as it contains the up-down transition of the URGENT
  4925. // flag, which breaks up the reader so it doesn't cross urgent
  4926. // boundaries.
  4927. //
  4928. AllocationSize = sizeof(TCP_RECEIVED_SEGMENT) + 1;
  4929. TailSegment = (PTCP_RECEIVED_SEGMENT)NetpTcpAllocateSegment(
  4930. Socket,
  4931. AllocationSize);
  4932. if (TailSegment != NULL) {
  4933. TailSegment->SequenceNumber = UrgentSequence;
  4934. TailSegment->NextSequence = UrgentSequence + 1;
  4935. TailSegment->Length = 0;
  4936. TailSegment->Flags = NewSegment->Flags |
  4937. TCP_RECEIVE_SEGMENT_FLAG_URGENT;
  4938. if ((Socket->Flags & TCP_SOCKET_FLAG_URGENT_INLINE) != 0) {
  4939. TailSegment->Length = 1;
  4940. TailSource = NewSegment + 1;
  4941. TailSource += TailSegment->SequenceNumber -
  4942. NewSegment->SequenceNumber;
  4943. RtlCopyMemory(TailSegment + 1, TailSource, 1);
  4944. }
  4945. INSERT_AFTER(&(NewSegment->Header.ListEntry),
  4946. PreviousListEntry);
  4947. //
  4948. // On allocation failure, move the insert length back past the
  4949. // previous tail and this byte so they seem unreceived.
  4950. //
  4951. } else {
  4952. InsertLength -= TailLength + 1;
  4953. }
  4954. //
  4955. // Clip the first segment, as the urgent byte and data following it
  4956. // are in subsequent segments. If allocations above failed, the
  4957. // data will be resent as the insert length variable was rolled
  4958. // back.
  4959. //
  4960. NewSegment->Length = UrgentSequence - NewSegment->SequenceNumber;
  4961. NewSegment->NextSequence = UrgentSequence;
  4962. IoSetIoObjectState(Socket->NetSocket.KernelSocket.IoState,
  4963. POLL_EVENT_IN_HIGH_PRIORITY,
  4964. TRUE);
  4965. }
  4966. }
  4967. //
  4968. // Insert the new segment into the list. It always goes after the previous
  4969. // segment, unless the list is empty.
  4970. //
  4971. INSERT_AFTER(&(NewSegment->Header.ListEntry), PreviousListEntry);
  4972. *InsertedSegment = TRUE;
  4973. //
  4974. // Move the sequence number up to the end of the insertion.
  4975. //
  4976. *SequenceNumber = InsertEnd;
  4977. *Length -= InsertLength;
  4978. TcpInsertReceivedDataSegmentEnd:
  4979. return Status;
  4980. }
  4981. VOID
  4982. NetpTcpSendPendingSegments (
  4983. PTCP_SOCKET Socket,
  4984. PULONGLONG CurrentTime
  4985. )
  4986. /*++
  4987. Routine Description:
  4988. This routine surveys the given socket and depending on what's appropriate
  4989. may send new data out, retransmit unacknowledged data, or neither. This
  4990. routine assumes that the socket's lock is already held.
  4991. Arguments:
  4992. Socket - Supplies a pointer to the socket involved.
  4993. CurrentTime - Supplies an optional time counter value for an approximate
  4994. current time.
  4995. Return Value:
  4996. None.
  4997. --*/
  4998. {
  4999. PLIST_ENTRY CurrentEntry;
  5000. PTCP_SEND_SEGMENT FirstSegment;
  5001. PULONG Flags;
  5002. BOOL InWindow;
  5003. PTCP_SEND_SEGMENT LastSegment;
  5004. ULONGLONG LocalCurrentTime;
  5005. PNET_PACKET_BUFFER Packet;
  5006. NET_PACKET_LIST PacketList;
  5007. PTCP_SEND_SEGMENT Segment;
  5008. ULONG SegmentBegin;
  5009. KSTATUS Status;
  5010. ULONG WindowBegin;
  5011. ULONG WindowEnd;
  5012. ULONG WindowSize;
  5013. //
  5014. // The connection may have been reset locally and be waiting on the lock to
  5015. // close out the socket. The close routine releases the socket lock briefly
  5016. // in order to acquire the socket list lock. If this is the case, don't
  5017. // bother to send any more packets.
  5018. //
  5019. if ((Socket->Flags & TCP_SOCKET_FLAG_CONNECTION_RESET) != 0) {
  5020. return;
  5021. }
  5022. if (LIST_EMPTY(&(Socket->OutgoingSegmentList)) != FALSE) {
  5023. //
  5024. // Check to see if the final FIN needs to be sent.
  5025. //
  5026. Flags = &(Socket->Flags);
  5027. if (((*Flags & TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID) != 0) &&
  5028. ((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) &&
  5029. ((Socket->State == TcpStateEstablished) ||
  5030. (Socket->State == TcpStateCloseWait) ||
  5031. (Socket->State == TcpStateSynReceived))) {
  5032. ASSERT(Socket->SendNextNetworkSequence ==
  5033. Socket->SendFinalSequence);
  5034. Socket->SendNextNetworkSequence += 1;
  5035. NetpTcpSendControlPacket(Socket, TCP_HEADER_FLAG_FIN);
  5036. if (Socket->State == TcpStateCloseWait) {
  5037. NetpTcpSetState(Socket, TcpStateLastAcknowledge);
  5038. } else {
  5039. NetpTcpSetState(Socket, TcpStateFinWait1);
  5040. }
  5041. }
  5042. return;
  5043. }
  5044. ASSERT((Socket->State == TcpStateEstablished) ||
  5045. (Socket->State == TcpStateCloseWait) ||
  5046. (Socket->State == TcpStateFinWait1));
  5047. //
  5048. // Determine the sequence numbers that can be sent at this time by getting
  5049. // the window size and last acknowledge number received.
  5050. //
  5051. WindowSize = NetpTcpGetSendWindowSize(Socket);
  5052. if (WindowSize == 0) {
  5053. return;
  5054. }
  5055. WindowBegin = Socket->SendWindowUpdateAcknowledge;
  5056. WindowEnd = WindowBegin + WindowSize;
  5057. //
  5058. // Loop adding as many segments as possible to the packets list.
  5059. //
  5060. LocalCurrentTime = 0;
  5061. if (CurrentTime != NULL) {
  5062. LocalCurrentTime = *CurrentTime;
  5063. }
  5064. FirstSegment = NULL;
  5065. LastSegment = NULL;
  5066. NET_INITIALIZE_PACKET_LIST(&PacketList);
  5067. CurrentEntry = Socket->OutgoingSegmentList.Next;
  5068. while (CurrentEntry != &(Socket->OutgoingSegmentList)) {
  5069. Segment = LIST_VALUE(CurrentEntry, TCP_SEND_SEGMENT, Header.ListEntry);
  5070. CurrentEntry = CurrentEntry->Next;
  5071. //
  5072. // Determine if the packet is inside the eligible window. If the
  5073. // segment is inside the window but bigger than the window, that's
  5074. // tough nuggets for the receiver. It's their job to chop it up.
  5075. //
  5076. InWindow = FALSE;
  5077. SegmentBegin = Segment->SequenceNumber + Segment->Offset;
  5078. if (WindowEnd >= WindowBegin) {
  5079. if ((SegmentBegin >= WindowBegin) && (SegmentBegin < WindowEnd)) {
  5080. InWindow = TRUE;
  5081. }
  5082. } else {
  5083. if ((SegmentBegin >= WindowBegin) || (SegmentBegin <= WindowEnd)) {
  5084. InWindow = TRUE;
  5085. }
  5086. }
  5087. //
  5088. // If it's not in the window, stop now.
  5089. //
  5090. if (InWindow == FALSE) {
  5091. break;
  5092. }
  5093. //
  5094. // Check to see if the packet needs to be sent for the first
  5095. // time.
  5096. //
  5097. if (Segment->SendAttemptCount == 0) {
  5098. ASSERT(Segment->Offset == 0);
  5099. Packet = NetpTcpCreatePacket(Socket, Segment);
  5100. if (Packet == NULL) {
  5101. break;
  5102. }
  5103. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  5104. if (FirstSegment == NULL) {
  5105. FirstSegment = Segment;
  5106. }
  5107. LastSegment = Segment;
  5108. //
  5109. // Update the next pointer and record the send time.
  5110. //
  5111. Socket->SendNextNetworkSequence = Segment->SequenceNumber +
  5112. Segment->Length;
  5113. if ((Segment->Flags & TCP_SEND_SEGMENT_FLAG_FIN) != 0) {
  5114. Socket->SendNextNetworkSequence += 1;
  5115. if (Socket->State == TcpStateCloseWait) {
  5116. NetpTcpSetState(Socket, TcpStateLastAcknowledge);
  5117. } else {
  5118. NetpTcpSetState(Socket, TcpStateFinWait1);
  5119. }
  5120. }
  5121. NetpTcpGetTransmitTimeoutInterval(Socket, Segment);
  5122. Segment->SendAttemptCount += 1;
  5123. //
  5124. // This segment has been sent before. Check to see if enough
  5125. // time has gone by without an acknowledge that it needs to be
  5126. // retransmitted.
  5127. //
  5128. } else {
  5129. if (LocalCurrentTime == 0) {
  5130. LocalCurrentTime = HlQueryTimeCounter();
  5131. }
  5132. if (LocalCurrentTime >=
  5133. Segment->LastSendTime + Segment->TimeoutInterval) {
  5134. Packet = NetpTcpCreatePacket(Socket, Segment);
  5135. if (Packet == NULL) {
  5136. break;
  5137. }
  5138. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  5139. if (FirstSegment == NULL) {
  5140. FirstSegment = Segment;
  5141. }
  5142. LastSegment = Segment;
  5143. NetpTcpTransmissionTimeout(Socket, Segment);
  5144. NetpTcpGetTransmitTimeoutInterval(Socket, Segment);
  5145. Segment->SendAttemptCount += 1;
  5146. break;
  5147. }
  5148. }
  5149. }
  5150. //
  5151. // Exit immediately if there was nothing to send.
  5152. //
  5153. if (NET_PACKET_LIST_EMPTY(&PacketList) != FALSE) {
  5154. Status = STATUS_SUCCESS;
  5155. goto TcpSendPendingSegmentsEnd;
  5156. }
  5157. //
  5158. // Otherwise send off the whole group of packets.
  5159. //
  5160. Status = Socket->NetSocket.Network->Interface.Send(
  5161. &(Socket->NetSocket),
  5162. &(Socket->NetSocket.RemoteAddress),
  5163. NULL,
  5164. &PacketList);
  5165. if (!KSUCCESS(Status)) {
  5166. RtlDebugPrint("TCP segments failed to send %d.\n", Status);
  5167. goto TcpSendPendingSegmentsEnd;
  5168. }
  5169. //
  5170. // Update all the sent segments' last send time now that they have been
  5171. // sent to the physical layer.
  5172. //
  5173. LocalCurrentTime = HlQueryTimeCounter();
  5174. CurrentEntry = &(FirstSegment->Header.ListEntry);
  5175. while (CurrentEntry != LastSegment->Header.ListEntry.Next) {
  5176. Segment = LIST_VALUE(CurrentEntry, TCP_SEND_SEGMENT, Header.ListEntry);
  5177. CurrentEntry = CurrentEntry->Next;
  5178. Segment->LastSendTime = LocalCurrentTime;
  5179. }
  5180. TcpSendPendingSegmentsEnd:
  5181. if (!KSUCCESS(Status)) {
  5182. NetDestroyBufferList(&PacketList);
  5183. }
  5184. if (CurrentTime != NULL) {
  5185. *CurrentTime = LocalCurrentTime;
  5186. }
  5187. return;
  5188. }
  5189. KSTATUS
  5190. NetpTcpSendSegment (
  5191. PTCP_SOCKET Socket,
  5192. PTCP_SEND_SEGMENT Segment
  5193. )
  5194. /*++
  5195. Routine Description:
  5196. This routine transmits the given segment down the wire (unconditionally).
  5197. This routine assumes the socket lock is already held.
  5198. Arguments:
  5199. Socket - Supplies a pointer to the socket involved.
  5200. Segment - Supplies a pointer to the segment to transmit.
  5201. Return Value:
  5202. Status code.
  5203. --*/
  5204. {
  5205. ULONGLONG LastSendTime;
  5206. PNET_PACKET_BUFFER Packet;
  5207. NET_PACKET_LIST PacketList;
  5208. KSTATUS Status;
  5209. //
  5210. // Create the network packet to send down to the network layer.
  5211. //
  5212. NET_INITIALIZE_PACKET_LIST(&PacketList);
  5213. Packet = NetpTcpCreatePacket(Socket, Segment);
  5214. if (Packet == NULL) {
  5215. Status = STATUS_INSUFFICIENT_RESOURCES;
  5216. goto TcpSendSegmentEnd;
  5217. }
  5218. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  5219. Status = Socket->NetSocket.Network->Interface.Send(
  5220. &(Socket->NetSocket),
  5221. &(Socket->NetSocket.RemoteAddress),
  5222. NULL,
  5223. &PacketList);
  5224. if (!KSUCCESS(Status)) {
  5225. RtlDebugPrint("TCP segment failed to send %d.\n", Status);
  5226. goto TcpSendSegmentEnd;
  5227. }
  5228. //
  5229. // Update the next pointer and window if this is the first time this packet
  5230. // is being sent.
  5231. //
  5232. if (Segment->SendAttemptCount == 0) {
  5233. ASSERT(Segment->Offset == 0);
  5234. Socket->SendNextNetworkSequence = Segment->SequenceNumber +
  5235. Segment->Length;
  5236. if ((Segment->Flags & TCP_SEND_SEGMENT_FLAG_FIN) != 0) {
  5237. Socket->SendNextNetworkSequence += 1;
  5238. if (Socket->State == TcpStateCloseWait) {
  5239. NetpTcpSetState(Socket, TcpStateLastAcknowledge);
  5240. } else {
  5241. NetpTcpSetState(Socket, TcpStateFinWait1);
  5242. }
  5243. }
  5244. }
  5245. LastSendTime = Segment->LastSendTime;
  5246. Segment->LastSendTime = HlQueryTimeCounter();
  5247. //
  5248. // Double the timeout interval only if this retransmission was due to a
  5249. // timeout.
  5250. //
  5251. if (LastSendTime + Segment->TimeoutInterval < Segment->LastSendTime) {
  5252. NetpTcpGetTransmitTimeoutInterval(Socket, Segment);
  5253. }
  5254. Segment->SendAttemptCount += 1;
  5255. Status = STATUS_SUCCESS;
  5256. TcpSendSegmentEnd:
  5257. if (!KSUCCESS(Status)) {
  5258. NetDestroyBufferList(&PacketList);
  5259. }
  5260. return Status;
  5261. }
  5262. PNET_PACKET_BUFFER
  5263. NetpTcpCreatePacket (
  5264. PTCP_SOCKET Socket,
  5265. PTCP_SEND_SEGMENT Segment
  5266. )
  5267. /*++
  5268. Routine Description:
  5269. This routine creates a network packet for the given TCP segment. It
  5270. allocates a network packet buffer and fills out the TCP header.
  5271. Arguments:
  5272. Socket - Supplies a pointer to the socket involved.
  5273. Segment - Supplies a pointer to the segment to use for packet
  5274. initialization.
  5275. Return Value:
  5276. Returns a pointer to the newly allocated packet buffer on success, or NULL
  5277. on failure.
  5278. --*/
  5279. {
  5280. USHORT HeaderFlags;
  5281. PNET_PACKET_BUFFER Packet;
  5282. ULONG SegmentLength;
  5283. PNET_PACKET_SIZE_INFORMATION SizeInformation;
  5284. KSTATUS Status;
  5285. //
  5286. // Allocate the network buffer.
  5287. //
  5288. SegmentLength = Segment->Length - Segment->Offset;
  5289. ASSERT(SegmentLength != 0);
  5290. Packet = NULL;
  5291. SizeInformation = &(Socket->NetSocket.PacketSizeInformation);
  5292. Status = NetAllocateBuffer(SizeInformation->HeaderSize,
  5293. SegmentLength,
  5294. SizeInformation->FooterSize,
  5295. Socket->NetSocket.Link,
  5296. 0,
  5297. &Packet);
  5298. if (!KSUCCESS(Status)) {
  5299. ASSERT(Packet == NULL);
  5300. goto TcpCreatePacketEnd;
  5301. }
  5302. //
  5303. // Convert any flags into header flags. They match up for convenience.
  5304. //
  5305. HeaderFlags = Segment->Flags & TCP_SEND_SEGMENT_HEADER_FLAG_MASK;
  5306. //
  5307. // Copy the segment data over and fill out the TCP header.
  5308. //
  5309. RtlCopyMemory(Packet->Buffer + Packet->DataOffset,
  5310. (PUCHAR)(Segment + 1) + Segment->Offset,
  5311. SegmentLength);
  5312. ASSERT(Packet->DataOffset >= sizeof(TCP_HEADER));
  5313. Packet->DataOffset -= sizeof(TCP_HEADER);
  5314. NetpTcpFillOutHeader(Socket,
  5315. Packet,
  5316. Segment->SequenceNumber + Segment->Offset,
  5317. HeaderFlags,
  5318. 0,
  5319. 0,
  5320. SegmentLength);
  5321. TcpCreatePacketEnd:
  5322. return Packet;
  5323. }
  5324. VOID
  5325. NetpTcpFreeSentSegments (
  5326. PTCP_SOCKET Socket,
  5327. PULONGLONG CurrentTime
  5328. )
  5329. /*++
  5330. Routine Description:
  5331. This routine frees any packets in the send buffer that have been
  5332. acknowledged by the remote host. This routine assumes that the socket is
  5333. already locked.
  5334. Arguments:
  5335. Socket - Supplies a pointer to the socket involved.
  5336. CurrentTime - Supplies a pointer to a time counter value for an approximate
  5337. current time. If it is set to 0, it may be updated by this routine.
  5338. Return Value:
  5339. None.
  5340. --*/
  5341. {
  5342. ULONG AcknowledgeNumber;
  5343. PLIST_ENTRY CurrentEntry;
  5344. PIO_OBJECT_STATE IoState;
  5345. PTCP_SEND_SEGMENT Segment;
  5346. ULONG SegmentBegin;
  5347. ULONG SegmentEnd;
  5348. BOOL SignalTransmitReadyEvent;
  5349. SignalTransmitReadyEvent = FALSE;
  5350. IoState = Socket->NetSocket.KernelSocket.IoState;
  5351. AcknowledgeNumber = Socket->SendUnacknowledgedSequence;
  5352. CurrentEntry = Socket->OutgoingSegmentList.Next;
  5353. while (CurrentEntry != &(Socket->OutgoingSegmentList)) {
  5354. Segment = LIST_VALUE(CurrentEntry, TCP_SEND_SEGMENT, Header.ListEntry);
  5355. CurrentEntry = CurrentEntry->Next;
  5356. //
  5357. // Figure out if the current acknowledge number is greater than the
  5358. // current segment's ending sequence number.
  5359. //
  5360. SegmentBegin = Segment->SequenceNumber + Segment->Offset;
  5361. SegmentEnd = Segment->SequenceNumber + Segment->Length;
  5362. if ((AcknowledgeNumber == SegmentEnd) ||
  5363. (TCP_SEQUENCE_GREATER_THAN(AcknowledgeNumber, SegmentEnd))) {
  5364. //
  5365. // If the remote host is acknowledging exactly this segment, then
  5366. // let congestion control know that there's a new round trip time
  5367. // in the house.
  5368. //
  5369. if ((AcknowledgeNumber == SegmentEnd) &&
  5370. (Segment->SendAttemptCount == 1)) {
  5371. if (*CurrentTime == 0) {
  5372. *CurrentTime = HlQueryTimeCounter();
  5373. }
  5374. NetpTcpProcessNewRoundTripTimeSample(
  5375. Socket,
  5376. *CurrentTime - Segment->LastSendTime);
  5377. }
  5378. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  5379. NetpTcpPrintSocketEndpoints(Socket, TRUE);
  5380. RtlDebugPrint(
  5381. " Freeing TX segment %d size %d for ACK %d.\n",
  5382. Segment->SequenceNumber - Socket->SendInitialSequence,
  5383. Segment->Length,
  5384. AcknowledgeNumber - Socket->SendInitialSequence);
  5385. }
  5386. //
  5387. // It would be weird for the remote host to acknowledge a packet not
  5388. // yet sent.
  5389. //
  5390. ASSERT(Segment->SendAttemptCount != 0);
  5391. LIST_REMOVE(&(Segment->Header.ListEntry));
  5392. if (LIST_EMPTY(&(Socket->OutgoingSegmentList)) != FALSE) {
  5393. NetpTcpTimerReleaseReference();
  5394. }
  5395. Socket->SendBufferFreeSize += Segment->Length;
  5396. if (Socket->SendBufferFreeSize > Socket->SendBufferTotalSize) {
  5397. Socket->SendBufferFreeSize = Socket->SendBufferTotalSize;
  5398. }
  5399. SignalTransmitReadyEvent = TRUE;
  5400. NetpTcpFreeSegment(Socket, &(Segment->Header));
  5401. //
  5402. // If the current acknowledge number is in the middle of the segment,
  5403. // update the offset. Don't touch the send buffer size in this case, as
  5404. // the memory is still allocated.
  5405. //
  5406. } else if (TCP_SEQUENCE_GREATER_THAN(AcknowledgeNumber, SegmentBegin)) {
  5407. //
  5408. // It would be weird for the remote host to acknowledge a segment
  5409. // not yet sent.
  5410. //
  5411. ASSERT(Segment->SendAttemptCount != 0);
  5412. Segment->Offset = AcknowledgeNumber - Segment->SequenceNumber;
  5413. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  5414. NetpTcpPrintSocketEndpoints(Socket, TRUE);
  5415. RtlDebugPrint(" Partial segment ACK: Segment %d, size %x, new "
  5416. "offset %x.\n",
  5417. Segment->SequenceNumber,
  5418. Segment->Length,
  5419. Segment->Offset);
  5420. }
  5421. break;
  5422. //
  5423. // This segment is wholly beyond the acknowledge number, so it and all
  5424. // the others must remain.
  5425. //
  5426. } else {
  5427. break;
  5428. }
  5429. }
  5430. //
  5431. // If some packets were freed up, signal the transmit ready event unless
  5432. // the final sequence has been reached.
  5433. //
  5434. if ((SignalTransmitReadyEvent != FALSE) &&
  5435. ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID) == 0) &&
  5436. ((Socket->State == TcpStateEstablished) ||
  5437. (Socket->State == TcpStateCloseWait))) {
  5438. IoSetIoObjectState(IoState, POLL_EVENT_OUT, TRUE);
  5439. }
  5440. return;
  5441. }
  5442. VOID
  5443. NetpTcpFreeSocketDataBuffers (
  5444. PTCP_SOCKET Socket
  5445. )
  5446. /*++
  5447. Routine Description:
  5448. This routine frees many resources associated with a socket, preparing it
  5449. to be deleted. This routine is usually called when a connection is reset
  5450. or a close has completed. This routine assumes the socket lock is already
  5451. acquired.
  5452. Arguments:
  5453. Socket - Supplies a pointer to the socket involved.
  5454. Return Value:
  5455. None.
  5456. --*/
  5457. {
  5458. PTCP_INCOMING_CONNECTION IncomingConnection;
  5459. PTCP_SEND_SEGMENT OutgoingSegment;
  5460. PTCP_RECEIVED_SEGMENT ReceivedSegment;
  5461. PTCP_SEGMENT_HEADER Segment;
  5462. //
  5463. // Loop through all outgoing packets and clean them up.
  5464. //
  5465. while (LIST_EMPTY(&(Socket->OutgoingSegmentList)) == FALSE) {
  5466. OutgoingSegment = LIST_VALUE(Socket->OutgoingSegmentList.Next,
  5467. TCP_SEND_SEGMENT,
  5468. Header.ListEntry);
  5469. LIST_REMOVE(&(OutgoingSegment->Header.ListEntry));
  5470. if (LIST_EMPTY(&(Socket->OutgoingSegmentList)) != FALSE) {
  5471. NetpTcpTimerReleaseReference();
  5472. }
  5473. MmFreePagedPool(OutgoingSegment);
  5474. }
  5475. //
  5476. // Loop through all received packets and clean them up too.
  5477. //
  5478. while (LIST_EMPTY(&(Socket->ReceivedSegmentList)) == FALSE) {
  5479. ReceivedSegment = LIST_VALUE(Socket->ReceivedSegmentList.Next,
  5480. TCP_RECEIVED_SEGMENT,
  5481. Header.ListEntry);
  5482. LIST_REMOVE(&(ReceivedSegment->Header.ListEntry));
  5483. MmFreePagedPool(ReceivedSegment);
  5484. }
  5485. //
  5486. // Release the list of free segments.
  5487. //
  5488. while (LIST_EMPTY(&(Socket->FreeSegmentList)) == FALSE) {
  5489. Segment = LIST_VALUE(Socket->FreeSegmentList.Next,
  5490. TCP_SEGMENT_HEADER,
  5491. ListEntry);
  5492. LIST_REMOVE(&(Segment->ListEntry));
  5493. MmFreePagedPool(Segment);
  5494. }
  5495. //
  5496. // Also free any pending incoming connections.
  5497. //
  5498. while (LIST_EMPTY(&(Socket->IncomingConnectionList)) == FALSE) {
  5499. IncomingConnection = LIST_VALUE(Socket->IncomingConnectionList.Next,
  5500. TCP_INCOMING_CONNECTION,
  5501. ListEntry);
  5502. LIST_REMOVE(&(IncomingConnection->ListEntry));
  5503. Socket->IncomingConnectionCount -= 1;
  5504. IoClose(IncomingConnection->IoHandle);
  5505. MmFreePagedPool(IncomingConnection);
  5506. }
  5507. ASSERT(Socket->IncomingConnectionCount == 0);
  5508. return;
  5509. }
  5510. VOID
  5511. NetpTcpShutdownUnlocked (
  5512. PTCP_SOCKET TcpSocket,
  5513. ULONG ShutdownType
  5514. )
  5515. /*++
  5516. Routine Description:
  5517. This routine shuts down communication with a given socket based on the
  5518. supplied shutdown state. This routine assumes that the socket lock is
  5519. already held.
  5520. Arguments:
  5521. TcpSocket - Supplies a pointer to the TCP socket.
  5522. ShutdownType - Supplies the shutdown type to perform. See the
  5523. SOCKET_SHUTDOWN_* definitions.
  5524. Return Value:
  5525. None.
  5526. --*/
  5527. {
  5528. BOOL ResetSent;
  5529. ASSERT(KeIsQueuedLockHeld(TcpSocket->Lock) != FALSE);
  5530. ResetSent = FALSE;
  5531. if ((ShutdownType & SOCKET_SHUTDOWN_READ) != 0) {
  5532. NetpTcpShutdownReceive(TcpSocket, &ResetSent);
  5533. }
  5534. if ((ResetSent == FALSE) &&
  5535. ((ShutdownType & SOCKET_SHUTDOWN_WRITE) != 0)) {
  5536. NetpTcpShutdownTransmit(TcpSocket);
  5537. }
  5538. return;
  5539. }
  5540. VOID
  5541. NetpTcpShutdownTransmit (
  5542. PTCP_SOCKET TcpSocket
  5543. )
  5544. /*++
  5545. Routine Description:
  5546. This routine shuts down the transmit side of communications, marking the
  5547. last sequence number and sending a FIN if already caught up. This routine
  5548. assumes the TCP socket lock is already held.
  5549. Arguments:
  5550. TcpSocket - Supplies a pointer to the socket to shut down.
  5551. Return Value:
  5552. None.
  5553. --*/
  5554. {
  5555. PULONG Flags;
  5556. PIO_OBJECT_STATE IoState;
  5557. PTCP_SEND_SEGMENT LastSegment;
  5558. PLIST_ENTRY OutgoingSegmentList;
  5559. ASSERT((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_WRITE) != 0);
  5560. ASSERT(KeIsQueuedLockHeld(TcpSocket->Lock) != FALSE);
  5561. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  5562. switch (TcpSocket->State) {
  5563. //
  5564. // Some states don't require a FIN to be sent; either the connection wasn't
  5565. // established enough, or it's already been sent.
  5566. //
  5567. case TcpStateClosed:
  5568. case TcpStateFinWait1:
  5569. case TcpStateFinWait2:
  5570. case TcpStateClosing:
  5571. case TcpStateLastAcknowledge:
  5572. case TcpStateTimeWait:
  5573. break;
  5574. //
  5575. // Some states don't need a FIN, but should have the transmit event
  5576. // signaled for anybody polling on this socket.
  5577. //
  5578. case TcpStateInitialized:
  5579. case TcpStateListening:
  5580. case TcpStateSynSent:
  5581. IoSetIoObjectState(IoState, POLL_EVENT_OUT, TRUE);
  5582. break;
  5583. //
  5584. // In the states with active connections, send a FIN segment (or at
  5585. // least queue that one needs to be sent).
  5586. //
  5587. case TcpStateSynReceived:
  5588. case TcpStateEstablished:
  5589. case TcpStateCloseWait:
  5590. //
  5591. // If the final sequence is yet to be determined, do it now and prepare
  5592. // to send the FIN. Only do this once as the socket is guaranteed to
  5593. // move out of the three above states. Another shutdown attempt should
  5594. // have no effect.
  5595. //
  5596. Flags = &(TcpSocket->Flags);
  5597. if ((*Flags & TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID) == 0) {
  5598. //
  5599. // Mark the "end of the line" sequence number.
  5600. //
  5601. TcpSocket->SendFinalSequence = TcpSocket->SendNextBufferSequence;
  5602. TcpSocket->SendNextBufferSequence += 1;
  5603. //
  5604. // If the outgoing segment list is not empty and the last segment
  5605. // has not yet been sent, then the FIN can be sent along with it.
  5606. //
  5607. ASSERT((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0);
  5608. OutgoingSegmentList = &(TcpSocket->OutgoingSegmentList);
  5609. if (LIST_EMPTY(OutgoingSegmentList) == FALSE) {
  5610. LastSegment = LIST_VALUE(OutgoingSegmentList->Previous,
  5611. TCP_SEND_SEGMENT,
  5612. Header.ListEntry);
  5613. if (LastSegment->SendAttemptCount == 0) {
  5614. LastSegment->Flags |= TCP_SEND_SEGMENT_FLAG_FIN;
  5615. *Flags |= TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA;
  5616. }
  5617. }
  5618. //
  5619. // Now that the final sequence and how the FIN will be sent have
  5620. // been determined, mark the final sequence valid.
  5621. //
  5622. *Flags |= TCP_SOCKET_FLAG_SEND_FINAL_SEQUENCE_VALID;
  5623. //
  5624. // No more sends are expected, so unset the transmit ready event,
  5625. // as it gets reused as a "close operation finished" event.
  5626. //
  5627. IoSetIoObjectState(IoState, POLL_EVENT_OUT, FALSE);
  5628. //
  5629. // If the acknowledged data is all caught up, send the FIN right
  5630. // away.
  5631. //
  5632. if (TcpSocket->SendUnacknowledgedSequence ==
  5633. TcpSocket->SendFinalSequence) {
  5634. ASSERT((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0);
  5635. ASSERT((TcpSocket->SendNextNetworkSequence + 1) ==
  5636. TcpSocket->SendNextBufferSequence);
  5637. TcpSocket->SendNextNetworkSequence += 1;
  5638. NetpTcpSendControlPacket(TcpSocket, TCP_HEADER_FLAG_FIN);
  5639. if (TcpSocket->State == TcpStateCloseWait) {
  5640. NetpTcpSetState(TcpSocket, TcpStateLastAcknowledge);
  5641. } else {
  5642. NetpTcpSetState(TcpSocket, TcpStateFinWait1);
  5643. }
  5644. //
  5645. // Otherwise if the FIN cannot be sent with a data packet, add a
  5646. // reference to the TCP timer to make sure it gets sent.
  5647. //
  5648. } else if ((*Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) {
  5649. NetpTcpTimerAddReference();
  5650. }
  5651. }
  5652. break;
  5653. default:
  5654. ASSERT(FALSE);
  5655. break;
  5656. }
  5657. return;
  5658. }
  5659. VOID
  5660. NetpTcpShutdownReceive (
  5661. PTCP_SOCKET TcpSocket,
  5662. PBOOL ResetSent
  5663. )
  5664. /*++
  5665. Routine Description:
  5666. This routine shuts down the receive side of communications, doing nothing
  5667. if all the received data has been read or sending a RST if it has not. This
  5668. routine assumes the TCP socket lock is already held.
  5669. Arguments:
  5670. TcpSocket - Supplies a pointer to the socket to shut down.
  5671. ResetSent - Supplies a pointer to a boolean that receives status as to
  5672. whether or not a reset was sent.
  5673. Return Value:
  5674. None.
  5675. --*/
  5676. {
  5677. ASSERT((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0);
  5678. ASSERT(KeIsQueuedLockHeld(TcpSocket->Lock) != FALSE);
  5679. *ResetSent = FALSE;
  5680. switch (TcpSocket->State) {
  5681. //
  5682. // There is nothing to do for most states. Either a connection was never
  5683. // initialized by the other side or a FIN has been received from the other
  5684. // side.
  5685. //
  5686. case TcpStateClosed:
  5687. case TcpStateClosing:
  5688. case TcpStateLastAcknowledge:
  5689. case TcpStateTimeWait:
  5690. case TcpStateInitialized:
  5691. case TcpStateListening:
  5692. case TcpStateSynSent:
  5693. break;
  5694. //
  5695. // In the states where packets can come in and a FIN needs to be sent to
  5696. // close the connection, send a RST if not all of the received data has
  5697. // been read.
  5698. //
  5699. case TcpStateFinWait1:
  5700. case TcpStateFinWait2:
  5701. case TcpStateSynReceived:
  5702. case TcpStateEstablished:
  5703. case TcpStateCloseWait:
  5704. if (LIST_EMPTY(&(TcpSocket->ReceivedSegmentList)) == FALSE) {
  5705. NetpTcpSendControlPacket(TcpSocket, TCP_HEADER_FLAG_RESET);
  5706. NetpTcpCloseOutSocket(TcpSocket, FALSE);
  5707. *ResetSent = TRUE;
  5708. }
  5709. break;
  5710. default:
  5711. ASSERT(FALSE);
  5712. break;
  5713. }
  5714. return;
  5715. }
  5716. KSTATUS
  5717. NetpTcpCloseOutSocket (
  5718. PTCP_SOCKET Socket,
  5719. BOOL InsideWorker
  5720. )
  5721. /*++
  5722. Routine Description:
  5723. This routine sets the socket to the closed state. This routine assumes the
  5724. socket lock is already held, and WILL briefly release it unless inside
  5725. the TCP worker thread.
  5726. Arguments:
  5727. Socket - Supplies a pointer to the socket to destroy.
  5728. InsideWorker - Supplies a boolean indicating that this routine is being
  5729. called from inside the TCP worker thread and that all locks are already
  5730. held.
  5731. Return Value:
  5732. Status code.
  5733. --*/
  5734. {
  5735. BOOL CloseSocket;
  5736. PIO_OBJECT_STATE IoState;
  5737. KSTATUS Status;
  5738. ASSERT(KeGetRunLevel() == RunLevelLow);
  5739. CloseSocket = FALSE;
  5740. IoState = Socket->NetSocket.KernelSocket.IoState;
  5741. Status = STATUS_SUCCESS;
  5742. //
  5743. // Check to see if the socket needs to be closed. Be careful as the state
  5744. // can change once the lock is releaed.
  5745. //
  5746. if (Socket->State != TcpStateClosed) {
  5747. CloseSocket = TRUE;
  5748. if (InsideWorker == FALSE) {
  5749. //
  5750. // Release the socket lock to prevent a deadlock (the TCP worker
  5751. // thread acquires the socket list lock, then the socket). This
  5752. // shouldn't be a problem for callers since closing out the socket
  5753. // is pretty much the last thing done to a socket. Then acquire the
  5754. // socket list lock and the socket lock (now in the right order)
  5755. // and remove the socket from being observable by the worker
  5756. // thread.
  5757. //
  5758. KeReleaseQueuedLock(Socket->Lock);
  5759. KeAcquireQueuedLock(NetTcpSocketListLock);
  5760. KeAcquireQueuedLock(Socket->Lock);
  5761. //
  5762. // While the lock was released, the socket may have been closed.
  5763. // Prepare to bail out on the rest of the work.
  5764. //
  5765. if (Socket->State == TcpStateClosed) {
  5766. CloseSocket = FALSE;
  5767. //
  5768. // While the lock is held, remove the socket from the global list.
  5769. //
  5770. } else {
  5771. LIST_REMOVE(&(Socket->ListEntry));
  5772. Socket->ListEntry.Next = NULL;
  5773. }
  5774. KeReleaseQueuedLock(NetTcpSocketListLock);
  5775. }
  5776. }
  5777. //
  5778. // Close out the socket if it was deteremined to not be in the closed state
  5779. // after all the lock ordering checks above.
  5780. //
  5781. if (CloseSocket != FALSE) {
  5782. ASSERT(Socket->State != TcpStateClosed);
  5783. //
  5784. // Be careful as the socket may have been removed from the global list
  5785. // above in the case where the global lock was not held upon entrance
  5786. // into this routine.
  5787. //
  5788. if (Socket->ListEntry.Next != NULL) {
  5789. ASSERT(InsideWorker != FALSE);
  5790. LIST_REMOVE(&(Socket->ListEntry));
  5791. Socket->ListEntry.Next = NULL;
  5792. }
  5793. //
  5794. // Leave the socket lock held to prevent late senders from getting
  5795. // involved, close the socket.
  5796. //
  5797. NetpTcpSetState(Socket, TcpStateClosed);
  5798. Status = Socket->NetSocket.Network->Interface.Close(
  5799. &(Socket->NetSocket));
  5800. //
  5801. // Release the reference taken for the TCP connection, after which the
  5802. // socket can't be touched as it may get destroyed.
  5803. //
  5804. IoSocketReleaseReference(&(Socket->NetSocket.KernelSocket));
  5805. //
  5806. // Just signal the event, the socket's already closed.
  5807. //
  5808. } else {
  5809. IoSetIoObjectState(IoState, TCP_POLL_EVENT_IO, TRUE);
  5810. }
  5811. return Status;
  5812. }
  5813. VOID
  5814. NetpTcpHandleIncomingConnection (
  5815. PTCP_SOCKET ListeningSocket,
  5816. PTCP_HEADER Header,
  5817. PNET_PACKET_BUFFER Packet,
  5818. PNET_LINK Link,
  5819. PNETWORK_ADDRESS LocalAddress,
  5820. PNETWORK_ADDRESS RemoteAddress
  5821. )
  5822. /*++
  5823. Routine Description:
  5824. This routine handles an incoming TCP connection on a listening socket. It
  5825. spawns a new TCP socket bound to the remote address, sends the SYN+ACK,
  5826. and adds an entry onto the listening socket's incoming connection list.
  5827. Arguments:
  5828. ListeningSocket - Supplies a pointer to the original listening socket that
  5829. just saw an incoming connection request.
  5830. Header - Supplies a pointer to the valid TCP header containing the SYN.
  5831. Packet - Supplies a pointer to the packet body, used to parse any options
  5832. in the header.
  5833. Link - Supplies a pointer to the link this connection was received on.
  5834. LocalAddress - Supplies a pointer to the local address this connection was
  5835. received on.
  5836. RemoteAddress - Supplies a pointer to the remote address making the
  5837. connection request.
  5838. Return Value:
  5839. None.
  5840. --*/
  5841. {
  5842. PTCP_INCOMING_CONNECTION IncomingConnection;
  5843. PIO_OBJECT_STATE IoState;
  5844. BOOL LockHeld;
  5845. ULONG NetSocketFlags;
  5846. ULONG NetworkProtocol;
  5847. PIO_HANDLE NewIoHandle;
  5848. PTCP_SOCKET NewTcpSocket;
  5849. ULONG RemoteSequence;
  5850. ULONG ResetFlags;
  5851. ULONG ResetSequenceNumber;
  5852. KSTATUS Status;
  5853. LockHeld = FALSE;
  5854. NewIoHandle = NULL;
  5855. NewTcpSocket = NULL;
  5856. IncomingConnection = MmAllocatePagedPool(sizeof(TCP_INCOMING_CONNECTION),
  5857. TCP_ALLOCATION_TAG);
  5858. if (IncomingConnection == NULL) {
  5859. Status = STATUS_INSUFFICIENT_RESOURCES;
  5860. goto TcpHandleIncomingConnectionEnd;
  5861. }
  5862. RtlZeroMemory(IncomingConnection, sizeof(TCP_INCOMING_CONNECTION));
  5863. //
  5864. // Create a new socket for this connection.
  5865. //
  5866. ASSERT(LocalAddress->Domain == RemoteAddress->Domain);
  5867. ASSERT(ListeningSocket->NetSocket.KernelSocket.Protocol ==
  5868. SOCKET_INTERNET_PROTOCOL_TCP);
  5869. NetworkProtocol = ListeningSocket->NetSocket.KernelSocket.Protocol;
  5870. Status = IoSocketCreate(LocalAddress->Domain,
  5871. NetSocketStream,
  5872. NetworkProtocol,
  5873. 0,
  5874. &NewIoHandle);
  5875. if (!KSUCCESS(Status)) {
  5876. goto TcpHandleIncomingConnectionEnd;
  5877. }
  5878. Status = IoGetSocketFromHandle(NewIoHandle, (PVOID)&NewTcpSocket);
  5879. if (!KSUCCESS(Status)) {
  5880. goto TcpHandleIncomingConnectionEnd;
  5881. }
  5882. //
  5883. // Carry over the net socket flags from the original socket. Also record
  5884. // that this socket was copied from a listener to allow reuse of the local
  5885. // port on bind.
  5886. //
  5887. NetSocketFlags = ListeningSocket->NetSocket.Flags &
  5888. NET_SOCKET_FLAGS_INHERIT_MASK;
  5889. NetSocketFlags |= NET_SOCKET_FLAG_FORKED_LISTENER;
  5890. RtlAtomicOr32(&(NewTcpSocket->NetSocket.Flags), NetSocketFlags);
  5891. IoSocketAddReference(&(NewTcpSocket->NetSocket.KernelSocket));
  5892. KeAcquireQueuedLock(NewTcpSocket->Lock);
  5893. LockHeld = TRUE;
  5894. //
  5895. // Bind the new socket to the local address.
  5896. //
  5897. Status = NewTcpSocket->NetSocket.Network->Interface.BindToAddress(
  5898. &(NewTcpSocket->NetSocket),
  5899. Link,
  5900. LocalAddress);
  5901. if (!KSUCCESS(Status)) {
  5902. goto TcpHandleIncomingConnectionEnd;
  5903. }
  5904. //
  5905. // Bind the new socket to the remote address.
  5906. //
  5907. Status = NewTcpSocket->NetSocket.Network->Interface.Connect(
  5908. (PNET_SOCKET)NewTcpSocket,
  5909. RemoteAddress);
  5910. if (!KSUCCESS(Status)) {
  5911. goto TcpHandleIncomingConnectionEnd;
  5912. }
  5913. //
  5914. // Inherit configurable options from the listening socket.
  5915. //
  5916. ASSERT(ListeningSocket->SendBufferTotalSize ==
  5917. ListeningSocket->SendBufferFreeSize);
  5918. NewTcpSocket->SendBufferTotalSize = ListeningSocket->SendBufferTotalSize;
  5919. NewTcpSocket->SendBufferFreeSize = ListeningSocket->SendBufferFreeSize;
  5920. NewTcpSocket->SendTimeout = ListeningSocket->SendTimeout;
  5921. ASSERT(ListeningSocket->ReceiveWindowTotalSize ==
  5922. ListeningSocket->ReceiveWindowFreeSize);
  5923. NewTcpSocket->ReceiveWindowTotalSize =
  5924. ListeningSocket->ReceiveWindowTotalSize;
  5925. NewTcpSocket->ReceiveWindowFreeSize =
  5926. ListeningSocket->ReceiveWindowFreeSize;
  5927. NewTcpSocket->ReceiveWindowScale = ListeningSocket->ReceiveWindowScale;
  5928. NewTcpSocket->ReceiveTimeout = ListeningSocket->ReceiveTimeout;
  5929. NewTcpSocket->ReceiveMinimum = ListeningSocket->ReceiveMinimum;
  5930. if ((ListeningSocket->Flags & TCP_SOCKET_FLAG_LINGER_ENABLED) != 0) {
  5931. NewTcpSocket->Flags |= TCP_SOCKET_FLAG_LINGER_ENABLED;
  5932. }
  5933. NewTcpSocket->LingerTimeout = ListeningSocket->LingerTimeout;
  5934. //
  5935. // Re-parse any options coming from the SYN packet and set up the sequence
  5936. // numbers.
  5937. //
  5938. NetpTcpProcessPacketOptions(NewTcpSocket, Header, Packet);
  5939. RemoteSequence = NETWORK_TO_CPU32(Header->SequenceNumber);
  5940. NewTcpSocket->ReceiveInitialSequence = RemoteSequence;
  5941. NewTcpSocket->ReceiveNextSequence = RemoteSequence + 1;
  5942. NewTcpSocket->ReceiveUnreadSequence = NewTcpSocket->ReceiveNextSequence;
  5943. //
  5944. // If there are already too many connections queued, send a RESET and kill
  5945. // this one.
  5946. //
  5947. if (ListeningSocket->IncomingConnectionCount >=
  5948. ListeningSocket->NetSocket.MaxIncomingConnections) {
  5949. Status = STATUS_TOO_MANY_CONNECTIONS;
  5950. goto TcpHandleIncomingConnectionEnd;
  5951. }
  5952. //
  5953. // Set the state, which will send out an SYN+ACK and kick off some retries.
  5954. //
  5955. NetpTcpSetState(NewTcpSocket, TcpStateSynReceived);
  5956. IncomingConnection->IoHandle = NewIoHandle;
  5957. ListeningSocket->IncomingConnectionCount += 1;
  5958. INSERT_BEFORE(&(IncomingConnection->ListEntry),
  5959. &(ListeningSocket->IncomingConnectionList));
  5960. IoState = ListeningSocket->NetSocket.KernelSocket.IoState;
  5961. IoSetIoObjectState(IoState, POLL_EVENT_IN, TRUE);
  5962. Status = STATUS_SUCCESS;
  5963. TcpHandleIncomingConnectionEnd:
  5964. if (!KSUCCESS(Status)) {
  5965. if (Status == STATUS_TOO_MANY_CONNECTIONS) {
  5966. ResetSequenceNumber = NETWORK_TO_CPU32(
  5967. Header->AcknowledgmentNumber);
  5968. ResetFlags = TCP_HEADER_FLAG_RESET | TCP_HEADER_FLAG_ACKNOWLEDGE;
  5969. NewTcpSocket->SendUnacknowledgedSequence = ResetSequenceNumber;
  5970. NetpTcpSendControlPacket(NewTcpSocket, ResetFlags);
  5971. }
  5972. if (IncomingConnection != NULL) {
  5973. MmFreePagedPool(IncomingConnection);
  5974. }
  5975. }
  5976. if (LockHeld != FALSE) {
  5977. ASSERT(NewTcpSocket != NULL);
  5978. KeReleaseQueuedLock(NewTcpSocket->Lock);
  5979. IoSocketReleaseReference(&(NewTcpSocket->NetSocket.KernelSocket));
  5980. }
  5981. //
  5982. // Now that the socket's lock has been released, close the handle.
  5983. //
  5984. if (!KSUCCESS(Status)) {
  5985. if (NewIoHandle != NULL) {
  5986. IoClose(NewIoHandle);
  5987. }
  5988. }
  5989. return;
  5990. }
  5991. VOID
  5992. NetpTcpSetState (
  5993. PTCP_SOCKET Socket,
  5994. TCP_STATE NewState
  5995. )
  5996. /*++
  5997. Routine Description:
  5998. This routine sets the given TCP socket's state, performing any default
  5999. behavior that should happen once that state is reached.
  6000. Arguments:
  6001. Socket - Supplies a pointer to the socket whose state is being updated.
  6002. NewState - Supplies the new TCP state for the socket.
  6003. Return Value:
  6004. None.
  6005. --*/
  6006. {
  6007. PNET_SOCKET NetSocket;
  6008. TCP_STATE OldState;
  6009. OldState = Socket->State;
  6010. Socket->State = NewState;
  6011. //
  6012. // Modify the socket based on the new state.
  6013. //
  6014. switch (NewState) {
  6015. case TcpStateInitialized:
  6016. ASSERT((OldState == TcpStateInvalid) ||
  6017. (OldState == TcpStateSynReceived) ||
  6018. (OldState == TcpStateSynSent));
  6019. //
  6020. // When transitioning to the initialized state from the SYN-sent or
  6021. // SYN-received state, disconnect the socket from its remote address
  6022. // and reset the retry values and backtrack on the buffer sequences.
  6023. // Reset the error event as well, the socket could try to connect again.
  6024. //
  6025. if ((OldState == TcpStateSynReceived) ||
  6026. (OldState == TcpStateSynSent)) {
  6027. NetSocket = &(Socket->NetSocket);
  6028. NetSocket->Network->Interface.Disconnect(NetSocket);
  6029. Socket->RetryTime = 0;
  6030. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  6031. Socket->SendNextBufferSequence = Socket->SendInitialSequence;
  6032. Socket->SendNextNetworkSequence = Socket->SendInitialSequence;
  6033. }
  6034. break;
  6035. case TcpStateListening:
  6036. ASSERT(OldState == TcpStateInitialized);
  6037. break;
  6038. case TcpStateSynSent:
  6039. ASSERT(OldState == TcpStateInitialized);
  6040. //
  6041. // Make sure that the error event is not signalled. Give the socket a
  6042. // new chance to connect.
  6043. //
  6044. IoSetIoObjectState(Socket->NetSocket.KernelSocket.IoState,
  6045. POLL_EVENT_ERROR,
  6046. FALSE);
  6047. Socket->SendNextBufferSequence += 1;
  6048. Socket->SendNextNetworkSequence += 1;
  6049. TCP_UPDATE_RETRY_TIME(Socket);
  6050. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6051. NetpTcpTimerAddReference();
  6052. NetpTcpSendSyn(Socket, FALSE);
  6053. break;
  6054. case TcpStateSynReceived:
  6055. ASSERT((OldState == TcpStateInitialized) ||
  6056. (OldState == TcpStateSynSent));
  6057. if (OldState == TcpStateInitialized) {
  6058. //
  6059. // Make sure that the error event is not signalled. Give the socket
  6060. // a new chance to connect.
  6061. //
  6062. IoSetIoObjectState(Socket->NetSocket.KernelSocket.IoState,
  6063. POLL_EVENT_ERROR,
  6064. FALSE);
  6065. Socket->SendNextBufferSequence += 1;
  6066. Socket->SendNextNetworkSequence += 1;
  6067. TCP_UPDATE_RETRY_TIME(Socket);
  6068. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6069. NetpTcpTimerAddReference();
  6070. }
  6071. NetpTcpSendSyn(Socket, TRUE);
  6072. break;
  6073. case TcpStateEstablished:
  6074. ASSERT((OldState == TcpStateSynReceived) ||
  6075. (OldState == TcpStateSynSent));
  6076. Socket->RetryTime = 0;
  6077. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  6078. NetpTcpTimerReleaseReference();
  6079. NetpTcpCongestionConnectionEstablished(Socket);
  6080. IoSetIoObjectState(Socket->NetSocket.KernelSocket.IoState,
  6081. POLL_EVENT_OUT,
  6082. TRUE);
  6083. break;
  6084. case TcpStateFinWait1:
  6085. ASSERT((OldState == TcpStateSynReceived) ||
  6086. (OldState == TcpStateEstablished));
  6087. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) {
  6088. Socket->RetryTime = 0;
  6089. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  6090. TCP_UPDATE_RETRY_TIME(Socket);
  6091. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6092. if (OldState == TcpStateEstablished) {
  6093. NetpTcpTimerAddReference();
  6094. }
  6095. }
  6096. break;
  6097. case TcpStateFinWait2:
  6098. ASSERT(OldState == TcpStateFinWait1);
  6099. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) {
  6100. NetpTcpTimerReleaseReference();
  6101. }
  6102. break;
  6103. //
  6104. // The close-wait state is reached when a FIN is received while in the
  6105. // established state. Not much to do here. Data can still be sent and the
  6106. // socket is just waiting on a local close.
  6107. //
  6108. case TcpStateCloseWait:
  6109. ASSERT(OldState == TcpStateEstablished);
  6110. break;
  6111. //
  6112. // The closing state is still waiting on a FIN to be ACK'd. But since the
  6113. // remote is clearly still alive, reset the retry and timeout. Keep the
  6114. // reference on the timer taken during FIN-Wait1 alive. Keep in mind that
  6115. // this logic is only valid if there isn't more data to send, as evidenced
  6116. // by whether or not the FIN is to be sent with data.
  6117. //
  6118. case TcpStateClosing:
  6119. ASSERT(OldState == TcpStateFinWait1);
  6120. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) {
  6121. Socket->RetryTime = 0;
  6122. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  6123. TCP_UPDATE_RETRY_TIME(Socket);
  6124. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6125. }
  6126. break;
  6127. //
  6128. // The last acknowledge state is waiting for a FIN to be acknowledged.
  6129. // Reinitialize the retry period for resending the FIN and set the default
  6130. // timeout. The close wait state does not have a reference on the timer, so
  6131. // take a new one. This only applies if there isn't data being sent with
  6132. // the FIN.
  6133. //
  6134. case TcpStateLastAcknowledge:
  6135. ASSERT(OldState == TcpStateCloseWait);
  6136. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0) {
  6137. Socket->RetryTime = 0;
  6138. Socket->RetryWaitPeriod = TCP_INITIAL_RETRY_WAIT_PERIOD;
  6139. TCP_UPDATE_RETRY_TIME(Socket);
  6140. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6141. NetpTcpTimerAddReference();
  6142. }
  6143. break;
  6144. //
  6145. // The time wait state just sits around until the timeout expires. Set the
  6146. // default timeout and take a reference on the timer if coming from a state
  6147. // that does not have a reference on the timer.
  6148. //
  6149. case TcpStateTimeWait:
  6150. ASSERT((OldState == TcpStateFinWait1) ||
  6151. (OldState == TcpStateFinWait2) ||
  6152. (OldState == TcpStateClosing));
  6153. RtlAtomicOr32(&(Socket->NetSocket.Flags), NET_SOCKET_FLAG_TIME_WAIT);
  6154. TCP_SET_DEFAULT_TIMEOUT(Socket);
  6155. if ((OldState == TcpStateFinWait2) ||
  6156. ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) != 0)) {
  6157. NetpTcpTimerAddReference();
  6158. }
  6159. break;
  6160. //
  6161. // The closed state can be reached from just about every other state. If
  6162. // the old state had a reference on the timer, then release that reference.
  6163. //
  6164. case TcpStateClosed:
  6165. if ((TCP_IS_SYN_RETRY_STATE(OldState) != FALSE) ||
  6166. ((TCP_IS_FIN_RETRY_STATE(OldState) != FALSE) &&
  6167. ((Socket->Flags & TCP_SOCKET_FLAG_SEND_FIN_WITH_DATA) == 0)) ||
  6168. (OldState == TcpStateTimeWait)) {
  6169. NetpTcpTimerReleaseReference();
  6170. }
  6171. if ((Socket->Flags & TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE) != 0) {
  6172. Socket->Flags &= ~TCP_SOCKET_FLAG_SEND_ACKNOWLEDGE;
  6173. NetpTcpTimerReleaseReference();
  6174. }
  6175. NetpTcpFreeSocketDataBuffers(Socket);
  6176. IoSetIoObjectState(Socket->NetSocket.KernelSocket.IoState,
  6177. TCP_POLL_EVENT_IO,
  6178. TRUE);
  6179. break;
  6180. default:
  6181. ASSERT(FALSE);
  6182. break;
  6183. }
  6184. return;
  6185. }
  6186. KSTATUS
  6187. NetpTcpSendSyn (
  6188. PTCP_SOCKET Socket,
  6189. BOOL WithAcknowledge
  6190. )
  6191. /*++
  6192. Routine Description:
  6193. This routine sends a SYN packet with all the fancy options on it.
  6194. Arguments:
  6195. Socket - Supplies a pointer to the socket to use for the connection.
  6196. WithAcknowledge - Supplies a boolean indicating whether this should just be
  6197. a plain SYN (FALSE) or a SYN+ACK (TRUE).
  6198. Return Value:
  6199. Status code.
  6200. --*/
  6201. {
  6202. ULONG ControlFlags;
  6203. ULONG DataSize;
  6204. ULONG MaximumSegmentSize;
  6205. PNET_SOCKET NetSocket;
  6206. PNET_PACKET_BUFFER Packet;
  6207. PUCHAR PacketBuffer;
  6208. NET_PACKET_LIST PacketList;
  6209. KSTATUS Status;
  6210. NetSocket = &(Socket->NetSocket);
  6211. NET_INITIALIZE_PACKET_LIST(&PacketList);
  6212. DataSize = TCP_OPTION_MSS_SIZE;
  6213. if ((Socket->Flags & TCP_SOCKET_FLAG_WINDOW_SCALING) != 0) {
  6214. DataSize += TCP_OPTION_WINDOW_SCALE_SIZE + TCP_OPTION_NOP_SIZE;
  6215. }
  6216. //
  6217. // Allocate the SYN packet that will kick things off with the remote host.
  6218. //
  6219. Packet = NULL;
  6220. Status = NetAllocateBuffer(NetSocket->PacketSizeInformation.HeaderSize,
  6221. DataSize,
  6222. NetSocket->PacketSizeInformation.FooterSize,
  6223. NetSocket->Link,
  6224. 0,
  6225. &Packet);
  6226. if (!KSUCCESS(Status)) {
  6227. goto TcpSendSynEnd;
  6228. }
  6229. NET_ADD_PACKET_TO_LIST(Packet, &PacketList);
  6230. //
  6231. // Initialize the options of the SYN packet. The first option will be the
  6232. // Maximum Segment Size.
  6233. //
  6234. PacketBuffer = (PUCHAR)(Packet->Buffer + Packet->DataOffset);
  6235. *PacketBuffer = TCP_OPTION_MAXIMUM_SEGMENT_SIZE;
  6236. PacketBuffer += 1;
  6237. *PacketBuffer = TCP_OPTION_MSS_SIZE;
  6238. PacketBuffer += 1;
  6239. MaximumSegmentSize = NetSocket->PacketSizeInformation.MaxPacketSize -
  6240. NetSocket->PacketSizeInformation.HeaderSize -
  6241. NetSocket->PacketSizeInformation.FooterSize;
  6242. if (MaximumSegmentSize > MAX_USHORT) {
  6243. MaximumSegmentSize = MAX_USHORT;
  6244. }
  6245. //
  6246. // Save the maximum segment size for future use.
  6247. //
  6248. Socket->ReceiveMaxSegmentSize = MaximumSegmentSize;
  6249. *((PUSHORT)PacketBuffer) = CPU_TO_NETWORK16(MaximumSegmentSize);
  6250. PacketBuffer += sizeof(USHORT);
  6251. //
  6252. // Add the Window Scale option if the remote supports it.
  6253. //
  6254. if ((Socket->Flags & TCP_SOCKET_FLAG_WINDOW_SCALING) != 0) {
  6255. *PacketBuffer = TCP_OPTION_WINDOW_SCALE;
  6256. PacketBuffer += 1;
  6257. *PacketBuffer = TCP_OPTION_WINDOW_SCALE_SIZE;
  6258. PacketBuffer += 1;
  6259. *PacketBuffer = (UCHAR)(Socket->ReceiveWindowScale);
  6260. PacketBuffer += 1;
  6261. //
  6262. // Add a padding option to get the header length to a multiple of
  6263. // 32-bits (as the header length field can only express such granules).
  6264. //
  6265. *PacketBuffer = TCP_OPTION_NOP;
  6266. PacketBuffer += 1;
  6267. }
  6268. //
  6269. // Add the TCP header and send this packet down the wire. Remember that the
  6270. // semantics of the ACK flag are different for the function below, so by
  6271. // passing it here it's being cleared in the header (making SYN the only
  6272. // flag set in the packet).
  6273. //
  6274. ControlFlags = TCP_HEADER_FLAG_SYN;
  6275. if (WithAcknowledge == FALSE) {
  6276. ControlFlags |= TCP_HEADER_FLAG_ACKNOWLEDGE;
  6277. }
  6278. ASSERT(Packet->DataOffset >= sizeof(TCP_HEADER));
  6279. Packet->DataOffset -= sizeof(TCP_HEADER);
  6280. NetpTcpFillOutHeader(Socket,
  6281. Packet,
  6282. Socket->SendInitialSequence,
  6283. ControlFlags,
  6284. DataSize,
  6285. 0,
  6286. 0);
  6287. Status = NetSocket->Network->Interface.Send(NetSocket,
  6288. &(NetSocket->RemoteAddress),
  6289. NULL,
  6290. &PacketList);
  6291. if (!KSUCCESS(Status)) {
  6292. goto TcpSendSynEnd;
  6293. }
  6294. TcpSendSynEnd:
  6295. if (!KSUCCESS(Status)) {
  6296. NetDestroyBufferList(&PacketList);
  6297. }
  6298. return Status;
  6299. }
  6300. VOID
  6301. NetpTcpTimerAddReference (
  6302. VOID
  6303. )
  6304. /*++
  6305. Routine Description:
  6306. This routine increments the reference count on the TCP timer, ensuring that
  6307. it runs.
  6308. Arguments:
  6309. None.
  6310. Return Value:
  6311. None.
  6312. --*/
  6313. {
  6314. ULONG OldReferenceCount;
  6315. OldReferenceCount = RtlAtomicAdd32(&NetTcpTimerReferenceCount, 1);
  6316. ASSERT(OldReferenceCount < TCP_TIMER_MAX_REFERENCE);
  6317. if (OldReferenceCount == 0) {
  6318. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  6319. RtlDebugPrint("TCP: Enabled periodic timer.\n");
  6320. }
  6321. NetpTcpQueueTcpTimer();
  6322. }
  6323. return;
  6324. }
  6325. ULONG
  6326. NetpTcpTimerReleaseReference (
  6327. VOID
  6328. )
  6329. /*++
  6330. Routine Description:
  6331. This routine decrements the reference count on the TCP timer, canceling it
  6332. if no one else is using it.
  6333. Arguments:
  6334. None.
  6335. Return Value:
  6336. Returns the old reference count on the TCP timer.
  6337. --*/
  6338. {
  6339. ULONG OldReferenceCount;
  6340. OldReferenceCount = RtlAtomicAdd32(&NetTcpTimerReferenceCount, (ULONG)-1);
  6341. ASSERT((OldReferenceCount != 0) &&
  6342. (OldReferenceCount < TCP_TIMER_MAX_REFERENCE));
  6343. return OldReferenceCount;
  6344. }
  6345. VOID
  6346. NetpTcpQueueTcpTimer (
  6347. VOID
  6348. )
  6349. /*++
  6350. Routine Description:
  6351. This routine queues the TCP timer.
  6352. Arguments:
  6353. None.
  6354. Return Value:
  6355. None.
  6356. --*/
  6357. {
  6358. ULONGLONG DueTime;
  6359. KSTATUS Status;
  6360. ASSERT(KeGetRunLevel() == RunLevelLow);
  6361. //
  6362. // Add a reference for the TCP worker and queue the timer.
  6363. //
  6364. RtlAtomicAdd32(&NetTcpTimerReferenceCount, 1);
  6365. DueTime = KeGetRecentTimeCounter();
  6366. DueTime += NetTcpTimerPeriod;
  6367. Status = KeQueueTimer(NetTcpTimer,
  6368. TimerQueueSoftWake,
  6369. DueTime,
  6370. 0,
  6371. 0,
  6372. NULL);
  6373. if (!KSUCCESS(Status)) {
  6374. RtlDebugPrint("Error: Failed to queue TCP timer: %d\n", Status);
  6375. }
  6376. return;
  6377. }
  6378. VOID
  6379. NetpTcpArmKeepAliveTimer (
  6380. ULONGLONG DueTime
  6381. )
  6382. /*++
  6383. Routine Description:
  6384. This routine arms or re-arms the keep alive timer to the given due time if
  6385. it is less than the current due time.
  6386. Arguments:
  6387. DueTime - Supplies the value of the time tick counter when the keep alive
  6388. timer should expire.
  6389. Return Value:
  6390. None.
  6391. --*/
  6392. {
  6393. ULONGLONG CurrentDueTime;
  6394. KSTATUS Status;
  6395. ASSERT(KeGetRunLevel() == RunLevelLow);
  6396. //
  6397. // If the timer's current due time is 0 (not queued) or greater than the
  6398. // requested due time, cancel the timer and re-queue it.
  6399. //
  6400. KeAcquireQueuedLock(NetTcpKeepAliveTimerLock);
  6401. CurrentDueTime = KeGetTimerDueTime(NetTcpKeepAliveTimer);
  6402. if ((CurrentDueTime == 0) || (CurrentDueTime > DueTime)) {
  6403. if (NetTcpDebugPrintSequenceNumbers != FALSE) {
  6404. RtlDebugPrint("TCP: Arming keep alive timer.\n");
  6405. }
  6406. KeCancelTimer(NetTcpKeepAliveTimer);
  6407. Status = KeQueueTimer(NetTcpKeepAliveTimer,
  6408. TimerQueueSoftWake,
  6409. DueTime,
  6410. 0,
  6411. 0,
  6412. NULL);
  6413. if (!KSUCCESS(Status)) {
  6414. RtlDebugPrint("Error: Failed to queue TCP keep alive timer: %d\n",
  6415. Status);
  6416. }
  6417. }
  6418. KeReleaseQueuedLock(NetTcpKeepAliveTimerLock);
  6419. return;
  6420. }
  6421. KSTATUS
  6422. NetpTcpReceiveOutOfBandData (
  6423. BOOL FromKernelMode,
  6424. PTCP_SOCKET TcpSocket,
  6425. PSOCKET_IO_PARAMETERS Parameters,
  6426. PIO_BUFFER IoBuffer
  6427. )
  6428. /*++
  6429. Routine Description:
  6430. This routine is called by the user to receive data from the socket.
  6431. Arguments:
  6432. FromKernelMode - Supplies a boolean indicating whether the request is
  6433. coming from kernel mode (TRUE) or user mode (FALSE).
  6434. TcpSocket - Supplies a pointer to the socket to receive data from.
  6435. Parameters - Supplies a pointer to the socket I/O parameters.
  6436. IoBuffer - Supplies a pointer to the I/O buffer where the received data
  6437. will be returned.
  6438. Return Value:
  6439. STATUS_SUCCESS if any bytes were read.
  6440. STATUS_TIMEOUT if the request timed out.
  6441. STATUS_BUFFER_TOO_SMALL if the incoming datagram was too large for the
  6442. buffer. The remainder of the datagram is discarded in this case.
  6443. Other error codes on other failures.
  6444. --*/
  6445. {
  6446. UINTN BytesComplete;
  6447. ULONGLONG CurrentTime;
  6448. ULONGLONG EndTime;
  6449. PIO_OBJECT_STATE IoState;
  6450. BOOL LockHeld;
  6451. ULONG ReturnedEvents;
  6452. UINTN Size;
  6453. KSTATUS Status;
  6454. ULONGLONG TimeCounterFrequency;
  6455. ULONG Timeout;
  6456. UINTN WaitTime;
  6457. BytesComplete = 0;
  6458. IoState = TcpSocket->NetSocket.KernelSocket.IoState;
  6459. LockHeld = FALSE;
  6460. Parameters->SocketIoFlags = 0;
  6461. Size = Parameters->Size;
  6462. Timeout = Parameters->TimeoutInMilliseconds;
  6463. //
  6464. // If OOB data is sent inline, this is not a valid call.
  6465. //
  6466. if ((TcpSocket->Flags & TCP_SOCKET_FLAG_URGENT_INLINE) != 0) {
  6467. Status = STATUS_INVALID_PARAMETER;
  6468. goto TcpReceiveOutOfBandDataEnd;
  6469. }
  6470. if (Size == 0) {
  6471. Status = STATUS_SUCCESS;
  6472. goto TcpReceiveOutOfBandDataEnd;
  6473. }
  6474. //
  6475. // Set a timeout timer to give up on. The socket stores the maximum timeout.
  6476. //
  6477. if (Timeout > TcpSocket->ReceiveTimeout) {
  6478. Timeout = TcpSocket->ReceiveTimeout;
  6479. }
  6480. EndTime = 0;
  6481. if ((Timeout != 0) && (Timeout != WAIT_TIME_INDEFINITE)) {
  6482. EndTime = KeGetRecentTimeCounter();
  6483. EndTime += KeConvertMicrosecondsToTimeTicks(
  6484. Timeout * MICROSECONDS_PER_MILLISECOND);
  6485. }
  6486. TimeCounterFrequency = HlQueryTimeCounterFrequency();
  6487. while (TRUE) {
  6488. if (Timeout == 0) {
  6489. WaitTime = 0;
  6490. } else if (Timeout != WAIT_TIME_INDEFINITE) {
  6491. CurrentTime = KeGetRecentTimeCounter();
  6492. WaitTime = (EndTime - CurrentTime) * MILLISECONDS_PER_SECOND /
  6493. TimeCounterFrequency;
  6494. } else {
  6495. WaitTime = WAIT_TIME_INDEFINITE;
  6496. }
  6497. Status = IoWaitForIoObjectState(IoState,
  6498. POLL_EVENT_IN_HIGH_PRIORITY,
  6499. TRUE,
  6500. WaitTime,
  6501. &ReturnedEvents);
  6502. if (!KSUCCESS(Status)) {
  6503. goto TcpReceiveOutOfBandDataEnd;
  6504. }
  6505. if ((ReturnedEvents & POLL_ERROR_EVENTS) != 0) {
  6506. if ((ReturnedEvents & POLL_EVENT_DISCONNECTED) != 0) {
  6507. Status = STATUS_NO_NETWORK_CONNECTION;
  6508. } else {
  6509. Status = NET_SOCKET_GET_LAST_ERROR(&(TcpSocket->NetSocket));
  6510. if (KSUCCESS(Status)) {
  6511. Status = STATUS_DEVICE_IO_ERROR;
  6512. }
  6513. }
  6514. goto TcpReceiveOutOfBandDataEnd;
  6515. }
  6516. KeAcquireQueuedLock(TcpSocket->Lock);
  6517. LockHeld = TRUE;
  6518. if ((TcpSocket->ShutdownTypes & SOCKET_SHUTDOWN_READ) != 0) {
  6519. Status = STATUS_END_OF_FILE;
  6520. goto TcpReceiveOutOfBandDataEnd;
  6521. }
  6522. if (TcpSocket->OutOfBandData != -1) {
  6523. Status = MmCopyIoBufferData(IoBuffer,
  6524. &(TcpSocket->OutOfBandData),
  6525. BytesComplete,
  6526. 1,
  6527. TRUE);
  6528. if (!KSUCCESS(Status)) {
  6529. goto TcpReceiveOutOfBandDataEnd;
  6530. }
  6531. TcpSocket->OutOfBandData = -1;
  6532. IoSetIoObjectState(IoState, POLL_EVENT_IN_HIGH_PRIORITY, FALSE);
  6533. BytesComplete = 1;
  6534. Parameters->SocketIoFlags |= SOCKET_IO_OUT_OF_BAND;
  6535. Status = STATUS_SUCCESS;
  6536. break;
  6537. //
  6538. // There seemed to be no out of band data ready.
  6539. //
  6540. } else {
  6541. //
  6542. // Watch out for the socket closing down.
  6543. //
  6544. if (TcpSocket->State != TcpStateEstablished) {
  6545. ASSERT(TcpSocket->State > TcpStateEstablished);
  6546. //
  6547. // A reset connection fails as soon as it's known.
  6548. //
  6549. if ((TcpSocket->Flags &
  6550. TCP_SOCKET_FLAG_CONNECTION_RESET) != 0) {
  6551. Status = STATUS_CONNECTION_RESET;
  6552. //
  6553. // Otherwise, the request was not at all satisfied, and no more
  6554. // data is coming in.
  6555. //
  6556. } else {
  6557. Status = STATUS_END_OF_FILE;
  6558. }
  6559. goto TcpReceiveOutOfBandDataEnd;
  6560. }
  6561. }
  6562. KeReleaseQueuedLock(TcpSocket->Lock);
  6563. LockHeld = FALSE;
  6564. }
  6565. TcpReceiveOutOfBandDataEnd:
  6566. if (LockHeld != FALSE) {
  6567. KeReleaseQueuedLock(TcpSocket->Lock);
  6568. }
  6569. Parameters->Size = BytesComplete;
  6570. return Status;
  6571. }
  6572. PTCP_SEGMENT_HEADER
  6573. NetpTcpAllocateSegment (
  6574. PTCP_SOCKET Socket,
  6575. ULONG AllocationSize
  6576. )
  6577. /*++
  6578. Routine Description:
  6579. This routine allocates a TCP segment structure and appended buffer that can
  6580. be used to send or receive data.
  6581. Arguments:
  6582. Socket - Supplies a pointer to the TCP socket requesting the segment.
  6583. AllocationSize - Supplies the minimum size of the allocation.
  6584. Return Value:
  6585. Returns a pointer to the allocated segment on success or NULL on failure.
  6586. --*/
  6587. {
  6588. PTCP_SEGMENT_HEADER NewSegment;
  6589. ULONG ReceiveSize;
  6590. ULONG SendSize;
  6591. ASSERT(KeIsQueuedLockHeld(Socket->Lock) != FALSE);
  6592. //
  6593. // If the list of free, reusable segments is empty, then allocate a new
  6594. // segment. Ignore the requested allocation size and just make it as big
  6595. // as the maximum segment, making future reuse possible.
  6596. //
  6597. if (LIST_EMPTY(&(Socket->FreeSegmentList)) != FALSE) {
  6598. //
  6599. // Determine the segment allocation size if it has not already been
  6600. // determined.
  6601. //
  6602. if (Socket->SegmentAllocationSize == 0) {
  6603. ReceiveSize = Socket->ReceiveMaxSegmentSize +
  6604. sizeof(TCP_RECEIVED_SEGMENT);
  6605. SendSize = Socket->SendMaxSegmentSize + sizeof(TCP_SEND_SEGMENT);
  6606. if (ReceiveSize > SendSize) {
  6607. Socket->SegmentAllocationSize = ReceiveSize;
  6608. } else {
  6609. Socket->SegmentAllocationSize = SendSize;
  6610. }
  6611. }
  6612. NewSegment = MmAllocatePagedPool(Socket->SegmentAllocationSize,
  6613. TCP_ALLOCATION_TAG);
  6614. //
  6615. // Otherwise grab the first segment off the list. Temporarily treating it
  6616. // as a received segment.
  6617. //
  6618. } else {
  6619. NewSegment = LIST_VALUE(Socket->FreeSegmentList.Next,
  6620. TCP_SEGMENT_HEADER,
  6621. ListEntry);
  6622. LIST_REMOVE(&(NewSegment->ListEntry));
  6623. }
  6624. ASSERT(AllocationSize <= Socket->SegmentAllocationSize);
  6625. return NewSegment;
  6626. }
  6627. VOID
  6628. NetpTcpFreeSegment (
  6629. PTCP_SOCKET Socket,
  6630. PTCP_SEGMENT_HEADER Segment
  6631. )
  6632. /*++
  6633. Routine Description:
  6634. This routine releases a TCP segment by making it available for reuse by
  6635. future incoming and outgoing packets.
  6636. Arguments:
  6637. Socket - Supplies a pointer to the TCP socket that owns the segment.
  6638. Segment - Supplies a pointer to the segment to be released.
  6639. Return Value:
  6640. None.
  6641. --*/
  6642. {
  6643. ASSERT(KeIsQueuedLockHeld(Socket->Lock) != FALSE);
  6644. //
  6645. // Just add it to the list of free segments. The socket should never
  6646. // allocate more segments than can fit in the send and receive windows. It
  6647. // shouldn't get out of hand. Put it at the beginning so it stays hot and
  6648. // is reused next.
  6649. //
  6650. INSERT_AFTER(&(Segment->ListEntry), &(Socket->FreeSegmentList));
  6651. return;
  6652. }