sctp_usrreq.c 253 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075
  1. /*-
  2. * SPDX-License-Identifier: BSD-3-Clause
  3. *
  4. * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
  5. * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
  6. * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. *
  11. * a) Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * b) Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the distribution.
  17. *
  18. * c) Neither the name of Cisco Systems, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  24. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #if defined(__FreeBSD__) && !defined(__Userspace__)
  35. #include <sys/cdefs.h>
  36. __FBSDID("$FreeBSD$");
  37. #endif
  38. #include <netinet/sctp_os.h>
  39. #if defined(__FreeBSD__) && !defined(__Userspace__)
  40. #include <sys/proc.h>
  41. #endif
  42. #include <netinet/sctp_pcb.h>
  43. #include <netinet/sctp_header.h>
  44. #include <netinet/sctp_var.h>
  45. #ifdef INET6
  46. #include <netinet6/sctp6_var.h>
  47. #endif
  48. #include <netinet/sctp_sysctl.h>
  49. #include <netinet/sctp_output.h>
  50. #include <netinet/sctp_uio.h>
  51. #include <netinet/sctp_asconf.h>
  52. #include <netinet/sctputil.h>
  53. #include <netinet/sctp_indata.h>
  54. #include <netinet/sctp_timer.h>
  55. #include <netinet/sctp_auth.h>
  56. #include <netinet/sctp_bsd_addr.h>
  57. #if defined(__Userspace__)
  58. #include <netinet/sctp_callout.h>
  59. #else
  60. #include <netinet/udp.h>
  61. #endif
  62. #if defined(__FreeBSD__) && !defined(__Userspace__)
  63. #include <sys/eventhandler.h>
  64. #endif
  65. #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
  66. #include <netinet/sctp_peeloff.h>
  67. #endif /* HAVE_SCTP_PEELOFF_SOCKOPT */
  68. extern const struct sctp_cc_functions sctp_cc_functions[];
  69. extern const struct sctp_ss_functions sctp_ss_functions[];
  70. #if defined(__Userspace__)
  71. void
  72. sctp_init(uint16_t port,
  73. int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
  74. void (*debug_printf)(const char *format, ...), int start_threads)
  75. #elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
  76. void
  77. sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
  78. #elif defined(__FreeBSD__)
  79. static void
  80. sctp_init(void *arg SCTP_UNUSED)
  81. #else
  82. void
  83. sctp_init(void)
  84. #endif
  85. {
  86. #if !defined(__Userspace__)
  87. u_long sb_max_adj;
  88. #else
  89. init_random();
  90. #endif
  91. /* Initialize and modify the sysctled variables */
  92. sctp_init_sysctls();
  93. #if defined(__Userspace__)
  94. SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = port;
  95. #else
  96. #if defined(__APPLE__) && !defined(__Userspace__)
  97. sb_max_adj = (u_long)((u_quad_t) (sb_max) * MCLBYTES / (MSIZE + MCLBYTES));
  98. SCTP_BASE_SYSCTL(sctp_sendspace) = sb_max_adj;
  99. #else
  100. if ((nmbclusters / 8) > SCTP_ASOC_MAX_CHUNKS_ON_QUEUE)
  101. SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = (nmbclusters / 8);
  102. /*
  103. * Allow a user to take no more than 1/2 the number of clusters or
  104. * the SB_MAX, whichever is smaller, for the send window.
  105. */
  106. sb_max_adj = (u_long)((u_quad_t) (SB_MAX) * MCLBYTES / (MSIZE + MCLBYTES));
  107. SCTP_BASE_SYSCTL(sctp_sendspace) = min(sb_max_adj,
  108. (((uint32_t)nmbclusters / 2) * MCLBYTES));
  109. #endif
  110. /*
  111. * Now for the recv window, should we take the same amount? or
  112. * should I do 1/2 the SB_MAX instead in the SB_MAX min above. For
  113. * now I will just copy.
  114. */
  115. SCTP_BASE_SYSCTL(sctp_recvspace) = SCTP_BASE_SYSCTL(sctp_sendspace);
  116. #endif
  117. SCTP_BASE_VAR(first_time) = 0;
  118. SCTP_BASE_VAR(sctp_pcb_initialized) = 0;
  119. #if defined(__Userspace__)
  120. #if !defined(_WIN32)
  121. #if defined(INET) || defined(INET6)
  122. SCTP_BASE_VAR(userspace_route) = -1;
  123. #endif
  124. #endif
  125. #ifdef INET
  126. SCTP_BASE_VAR(userspace_rawsctp) = -1;
  127. SCTP_BASE_VAR(userspace_udpsctp) = -1;
  128. #endif
  129. #ifdef INET6
  130. SCTP_BASE_VAR(userspace_rawsctp6) = -1;
  131. SCTP_BASE_VAR(userspace_udpsctp6) = -1;
  132. #endif
  133. SCTP_BASE_VAR(timer_thread_should_exit) = 0;
  134. SCTP_BASE_VAR(conn_output) = conn_output;
  135. SCTP_BASE_VAR(debug_printf) = debug_printf;
  136. SCTP_BASE_VAR(crc32c_offloaded) = 0;
  137. SCTP_BASE_VAR(iterator_thread_started) = 0;
  138. SCTP_BASE_VAR(timer_thread_started) = 0;
  139. #endif
  140. #if defined(__Userspace__)
  141. sctp_pcb_init(start_threads);
  142. if (start_threads) {
  143. sctp_start_timer_thread();
  144. }
  145. #else
  146. sctp_pcb_init();
  147. #endif
  148. #if defined(SCTP_PACKET_LOGGING)
  149. SCTP_BASE_VAR(packet_log_writers) = 0;
  150. SCTP_BASE_VAR(packet_log_end) = 0;
  151. memset(&SCTP_BASE_VAR(packet_log_buffer), 0, SCTP_PACKET_LOG_SIZE);
  152. #endif
  153. #if defined(__APPLE__) && !defined(__Userspace__)
  154. SCTP_BASE_VAR(sctp_main_timer_ticks) = 0;
  155. sctp_start_main_timer();
  156. timeout(sctp_delayed_startup, NULL, 1);
  157. #endif
  158. #if defined(__FreeBSD__) && !defined(__Userspace__)
  159. SCTP_BASE_VAR(eh_tag) = EVENTHANDLER_REGISTER(rt_addrmsg,
  160. sctp_addr_change_event_handler, NULL, EVENTHANDLER_PRI_FIRST);
  161. #endif
  162. }
  163. #if defined(__FreeBSD__) && !defined(__Userspace__)
  164. VNET_SYSINIT(sctp_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, sctp_init, NULL);
  165. #ifdef VIMAGE
  166. static void
  167. sctp_finish(void *unused __unused)
  168. {
  169. EVENTHANDLER_DEREGISTER(rt_addrmsg, SCTP_BASE_VAR(eh_tag));
  170. sctp_pcb_finish();
  171. }
  172. VNET_SYSUNINIT(sctp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, sctp_finish, NULL);
  173. #endif
  174. #else
  175. void
  176. sctp_finish(void)
  177. {
  178. #if defined(__APPLE__) && !defined(__Userspace__)
  179. untimeout(sctp_delayed_startup, NULL);
  180. sctp_over_udp_stop();
  181. sctp_address_monitor_stop();
  182. sctp_stop_main_timer();
  183. #endif
  184. #if defined(__Userspace__)
  185. #if defined(INET) || defined(INET6)
  186. recv_thread_destroy();
  187. #endif
  188. sctp_stop_timer_thread();
  189. #endif
  190. sctp_pcb_finish();
  191. #if defined(_WIN32) && !defined(__Userspace__)
  192. sctp_finish_sysctls();
  193. #endif
  194. #if defined(__Userspace__)
  195. finish_random();
  196. #endif
  197. }
  198. #endif
  199. void
  200. sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint32_t mtu, bool resend)
  201. {
  202. struct sctp_association *asoc;
  203. struct sctp_tmit_chunk *chk;
  204. uint32_t overhead;
  205. asoc = &stcb->asoc;
  206. KASSERT(mtu < asoc->smallest_mtu,
  207. ("Currently only reducing association MTU %u supported (MTU %u)",
  208. asoc->smallest_mtu, mtu));
  209. asoc->smallest_mtu = mtu;
  210. if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  211. overhead = SCTP_MIN_OVERHEAD;
  212. } else {
  213. #if defined(__Userspace__)
  214. if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
  215. overhead = sizeof(struct sctphdr);
  216. } else {
  217. overhead = SCTP_MIN_V4_OVERHEAD;
  218. }
  219. #else
  220. overhead = SCTP_MIN_V4_OVERHEAD;
  221. #endif
  222. }
  223. if (asoc->idata_supported) {
  224. if (sctp_auth_is_required_chunk(SCTP_IDATA, asoc->peer_auth_chunks)) {
  225. overhead += sctp_get_auth_chunk_len(asoc->peer_hmac_id);
  226. }
  227. } else {
  228. if (sctp_auth_is_required_chunk(SCTP_DATA, asoc->peer_auth_chunks)) {
  229. overhead += sctp_get_auth_chunk_len(asoc->peer_hmac_id);
  230. }
  231. }
  232. KASSERT(overhead % 4 == 0,
  233. ("overhead (%u) not a multiple of 4", overhead));
  234. TAILQ_FOREACH(chk, &asoc->send_queue, sctp_next) {
  235. if (((uint32_t)chk->send_size + overhead) > mtu) {
  236. chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
  237. }
  238. }
  239. TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
  240. if (((uint32_t)chk->send_size + overhead) > mtu) {
  241. chk->flags |= CHUNK_FLAGS_FRAGMENT_OK;
  242. if (resend && chk->sent < SCTP_DATAGRAM_RESEND) {
  243. /*
  244. * If requested, mark the chunk for immediate
  245. * resend, since we sent it being too big.
  246. */
  247. sctp_flight_size_decrease(chk);
  248. sctp_total_flight_decrease(stcb, chk);
  249. chk->sent = SCTP_DATAGRAM_RESEND;
  250. sctp_ucount_incr(asoc->sent_queue_retran_cnt);
  251. chk->rec.data.doing_fast_retransmit = 0;
  252. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
  253. sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_PMTU,
  254. chk->whoTo->flight_size,
  255. chk->book_size,
  256. (uint32_t)(uintptr_t)chk->whoTo,
  257. chk->rec.data.tsn);
  258. }
  259. /* Clear any time, so NO RTT is being done. */
  260. if (chk->do_rtt == 1) {
  261. chk->do_rtt = 0;
  262. chk->whoTo->rto_needed = 1;
  263. }
  264. }
  265. }
  266. }
  267. }
  268. #ifdef INET
  269. #if !defined(__Userspace__)
  270. void
  271. sctp_notify(struct sctp_inpcb *inp,
  272. struct sctp_tcb *stcb,
  273. struct sctp_nets *net,
  274. uint8_t icmp_type,
  275. uint8_t icmp_code,
  276. uint16_t ip_len,
  277. uint32_t next_mtu)
  278. {
  279. #if defined(__APPLE__) && !defined(__Userspace__)
  280. struct socket *so;
  281. #endif
  282. int timer_stopped;
  283. if (icmp_type != ICMP_UNREACH) {
  284. /* We only care about unreachable */
  285. SCTP_TCB_UNLOCK(stcb);
  286. return;
  287. }
  288. if ((icmp_code == ICMP_UNREACH_NET) ||
  289. (icmp_code == ICMP_UNREACH_HOST) ||
  290. (icmp_code == ICMP_UNREACH_NET_UNKNOWN) ||
  291. (icmp_code == ICMP_UNREACH_HOST_UNKNOWN) ||
  292. (icmp_code == ICMP_UNREACH_ISOLATED) ||
  293. (icmp_code == ICMP_UNREACH_NET_PROHIB) ||
  294. (icmp_code == ICMP_UNREACH_HOST_PROHIB) ||
  295. #if defined(__NetBSD__)
  296. (icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
  297. #else
  298. (icmp_code == ICMP_UNREACH_FILTER_PROHIB)) {
  299. #endif
  300. /* Mark the net unreachable. */
  301. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  302. /* OK, that destination is NOT reachable. */
  303. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  304. net->dest_state &= ~SCTP_ADDR_PF;
  305. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
  306. stcb, 0,
  307. (void *)net, SCTP_SO_NOT_LOCKED);
  308. }
  309. SCTP_TCB_UNLOCK(stcb);
  310. } else if ((icmp_code == ICMP_UNREACH_PROTOCOL) ||
  311. (icmp_code == ICMP_UNREACH_PORT)) {
  312. /* Treat it like an ABORT. */
  313. sctp_abort_notification(stcb, true, false, 0, NULL, SCTP_SO_NOT_LOCKED);
  314. #if defined(__APPLE__) && !defined(__Userspace__)
  315. so = SCTP_INP_SO(inp);
  316. atomic_add_int(&stcb->asoc.refcnt, 1);
  317. SCTP_TCB_UNLOCK(stcb);
  318. SCTP_SOCKET_LOCK(so, 1);
  319. SCTP_TCB_LOCK(stcb);
  320. atomic_subtract_int(&stcb->asoc.refcnt, 1);
  321. #endif
  322. (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  323. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
  324. #if defined(__APPLE__) && !defined(__Userspace__)
  325. SCTP_SOCKET_UNLOCK(so, 1);
  326. /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/
  327. #endif
  328. /* no need to unlock here, since the TCB is gone */
  329. } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) {
  330. if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
  331. SCTP_TCB_UNLOCK(stcb);
  332. return;
  333. }
  334. /* Find the next (smaller) MTU */
  335. if (next_mtu == 0) {
  336. /*
  337. * Old type router that does not tell us what the next
  338. * MTU is.
  339. * Rats we will have to guess (in a educated fashion
  340. * of course).
  341. */
  342. next_mtu = sctp_get_prev_mtu(ip_len);
  343. }
  344. /* Stop the PMTU timer. */
  345. if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  346. timer_stopped = 1;
  347. sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
  348. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
  349. } else {
  350. timer_stopped = 0;
  351. }
  352. /* Update the path MTU. */
  353. if (net->port) {
  354. next_mtu -= sizeof(struct udphdr);
  355. }
  356. if (net->mtu > next_mtu) {
  357. net->mtu = next_mtu;
  358. #if defined(__FreeBSD__) && !defined(__Userspace__)
  359. if (net->port) {
  360. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu + sizeof(struct udphdr));
  361. } else {
  362. sctp_hc_set_mtu(&net->ro._l_addr, inp->fibnum, next_mtu);
  363. }
  364. #endif
  365. }
  366. /* Update the association MTU */
  367. if (stcb->asoc.smallest_mtu > next_mtu) {
  368. sctp_pathmtu_adjustment(stcb, next_mtu, true);
  369. }
  370. /* Finally, start the PMTU timer if it was running before. */
  371. if (timer_stopped) {
  372. sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
  373. }
  374. SCTP_TCB_UNLOCK(stcb);
  375. } else {
  376. SCTP_TCB_UNLOCK(stcb);
  377. }
  378. }
  379. #endif
  380. #if !defined(__Userspace__)
  381. void
  382. #if defined(__APPLE__) && !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION) && !defined(APPLE_ELCAPITAN)
  383. sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip, struct ifnet *ifp SCTP_UNUSED)
  384. #else
  385. sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
  386. #endif
  387. {
  388. #if defined(__FreeBSD__) && !defined(__Userspace__)
  389. struct ip *outer_ip;
  390. #endif
  391. struct ip *inner_ip;
  392. struct sctphdr *sh;
  393. struct icmp *icmp;
  394. struct sctp_inpcb *inp;
  395. struct sctp_tcb *stcb;
  396. struct sctp_nets *net;
  397. #if defined(__FreeBSD__) && !defined(__Userspace__)
  398. struct sctp_init_chunk *ch;
  399. #endif
  400. struct sockaddr_in src, dst;
  401. if (sa->sa_family != AF_INET ||
  402. ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
  403. return;
  404. }
  405. if (PRC_IS_REDIRECT(cmd)) {
  406. vip = NULL;
  407. } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
  408. return;
  409. }
  410. if (vip != NULL) {
  411. inner_ip = (struct ip *)vip;
  412. icmp = (struct icmp *)((caddr_t)inner_ip -
  413. (sizeof(struct icmp) - sizeof(struct ip)));
  414. #if defined(__FreeBSD__) && !defined(__Userspace__)
  415. outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
  416. #endif
  417. sh = (struct sctphdr *)((caddr_t)inner_ip + (inner_ip->ip_hl << 2));
  418. memset(&src, 0, sizeof(struct sockaddr_in));
  419. src.sin_family = AF_INET;
  420. #ifdef HAVE_SIN_LEN
  421. src.sin_len = sizeof(struct sockaddr_in);
  422. #endif
  423. src.sin_port = sh->src_port;
  424. src.sin_addr = inner_ip->ip_src;
  425. memset(&dst, 0, sizeof(struct sockaddr_in));
  426. dst.sin_family = AF_INET;
  427. #ifdef HAVE_SIN_LEN
  428. dst.sin_len = sizeof(struct sockaddr_in);
  429. #endif
  430. dst.sin_port = sh->dest_port;
  431. dst.sin_addr = inner_ip->ip_dst;
  432. /*
  433. * 'dst' holds the dest of the packet that failed to be sent.
  434. * 'src' holds our local endpoint address. Thus we reverse
  435. * the dst and the src in the lookup.
  436. */
  437. inp = NULL;
  438. net = NULL;
  439. stcb = sctp_findassociation_addr_sa((struct sockaddr *)&dst,
  440. (struct sockaddr *)&src,
  441. &inp, &net, 1,
  442. SCTP_DEFAULT_VRFID);
  443. if ((stcb != NULL) &&
  444. (net != NULL) &&
  445. (inp != NULL)) {
  446. /* Check the verification tag */
  447. if (ntohl(sh->v_tag) != 0) {
  448. /*
  449. * This must be the verification tag used for
  450. * sending out packets. We don't consider
  451. * packets reflecting the verification tag.
  452. */
  453. if (ntohl(sh->v_tag) != stcb->asoc.peer_vtag) {
  454. SCTP_TCB_UNLOCK(stcb);
  455. return;
  456. }
  457. } else {
  458. #if defined(__FreeBSD__) && !defined(__Userspace__)
  459. if (ntohs(outer_ip->ip_len) >=
  460. sizeof(struct ip) +
  461. 8 + (inner_ip->ip_hl << 2) + 20) {
  462. /*
  463. * In this case we can check if we
  464. * got an INIT chunk and if the
  465. * initiate tag matches.
  466. */
  467. ch = (struct sctp_init_chunk *)(sh + 1);
  468. if ((ch->ch.chunk_type != SCTP_INITIATION) ||
  469. (ntohl(ch->init.initiate_tag) != stcb->asoc.my_vtag)) {
  470. SCTP_TCB_UNLOCK(stcb);
  471. return;
  472. }
  473. } else {
  474. SCTP_TCB_UNLOCK(stcb);
  475. return;
  476. }
  477. #else
  478. SCTP_TCB_UNLOCK(stcb);
  479. return;
  480. #endif
  481. }
  482. sctp_notify(inp, stcb, net,
  483. icmp->icmp_type,
  484. icmp->icmp_code,
  485. #if defined(__FreeBSD__) && !defined(__Userspace__)
  486. ntohs(inner_ip->ip_len),
  487. #else
  488. inner_ip->ip_len,
  489. #endif
  490. (uint32_t)ntohs(icmp->icmp_nextmtu));
  491. #if defined(__Userspace__)
  492. if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  493. (stcb->sctp_socket != NULL)) {
  494. struct socket *upcall_socket;
  495. upcall_socket = stcb->sctp_socket;
  496. SOCK_LOCK(upcall_socket);
  497. soref(upcall_socket);
  498. SOCK_UNLOCK(upcall_socket);
  499. if ((upcall_socket->so_upcall != NULL) &&
  500. (upcall_socket->so_error != 0)) {
  501. (*upcall_socket->so_upcall)(upcall_socket, upcall_socket->so_upcallarg, M_NOWAIT);
  502. }
  503. ACCEPT_LOCK();
  504. SOCK_LOCK(upcall_socket);
  505. sorele(upcall_socket);
  506. }
  507. #endif
  508. } else {
  509. if ((stcb == NULL) && (inp != NULL)) {
  510. /* reduce ref-count */
  511. SCTP_INP_WLOCK(inp);
  512. SCTP_INP_DECR_REF(inp);
  513. SCTP_INP_WUNLOCK(inp);
  514. }
  515. if (stcb) {
  516. SCTP_TCB_UNLOCK(stcb);
  517. }
  518. }
  519. }
  520. return;
  521. }
  522. #endif
  523. #endif
  524. #if defined(__FreeBSD__) && !defined(__Userspace__)
  525. static int
  526. sctp_getcred(SYSCTL_HANDLER_ARGS)
  527. {
  528. struct xucred xuc;
  529. struct sockaddr_in addrs[2];
  530. struct sctp_inpcb *inp;
  531. struct sctp_nets *net;
  532. struct sctp_tcb *stcb;
  533. int error;
  534. uint32_t vrf_id;
  535. /* FIX, for non-bsd is this right? */
  536. vrf_id = SCTP_DEFAULT_VRFID;
  537. error = priv_check(req->td, PRIV_NETINET_GETCRED);
  538. if (error)
  539. return (error);
  540. error = SYSCTL_IN(req, addrs, sizeof(addrs));
  541. if (error)
  542. return (error);
  543. stcb = sctp_findassociation_addr_sa(sintosa(&addrs[1]),
  544. sintosa(&addrs[0]),
  545. &inp, &net, 1, vrf_id);
  546. if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
  547. if ((inp != NULL) && (stcb == NULL)) {
  548. /* reduce ref-count */
  549. SCTP_INP_WLOCK(inp);
  550. SCTP_INP_DECR_REF(inp);
  551. goto cred_can_cont;
  552. }
  553. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  554. error = ENOENT;
  555. goto out;
  556. }
  557. SCTP_TCB_UNLOCK(stcb);
  558. /* We use the write lock here, only
  559. * since in the error leg we need it.
  560. * If we used RLOCK, then we would have
  561. * to wlock/decr/unlock/rlock. Which
  562. * in theory could create a hole. Better
  563. * to use higher wlock.
  564. */
  565. SCTP_INP_WLOCK(inp);
  566. cred_can_cont:
  567. error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket);
  568. if (error) {
  569. SCTP_INP_WUNLOCK(inp);
  570. goto out;
  571. }
  572. cru2x(inp->sctp_socket->so_cred, &xuc);
  573. SCTP_INP_WUNLOCK(inp);
  574. error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
  575. out:
  576. return (error);
  577. }
  578. SYSCTL_PROC(_net_inet_sctp, OID_AUTO, getcred,
  579. CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
  580. 0, 0, sctp_getcred, "S,ucred",
  581. "Get the ucred of a SCTP connection");
  582. #endif
  583. #ifdef INET
  584. #if defined(_WIN32) || defined(__Userspace__)
  585. int
  586. #elif defined(__FreeBSD__)
  587. static void
  588. #else
  589. static int
  590. #endif
  591. sctp_abort(struct socket *so)
  592. {
  593. #if defined(__FreeBSD__) && !defined(__Userspace__)
  594. struct epoch_tracker et;
  595. #endif
  596. struct sctp_inpcb *inp;
  597. inp = (struct sctp_inpcb *)so->so_pcb;
  598. if (inp == NULL) {
  599. #if defined(__FreeBSD__) && !defined(__Userspace__)
  600. return;
  601. #else
  602. SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  603. return (EINVAL);
  604. #endif
  605. }
  606. SCTP_INP_WLOCK(inp);
  607. #if defined(__FreeBSD__) && !defined(__Userspace__)
  608. NET_EPOCH_ENTER(et);
  609. #endif
  610. #ifdef SCTP_LOG_CLOSING
  611. sctp_log_closing(inp, NULL, 17);
  612. #endif
  613. if (((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0)) {
  614. inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP;
  615. #ifdef SCTP_LOG_CLOSING
  616. sctp_log_closing(inp, NULL, 16);
  617. #endif
  618. SCTP_INP_WUNLOCK(inp);
  619. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
  620. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  621. SOCK_LOCK(so);
  622. #if defined(__FreeBSD__) && !defined(__Userspace__)
  623. KASSERT(!SOLISTENING(so),
  624. ("sctp_abort: called on listening socket %p", so));
  625. #endif
  626. SCTP_SB_CLEAR(so->so_snd);
  627. SCTP_SB_CLEAR(so->so_rcv);
  628. #if defined(__APPLE__) && !defined(__Userspace__)
  629. so->so_usecount--;
  630. #else
  631. /* Now null out the reference, we are completely detached. */
  632. so->so_pcb = NULL;
  633. #endif
  634. SOCK_UNLOCK(so);
  635. } else {
  636. SCTP_INP_WUNLOCK(inp);
  637. }
  638. #if defined(__FreeBSD__) && !defined(__Userspace__)
  639. NET_EPOCH_EXIT(et);
  640. #else
  641. return (0);
  642. #endif
  643. }
  644. #if defined(__Userspace__)
  645. int
  646. #else
  647. static int
  648. #endif
  649. #if defined(__Userspace__)
  650. sctp_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
  651. #elif defined(__FreeBSD__)
  652. sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED)
  653. #elif defined(_WIN32)
  654. sctp_attach(struct socket *so, int proto SCTP_UNUSED, PKTHREAD p SCTP_UNUSED)
  655. #else
  656. sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSED)
  657. #endif
  658. {
  659. struct sctp_inpcb *inp;
  660. struct inpcb *ip_inp;
  661. int error;
  662. #if !defined(__Userspace__)
  663. uint32_t vrf_id = SCTP_DEFAULT_VRFID;
  664. #endif
  665. inp = (struct sctp_inpcb *)so->so_pcb;
  666. if (inp != NULL) {
  667. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  668. return (EINVAL);
  669. }
  670. if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  671. error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
  672. if (error) {
  673. return (error);
  674. }
  675. }
  676. error = sctp_inpcb_alloc(so, vrf_id);
  677. if (error) {
  678. return (error);
  679. }
  680. inp = (struct sctp_inpcb *)so->so_pcb;
  681. SCTP_INP_WLOCK(inp);
  682. inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6; /* I'm not v6! */
  683. ip_inp = &inp->ip_inp.inp;
  684. ip_inp->inp_vflag |= INP_IPV4;
  685. ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
  686. SCTP_INP_WUNLOCK(inp);
  687. return (0);
  688. }
  689. #if defined(__Userspace__)
  690. int
  691. sctp_bind(struct socket *so, struct sockaddr *addr) {
  692. void *p = NULL;
  693. #elif defined(__FreeBSD__)
  694. static int
  695. sctp_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
  696. {
  697. #elif defined(__APPLE__)
  698. static int
  699. sctp_bind(struct socket *so, struct sockaddr *addr, struct proc *p) {
  700. #elif defined(_WIN32)
  701. static int
  702. sctp_bind(struct socket *so, struct sockaddr *addr, PKTHREAD p) {
  703. #else
  704. static int
  705. sctp_bind(struct socket *so, struct mbuf *nam, struct proc *p)
  706. {
  707. struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL;
  708. #endif
  709. struct sctp_inpcb *inp;
  710. inp = (struct sctp_inpcb *)so->so_pcb;
  711. if (inp == NULL) {
  712. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  713. return (EINVAL);
  714. }
  715. if (addr != NULL) {
  716. #ifdef HAVE_SA_LEN
  717. if ((addr->sa_family != AF_INET) ||
  718. (addr->sa_len != sizeof(struct sockaddr_in))) {
  719. #else
  720. if (addr->sa_family != AF_INET) {
  721. #endif
  722. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  723. return (EINVAL);
  724. }
  725. }
  726. return (sctp_inpcb_bind(so, addr, NULL, p));
  727. }
  728. #endif
  729. #if defined(__Userspace__)
  730. int
  731. sctpconn_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id)
  732. {
  733. struct sctp_inpcb *inp;
  734. struct inpcb *ip_inp;
  735. int error;
  736. inp = (struct sctp_inpcb *)so->so_pcb;
  737. if (inp != NULL) {
  738. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  739. return (EINVAL);
  740. }
  741. if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
  742. error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
  743. if (error) {
  744. return (error);
  745. }
  746. }
  747. error = sctp_inpcb_alloc(so, vrf_id);
  748. if (error) {
  749. return (error);
  750. }
  751. inp = (struct sctp_inpcb *)so->so_pcb;
  752. SCTP_INP_WLOCK(inp);
  753. inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUND_V6;
  754. inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_CONN;
  755. ip_inp = &inp->ip_inp.inp;
  756. ip_inp->inp_vflag |= INP_CONN;
  757. ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
  758. SCTP_INP_WUNLOCK(inp);
  759. return (0);
  760. }
  761. int
  762. sctpconn_bind(struct socket *so, struct sockaddr *addr)
  763. {
  764. struct sctp_inpcb *inp;
  765. inp = (struct sctp_inpcb *)so->so_pcb;
  766. if (inp == NULL) {
  767. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  768. return (EINVAL);
  769. }
  770. if (addr != NULL) {
  771. #ifdef HAVE_SA_LEN
  772. if ((addr->sa_family != AF_CONN) ||
  773. (addr->sa_len != sizeof(struct sockaddr_conn))) {
  774. #else
  775. if (addr->sa_family != AF_CONN) {
  776. #endif
  777. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  778. return (EINVAL);
  779. }
  780. }
  781. return (sctp_inpcb_bind(so, addr, NULL, NULL));
  782. }
  783. #endif
  784. #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
  785. void
  786. sctp_close(struct socket *so)
  787. {
  788. #if defined(__FreeBSD__) && !defined(__Userspace__)
  789. struct epoch_tracker et;
  790. #endif
  791. struct sctp_inpcb *inp;
  792. inp = (struct sctp_inpcb *)so->so_pcb;
  793. if (inp == NULL)
  794. return;
  795. /* Inform all the lower layer assoc that we
  796. * are done.
  797. */
  798. SCTP_INP_WLOCK(inp);
  799. #if defined(__FreeBSD__) && !defined(__Userspace__)
  800. NET_EPOCH_ENTER(et);
  801. #endif
  802. #ifdef SCTP_LOG_CLOSING
  803. sctp_log_closing(inp, NULL, 17);
  804. #endif
  805. if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
  806. inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP;
  807. #if defined(__Userspace__)
  808. if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
  809. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  810. #else
  811. if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
  812. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  813. #endif
  814. #ifdef SCTP_LOG_CLOSING
  815. sctp_log_closing(inp, NULL, 13);
  816. #endif
  817. SCTP_INP_WUNLOCK(inp);
  818. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
  819. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  820. } else {
  821. #ifdef SCTP_LOG_CLOSING
  822. sctp_log_closing(inp, NULL, 14);
  823. #endif
  824. SCTP_INP_WUNLOCK(inp);
  825. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
  826. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  827. }
  828. /* The socket is now detached, no matter what
  829. * the state of the SCTP association.
  830. */
  831. SOCK_LOCK(so);
  832. #if defined(__FreeBSD__) && !defined(__Userspace__)
  833. if (!SOLISTENING(so)) {
  834. SCTP_SB_CLEAR(so->so_snd);
  835. SCTP_SB_CLEAR(so->so_rcv);
  836. }
  837. #else
  838. SCTP_SB_CLEAR(so->so_snd);
  839. SCTP_SB_CLEAR(so->so_rcv);
  840. #endif
  841. #if !(defined(__APPLE__) && !defined(__Userspace__))
  842. /* Now null out the reference, we are completely detached. */
  843. so->so_pcb = NULL;
  844. #endif
  845. SOCK_UNLOCK(so);
  846. } else {
  847. SCTP_INP_WUNLOCK(inp);
  848. }
  849. #if defined(__FreeBSD__) && !defined(__Userspace__)
  850. NET_EPOCH_EXIT(et);
  851. #endif
  852. }
  853. #else
  854. int
  855. sctp_detach(struct socket *so)
  856. {
  857. struct sctp_inpcb *inp;
  858. uint32_t flags;
  859. inp = (struct sctp_inpcb *)so->so_pcb;
  860. if (inp == NULL) {
  861. #if defined(__FreeBSD__) && !defined(__Userspace__)
  862. return;
  863. #else
  864. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  865. return (EINVAL);
  866. #endif
  867. }
  868. sctp_must_try_again:
  869. flags = inp->sctp_flags;
  870. #ifdef SCTP_LOG_CLOSING
  871. sctp_log_closing(inp, NULL, 17);
  872. #endif
  873. if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  874. (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
  875. #if defined(__Userspace__)
  876. if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
  877. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  878. #else
  879. if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
  880. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  881. #endif
  882. #ifdef SCTP_LOG_CLOSING
  883. sctp_log_closing(inp, NULL, 13);
  884. #endif
  885. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
  886. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  887. } else {
  888. #ifdef SCTP_LOG_CLOSING
  889. sctp_log_closing(inp, NULL, 13);
  890. #endif
  891. sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_GRACEFUL_CLOSE,
  892. SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
  893. }
  894. /* The socket is now detached, no matter what
  895. * the state of the SCTP association.
  896. */
  897. SCTP_SB_CLEAR(so->so_snd);
  898. /* same for the rcv ones, they are only
  899. * here for the accounting/select.
  900. */
  901. SCTP_SB_CLEAR(so->so_rcv);
  902. #if !(defined(__APPLE__) && !defined(__Userspace__))
  903. /* Now disconnect */
  904. so->so_pcb = NULL;
  905. #endif
  906. } else {
  907. flags = inp->sctp_flags;
  908. if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
  909. goto sctp_must_try_again;
  910. }
  911. }
  912. #if defined(__FreeBSD__) && !defined(__Userspace__)
  913. return;
  914. #else
  915. return (0);
  916. #endif
  917. }
  918. #endif
  919. #if defined(__Userspace__)
  920. /* __Userspace__ is not calling sctp_sendm */
  921. #endif
  922. #if !(defined(_WIN32) && !defined(__Userspace__))
  923. int
  924. #if defined(__FreeBSD__) && !defined(__Userspace__)
  925. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  926. struct mbuf *control, struct thread *p);
  927. #else
  928. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  929. struct mbuf *control, struct proc *p);
  930. #endif
  931. int
  932. #if defined(__FreeBSD__) && !defined(__Userspace__)
  933. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  934. struct mbuf *control, struct thread *p)
  935. {
  936. #else
  937. sctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  938. struct mbuf *control, struct proc *p)
  939. {
  940. #endif
  941. struct sctp_inpcb *inp;
  942. int error;
  943. inp = (struct sctp_inpcb *)so->so_pcb;
  944. if (inp == NULL) {
  945. if (control) {
  946. sctp_m_freem(control);
  947. control = NULL;
  948. }
  949. SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  950. sctp_m_freem(m);
  951. return (EINVAL);
  952. }
  953. /* Got to have an to address if we are NOT a connected socket */
  954. if ((addr == NULL) &&
  955. ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) ||
  956. (inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE))) {
  957. goto connected_type;
  958. }
  959. error = 0;
  960. if (addr == NULL) {
  961. SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EDESTADDRREQ);
  962. error = EDESTADDRREQ;
  963. } else if (addr->sa_family != AF_INET) {
  964. SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  965. error = EAFNOSUPPORT;
  966. #if defined(HAVE_SA_LEN)
  967. } else if (addr->sa_len != sizeof(struct sockaddr_in)) {
  968. SCTP_LTRACE_ERR_RET_PKT(m, inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  969. error = EINVAL;
  970. #endif
  971. }
  972. if (error != 0) {
  973. sctp_m_freem(m);
  974. if (control) {
  975. sctp_m_freem(control);
  976. control = NULL;
  977. }
  978. return (error);
  979. }
  980. connected_type:
  981. /* now what about control */
  982. if (control) {
  983. if (inp->control) {
  984. sctp_m_freem(inp->control);
  985. inp->control = NULL;
  986. }
  987. inp->control = control;
  988. }
  989. /* Place the data */
  990. if (inp->pkt) {
  991. SCTP_BUF_NEXT(inp->pkt_last) = m;
  992. inp->pkt_last = m;
  993. } else {
  994. inp->pkt_last = inp->pkt = m;
  995. }
  996. if (
  997. #if (defined(__FreeBSD__) || defined(__APPLE__)) && !defined(__Userspace__)
  998. /* FreeBSD uses a flag passed */
  999. ((flags & PRUS_MORETOCOME) == 0)
  1000. #else
  1001. 1 /* Open BSD does not have any "more to come"
  1002. * indication */
  1003. #endif
  1004. ) {
  1005. /*
  1006. * note with the current version this code will only be used
  1007. * by OpenBSD-- NetBSD, FreeBSD, and MacOS have methods for
  1008. * re-defining sosend to use the sctp_sosend. One can
  1009. * optionally switch back to this code (by changing back the
  1010. * definitions) but this is not advisable. This code is used
  1011. * by FreeBSD when sending a file with sendfile() though.
  1012. */
  1013. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1014. struct epoch_tracker et;
  1015. #endif
  1016. int ret;
  1017. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1018. NET_EPOCH_ENTER(et);
  1019. #endif
  1020. ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags);
  1021. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1022. NET_EPOCH_EXIT(et);
  1023. #endif
  1024. inp->pkt = NULL;
  1025. inp->control = NULL;
  1026. return (ret);
  1027. } else {
  1028. return (0);
  1029. }
  1030. }
  1031. #endif
  1032. int
  1033. sctp_disconnect(struct socket *so)
  1034. {
  1035. struct sctp_inpcb *inp;
  1036. inp = (struct sctp_inpcb *)so->so_pcb;
  1037. if (inp == NULL) {
  1038. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
  1039. return (ENOTCONN);
  1040. }
  1041. SCTP_INP_RLOCK(inp);
  1042. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  1043. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
  1044. if (LIST_EMPTY(&inp->sctp_asoc_list)) {
  1045. /* No connection */
  1046. SCTP_INP_RUNLOCK(inp);
  1047. return (0);
  1048. } else {
  1049. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1050. struct epoch_tracker et;
  1051. #endif
  1052. struct sctp_association *asoc;
  1053. struct sctp_tcb *stcb;
  1054. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1055. if (stcb == NULL) {
  1056. SCTP_INP_RUNLOCK(inp);
  1057. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  1058. return (EINVAL);
  1059. }
  1060. SCTP_TCB_LOCK(stcb);
  1061. asoc = &stcb->asoc;
  1062. if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
  1063. /* We are about to be freed, out of here */
  1064. SCTP_TCB_UNLOCK(stcb);
  1065. SCTP_INP_RUNLOCK(inp);
  1066. return (0);
  1067. }
  1068. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1069. NET_EPOCH_ENTER(et);
  1070. #endif
  1071. #if defined(__Userspace__)
  1072. if (((so->so_options & SCTP_SO_LINGER) && (so->so_linger == 0)) ||
  1073. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  1074. #else
  1075. if (((so->so_options & SO_LINGER) && (so->so_linger == 0)) ||
  1076. (SCTP_SBAVAIL(&so->so_rcv) > 0)) {
  1077. #endif
  1078. if (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) {
  1079. /* Left with Data unread */
  1080. struct mbuf *op_err;
  1081. op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
  1082. sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
  1083. SCTP_STAT_INCR_COUNTER32(sctps_aborted);
  1084. }
  1085. SCTP_INP_RUNLOCK(inp);
  1086. if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
  1087. (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
  1088. SCTP_STAT_DECR_GAUGE32(sctps_currestab);
  1089. }
  1090. (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  1091. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
  1092. /* No unlock tcb assoc is gone */
  1093. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1094. NET_EPOCH_EXIT(et);
  1095. #endif
  1096. return (0);
  1097. }
  1098. if (TAILQ_EMPTY(&asoc->send_queue) &&
  1099. TAILQ_EMPTY(&asoc->sent_queue) &&
  1100. (asoc->stream_queue_cnt == 0)) {
  1101. /* there is nothing queued to send, so done */
  1102. if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
  1103. goto abort_anyway;
  1104. }
  1105. if ((SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT) &&
  1106. (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
  1107. /* only send SHUTDOWN 1st time thru */
  1108. struct sctp_nets *netp;
  1109. if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
  1110. (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
  1111. SCTP_STAT_DECR_GAUGE32(sctps_currestab);
  1112. }
  1113. SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
  1114. sctp_stop_timers_for_shutdown(stcb);
  1115. if (stcb->asoc.alternate) {
  1116. netp = stcb->asoc.alternate;
  1117. } else {
  1118. netp = stcb->asoc.primary_destination;
  1119. }
  1120. sctp_send_shutdown(stcb,netp);
  1121. sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
  1122. stcb->sctp_ep, stcb, netp);
  1123. sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
  1124. stcb->sctp_ep, stcb, NULL);
  1125. sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
  1126. }
  1127. } else {
  1128. /*
  1129. * we still got (or just got) data to send,
  1130. * so set SHUTDOWN_PENDING
  1131. */
  1132. /*
  1133. * XXX sockets draft says that SCTP_EOF
  1134. * should be sent with no data. currently,
  1135. * we will allow user data to be sent first
  1136. * and move to SHUTDOWN-PENDING
  1137. */
  1138. SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
  1139. sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
  1140. if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
  1141. SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
  1142. }
  1143. if (TAILQ_EMPTY(&asoc->send_queue) &&
  1144. TAILQ_EMPTY(&asoc->sent_queue) &&
  1145. (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
  1146. struct mbuf *op_err;
  1147. abort_anyway:
  1148. op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
  1149. stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4;
  1150. sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
  1151. SCTP_STAT_INCR_COUNTER32(sctps_aborted);
  1152. if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
  1153. (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
  1154. SCTP_STAT_DECR_GAUGE32(sctps_currestab);
  1155. }
  1156. SCTP_INP_RUNLOCK(inp);
  1157. (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  1158. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
  1159. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1160. NET_EPOCH_EXIT(et);
  1161. #endif
  1162. return (0);
  1163. } else {
  1164. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
  1165. }
  1166. }
  1167. soisdisconnecting(so);
  1168. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1169. NET_EPOCH_EXIT(et);
  1170. #endif
  1171. SCTP_TCB_UNLOCK(stcb);
  1172. SCTP_INP_RUNLOCK(inp);
  1173. return (0);
  1174. }
  1175. /* not reached */
  1176. } else {
  1177. /* UDP model does not support this */
  1178. SCTP_INP_RUNLOCK(inp);
  1179. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  1180. return (EOPNOTSUPP);
  1181. }
  1182. }
  1183. #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
  1184. int
  1185. sctp_flush(struct socket *so, int how)
  1186. {
  1187. /*
  1188. * We will just clear out the values and let
  1189. * subsequent close clear out the data, if any.
  1190. * Note if the user did a shutdown(SHUT_RD) they
  1191. * will not be able to read the data, the socket
  1192. * will block that from happening.
  1193. */
  1194. struct sctp_inpcb *inp;
  1195. inp = (struct sctp_inpcb *)so->so_pcb;
  1196. if (inp == NULL) {
  1197. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  1198. return (EINVAL);
  1199. }
  1200. SCTP_INP_RLOCK(inp);
  1201. /* For the 1 to many model this does nothing */
  1202. if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
  1203. SCTP_INP_RUNLOCK(inp);
  1204. return (0);
  1205. }
  1206. SCTP_INP_RUNLOCK(inp);
  1207. if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) {
  1208. /* First make sure the sb will be happy, we don't
  1209. * use these except maybe the count
  1210. */
  1211. SCTP_INP_WLOCK(inp);
  1212. SCTP_INP_READ_LOCK(inp);
  1213. inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ;
  1214. SCTP_INP_READ_UNLOCK(inp);
  1215. SCTP_INP_WUNLOCK(inp);
  1216. SOCK_LOCK(so);
  1217. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1218. KASSERT(!SOLISTENING(so),
  1219. ("sctp_flush: called on listening socket %p", so));
  1220. #endif
  1221. SCTP_SB_CLEAR(so->so_rcv);
  1222. SOCK_UNLOCK(so);
  1223. }
  1224. if ((how == PRU_FLUSH_WR) || (how == PRU_FLUSH_RDWR)) {
  1225. /* First make sure the sb will be happy, we don't
  1226. * use these except maybe the count
  1227. */
  1228. SOCK_LOCK(so);
  1229. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1230. KASSERT(!SOLISTENING(so),
  1231. ("sctp_flush: called on listening socket %p", so));
  1232. #endif
  1233. SCTP_SB_CLEAR(so->so_snd);
  1234. SOCK_UNLOCK(so);
  1235. }
  1236. return (0);
  1237. }
  1238. #endif
  1239. int
  1240. sctp_shutdown(struct socket *so)
  1241. {
  1242. struct sctp_inpcb *inp;
  1243. inp = (struct sctp_inpcb *)so->so_pcb;
  1244. if (inp == NULL) {
  1245. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  1246. return (EINVAL);
  1247. }
  1248. SCTP_INP_RLOCK(inp);
  1249. /* For UDP model this is a invalid call */
  1250. if (!((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  1251. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) {
  1252. /* Restore the flags that the soshutdown took away. */
  1253. #if (defined(__FreeBSD__) || defined(_WIN32)) && !defined(__Userspace__)
  1254. SOCKBUF_LOCK(&so->so_rcv);
  1255. so->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
  1256. SOCKBUF_UNLOCK(&so->so_rcv);
  1257. #else
  1258. SOCK_LOCK(so);
  1259. so->so_state &= ~SS_CANTRCVMORE;
  1260. SOCK_UNLOCK(so);
  1261. #endif
  1262. /* This proc will wakeup for read and do nothing (I hope) */
  1263. SCTP_INP_RUNLOCK(inp);
  1264. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  1265. return (EOPNOTSUPP);
  1266. } else {
  1267. /*
  1268. * Ok, if we reach here its the TCP model and it is either
  1269. * a SHUT_WR or SHUT_RDWR.
  1270. * This means we put the shutdown flag against it.
  1271. */
  1272. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1273. struct epoch_tracker et;
  1274. #endif
  1275. struct sctp_tcb *stcb;
  1276. struct sctp_association *asoc;
  1277. struct sctp_nets *netp;
  1278. if ((so->so_state &
  1279. (SS_ISCONNECTED|SS_ISCONNECTING|SS_ISDISCONNECTING)) == 0) {
  1280. SCTP_INP_RUNLOCK(inp);
  1281. return (ENOTCONN);
  1282. }
  1283. socantsendmore(so);
  1284. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1285. if (stcb == NULL) {
  1286. /*
  1287. * Ok, we hit the case that the shutdown call was
  1288. * made after an abort or something. Nothing to do
  1289. * now.
  1290. */
  1291. SCTP_INP_RUNLOCK(inp);
  1292. return (0);
  1293. }
  1294. SCTP_TCB_LOCK(stcb);
  1295. asoc = &stcb->asoc;
  1296. if (asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) {
  1297. SCTP_TCB_UNLOCK(stcb);
  1298. SCTP_INP_RUNLOCK(inp);
  1299. return (0);
  1300. }
  1301. if ((SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_WAIT) &&
  1302. (SCTP_GET_STATE(stcb) != SCTP_STATE_COOKIE_ECHOED) &&
  1303. (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN)) {
  1304. /* If we are not in or before ESTABLISHED, there is
  1305. * no protocol action required.
  1306. */
  1307. SCTP_TCB_UNLOCK(stcb);
  1308. SCTP_INP_RUNLOCK(inp);
  1309. return (0);
  1310. }
  1311. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1312. NET_EPOCH_ENTER(et);
  1313. #endif
  1314. if (stcb->asoc.alternate) {
  1315. netp = stcb->asoc.alternate;
  1316. } else {
  1317. netp = stcb->asoc.primary_destination;
  1318. }
  1319. if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) &&
  1320. TAILQ_EMPTY(&asoc->send_queue) &&
  1321. TAILQ_EMPTY(&asoc->sent_queue) &&
  1322. (asoc->stream_queue_cnt == 0)) {
  1323. if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
  1324. goto abort_anyway;
  1325. }
  1326. /* there is nothing queued to send, so I'm done... */
  1327. SCTP_STAT_DECR_GAUGE32(sctps_currestab);
  1328. SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT);
  1329. sctp_stop_timers_for_shutdown(stcb);
  1330. sctp_send_shutdown(stcb, netp);
  1331. sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
  1332. stcb->sctp_ep, stcb, netp);
  1333. } else {
  1334. /*
  1335. * We still got (or just got) data to send, so set
  1336. * SHUTDOWN_PENDING.
  1337. */
  1338. SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING);
  1339. if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete)(stcb, asoc)) {
  1340. SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_PARTIAL_MSG_LEFT);
  1341. }
  1342. if (TAILQ_EMPTY(&asoc->send_queue) &&
  1343. TAILQ_EMPTY(&asoc->sent_queue) &&
  1344. (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
  1345. struct mbuf *op_err;
  1346. abort_anyway:
  1347. op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
  1348. stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6;
  1349. SCTP_INP_RUNLOCK(inp);
  1350. sctp_abort_an_association(stcb->sctp_ep, stcb,
  1351. op_err, false, SCTP_SO_LOCKED);
  1352. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1353. NET_EPOCH_EXIT(et);
  1354. #endif
  1355. return (0);
  1356. }
  1357. }
  1358. sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb, NULL);
  1359. /* XXX: Why do this in the case where we have still data queued? */
  1360. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
  1361. SCTP_TCB_UNLOCK(stcb);
  1362. SCTP_INP_RUNLOCK(inp);
  1363. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1364. NET_EPOCH_EXIT(et);
  1365. #endif
  1366. return (0);
  1367. }
  1368. }
  1369. /*
  1370. * copies a "user" presentable address and removes embedded scope, etc.
  1371. * returns 0 on success, 1 on error
  1372. */
  1373. static uint32_t
  1374. sctp_fill_user_address(struct sockaddr *dst, struct sockaddr *src)
  1375. {
  1376. #ifdef INET6
  1377. #if defined(SCTP_EMBEDDED_V6_SCOPE)
  1378. struct sockaddr_in6 lsa6;
  1379. src = (struct sockaddr *)sctp_recover_scope((struct sockaddr_in6 *)src,
  1380. &lsa6);
  1381. #endif
  1382. #endif
  1383. #ifdef HAVE_SA_LEN
  1384. memcpy(dst, src, src->sa_len);
  1385. #else
  1386. switch (src->sa_family) {
  1387. #ifdef INET
  1388. case AF_INET:
  1389. memcpy(dst, src, sizeof(struct sockaddr_in));
  1390. break;
  1391. #endif
  1392. #ifdef INET6
  1393. case AF_INET6:
  1394. memcpy(dst, src, sizeof(struct sockaddr_in6));
  1395. break;
  1396. #endif
  1397. #if defined(__Userspace__)
  1398. case AF_CONN:
  1399. memcpy(dst, src, sizeof(struct sockaddr_conn));
  1400. break;
  1401. #endif
  1402. default:
  1403. /* TSNH */
  1404. break;
  1405. }
  1406. #endif
  1407. return (0);
  1408. }
  1409. static size_t
  1410. sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
  1411. struct sctp_tcb *stcb,
  1412. size_t limit,
  1413. struct sockaddr *addr,
  1414. uint32_t vrf_id)
  1415. {
  1416. struct sctp_ifn *sctp_ifn;
  1417. struct sctp_ifa *sctp_ifa;
  1418. size_t actual;
  1419. int loopback_scope;
  1420. #if defined(INET)
  1421. int ipv4_local_scope, ipv4_addr_legal;
  1422. #endif
  1423. #if defined(INET6)
  1424. int local_scope, site_scope, ipv6_addr_legal;
  1425. #endif
  1426. #if defined(__Userspace__)
  1427. int conn_addr_legal;
  1428. #endif
  1429. struct sctp_vrf *vrf;
  1430. SCTP_IPI_ADDR_LOCK_ASSERT();
  1431. actual = 0;
  1432. if (limit == 0)
  1433. return (actual);
  1434. if (stcb) {
  1435. /* Turn on all the appropriate scope */
  1436. loopback_scope = stcb->asoc.scope.loopback_scope;
  1437. #if defined(INET)
  1438. ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope;
  1439. ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal;
  1440. #endif
  1441. #if defined(INET6)
  1442. local_scope = stcb->asoc.scope.local_scope;
  1443. site_scope = stcb->asoc.scope.site_scope;
  1444. ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal;
  1445. #endif
  1446. #if defined(__Userspace__)
  1447. conn_addr_legal = stcb->asoc.scope.conn_addr_legal;
  1448. #endif
  1449. } else {
  1450. /* Use generic values for endpoints. */
  1451. loopback_scope = 1;
  1452. #if defined(INET)
  1453. ipv4_local_scope = 1;
  1454. #endif
  1455. #if defined(INET6)
  1456. local_scope = 1;
  1457. site_scope = 1;
  1458. #endif
  1459. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  1460. #if defined(INET6)
  1461. ipv6_addr_legal = 1;
  1462. #endif
  1463. #if defined(INET)
  1464. if (SCTP_IPV6_V6ONLY(inp)) {
  1465. ipv4_addr_legal = 0;
  1466. } else {
  1467. ipv4_addr_legal = 1;
  1468. }
  1469. #endif
  1470. #if defined(__Userspace__)
  1471. conn_addr_legal = 0;
  1472. #endif
  1473. } else {
  1474. #if defined(INET6)
  1475. ipv6_addr_legal = 0;
  1476. #endif
  1477. #if defined(__Userspace__)
  1478. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
  1479. conn_addr_legal = 1;
  1480. #if defined(INET)
  1481. ipv4_addr_legal = 0;
  1482. #endif
  1483. } else {
  1484. conn_addr_legal = 0;
  1485. #if defined(INET)
  1486. ipv4_addr_legal = 1;
  1487. #endif
  1488. }
  1489. #else
  1490. #if defined(INET)
  1491. ipv4_addr_legal = 1;
  1492. #endif
  1493. #endif
  1494. }
  1495. }
  1496. vrf = sctp_find_vrf(vrf_id);
  1497. if (vrf == NULL) {
  1498. return (0);
  1499. }
  1500. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  1501. LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
  1502. if ((loopback_scope == 0) &&
  1503. SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
  1504. /* Skip loopback if loopback_scope not set */
  1505. continue;
  1506. }
  1507. LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
  1508. if (stcb) {
  1509. /*
  1510. * For the BOUND-ALL case, the list
  1511. * associated with a TCB is Always
  1512. * considered a reverse list.. i.e.
  1513. * it lists addresses that are NOT
  1514. * part of the association. If this
  1515. * is one of those we must skip it.
  1516. */
  1517. if (sctp_is_addr_restricted(stcb,
  1518. sctp_ifa)) {
  1519. continue;
  1520. }
  1521. }
  1522. switch (sctp_ifa->address.sa.sa_family) {
  1523. #ifdef INET
  1524. case AF_INET:
  1525. if (ipv4_addr_legal) {
  1526. struct sockaddr_in *sin;
  1527. sin = &sctp_ifa->address.sin;
  1528. if (sin->sin_addr.s_addr == 0) {
  1529. /*
  1530. * we skip unspecified
  1531. * addresses
  1532. */
  1533. continue;
  1534. }
  1535. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1536. if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
  1537. &sin->sin_addr) != 0) {
  1538. continue;
  1539. }
  1540. #endif
  1541. if ((ipv4_local_scope == 0) &&
  1542. (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
  1543. continue;
  1544. }
  1545. #ifdef INET6
  1546. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
  1547. if (actual + sizeof(struct sockaddr_in6) > limit) {
  1548. return (actual);
  1549. }
  1550. in6_sin_2_v4mapsin6(sin, (struct sockaddr_in6 *)addr);
  1551. ((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
  1552. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
  1553. actual += sizeof(struct sockaddr_in6);
  1554. } else {
  1555. #endif
  1556. if (actual + sizeof(struct sockaddr_in) > limit) {
  1557. return (actual);
  1558. }
  1559. memcpy(addr, sin, sizeof(struct sockaddr_in));
  1560. ((struct sockaddr_in *)addr)->sin_port = inp->sctp_lport;
  1561. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in));
  1562. actual += sizeof(struct sockaddr_in);
  1563. #ifdef INET6
  1564. }
  1565. #endif
  1566. } else {
  1567. continue;
  1568. }
  1569. break;
  1570. #endif
  1571. #ifdef INET6
  1572. case AF_INET6:
  1573. if (ipv6_addr_legal) {
  1574. struct sockaddr_in6 *sin6;
  1575. #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
  1576. struct sockaddr_in6 lsa6;
  1577. #endif
  1578. sin6 = &sctp_ifa->address.sin6;
  1579. if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  1580. /*
  1581. * we skip unspecified
  1582. * addresses
  1583. */
  1584. continue;
  1585. }
  1586. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1587. if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
  1588. &sin6->sin6_addr) != 0) {
  1589. continue;
  1590. }
  1591. #endif
  1592. if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
  1593. if (local_scope == 0)
  1594. continue;
  1595. #if defined(SCTP_EMBEDDED_V6_SCOPE)
  1596. if (sin6->sin6_scope_id == 0) {
  1597. #ifdef SCTP_KAME
  1598. if (sa6_recoverscope(sin6) != 0)
  1599. /*
  1600. * bad link
  1601. * local
  1602. * address
  1603. */
  1604. continue;
  1605. #else
  1606. lsa6 = *sin6;
  1607. if (in6_recoverscope(&lsa6,
  1608. &lsa6.sin6_addr,
  1609. NULL))
  1610. /*
  1611. * bad link
  1612. * local
  1613. * address
  1614. */
  1615. continue;
  1616. sin6 = &lsa6;
  1617. #endif /* SCTP_KAME */
  1618. }
  1619. #endif /* SCTP_EMBEDDED_V6_SCOPE */
  1620. }
  1621. if ((site_scope == 0) &&
  1622. (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
  1623. continue;
  1624. }
  1625. if (actual + sizeof(struct sockaddr_in6) > limit) {
  1626. return (actual);
  1627. }
  1628. memcpy(addr, sin6, sizeof(struct sockaddr_in6));
  1629. ((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
  1630. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_in6));
  1631. actual += sizeof(struct sockaddr_in6);
  1632. } else {
  1633. continue;
  1634. }
  1635. break;
  1636. #endif
  1637. #if defined(__Userspace__)
  1638. case AF_CONN:
  1639. if (conn_addr_legal) {
  1640. if (actual + sizeof(struct sockaddr_conn) > limit) {
  1641. return (actual);
  1642. }
  1643. memcpy(addr, &sctp_ifa->address.sconn, sizeof(struct sockaddr_conn));
  1644. ((struct sockaddr_conn *)addr)->sconn_port = inp->sctp_lport;
  1645. addr = (struct sockaddr *)((caddr_t)addr + sizeof(struct sockaddr_conn));
  1646. actual += sizeof(struct sockaddr_conn);
  1647. } else {
  1648. continue;
  1649. }
  1650. #endif
  1651. default:
  1652. /* TSNH */
  1653. break;
  1654. }
  1655. }
  1656. }
  1657. } else {
  1658. struct sctp_laddr *laddr;
  1659. size_t sa_len;
  1660. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  1661. if (stcb) {
  1662. if (sctp_is_addr_restricted(stcb, laddr->ifa)) {
  1663. continue;
  1664. }
  1665. }
  1666. #ifdef HAVE_SA_LEN
  1667. sa_len = laddr->ifa->address.sa.sa_len;
  1668. #else
  1669. switch (laddr->ifa->address.sa.sa_family) {
  1670. #ifdef INET
  1671. case AF_INET:
  1672. sa_len = sizeof(struct sockaddr_in);
  1673. break;
  1674. #endif
  1675. #ifdef INET6
  1676. case AF_INET6:
  1677. sa_len = sizeof(struct sockaddr_in6);
  1678. break;
  1679. #endif
  1680. #if defined(__Userspace__)
  1681. case AF_CONN:
  1682. sa_len = sizeof(struct sockaddr_conn);
  1683. break;
  1684. #endif
  1685. default:
  1686. /* TSNH */
  1687. sa_len = 0;
  1688. break;
  1689. }
  1690. #endif
  1691. if (actual + sa_len > limit) {
  1692. return (actual);
  1693. }
  1694. if (sctp_fill_user_address(addr, &laddr->ifa->address.sa))
  1695. continue;
  1696. switch (laddr->ifa->address.sa.sa_family) {
  1697. #ifdef INET
  1698. case AF_INET:
  1699. ((struct sockaddr_in *)addr)->sin_port = inp->sctp_lport;
  1700. break;
  1701. #endif
  1702. #ifdef INET6
  1703. case AF_INET6:
  1704. ((struct sockaddr_in6 *)addr)->sin6_port = inp->sctp_lport;
  1705. break;
  1706. #endif
  1707. #if defined(__Userspace__)
  1708. case AF_CONN:
  1709. ((struct sockaddr_conn *)addr)->sconn_port = inp->sctp_lport;
  1710. break;
  1711. #endif
  1712. default:
  1713. /* TSNH */
  1714. break;
  1715. }
  1716. addr = (struct sockaddr *)((caddr_t)addr + sa_len);
  1717. actual += sa_len;
  1718. }
  1719. }
  1720. return (actual);
  1721. }
  1722. static size_t
  1723. sctp_fill_up_addresses(struct sctp_inpcb *inp,
  1724. struct sctp_tcb *stcb,
  1725. size_t limit,
  1726. struct sockaddr *addr)
  1727. {
  1728. size_t size;
  1729. #ifdef SCTP_MVRF
  1730. uint32_t id;
  1731. #endif
  1732. SCTP_IPI_ADDR_RLOCK();
  1733. #ifdef SCTP_MVRF
  1734. /*
  1735. * FIX ME: ?? this WILL report duplicate addresses if they appear
  1736. * in more than one VRF.
  1737. */
  1738. /* fill up addresses for all VRFs on the endpoint */
  1739. size = 0;
  1740. for (id = 0; (id < inp->num_vrfs) && (size < limit); id++) {
  1741. size += sctp_fill_up_addresses_vrf(inp, stcb, limit, addr,
  1742. inp->m_vrf_ids[id]);
  1743. addr = (struct sockaddr *)((caddr_t)addr + size);
  1744. }
  1745. #else
  1746. /* fill up addresses for the endpoint's default vrf */
  1747. size = sctp_fill_up_addresses_vrf(inp, stcb, limit, addr,
  1748. inp->def_vrf_id);
  1749. #endif
  1750. SCTP_IPI_ADDR_RUNLOCK();
  1751. return (size);
  1752. }
  1753. static size_t
  1754. sctp_max_size_addresses_vrf(struct sctp_inpcb *inp, uint32_t vrf_id)
  1755. {
  1756. struct sctp_vrf *vrf;
  1757. size_t size;
  1758. /*
  1759. * In both sub-set bound an bound_all cases we return the size of
  1760. * the maximum number of addresses that you could get. In reality
  1761. * the sub-set bound may have an exclusion list for a given TCB or
  1762. * in the bound-all case a TCB may NOT include the loopback or other
  1763. * addresses as well.
  1764. */
  1765. SCTP_IPI_ADDR_LOCK_ASSERT();
  1766. vrf = sctp_find_vrf(vrf_id);
  1767. if (vrf == NULL) {
  1768. return (0);
  1769. }
  1770. size = 0;
  1771. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  1772. struct sctp_ifn *sctp_ifn;
  1773. struct sctp_ifa *sctp_ifa;
  1774. LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
  1775. LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
  1776. /* Count them if they are the right type */
  1777. switch (sctp_ifa->address.sa.sa_family) {
  1778. #ifdef INET
  1779. case AF_INET:
  1780. #ifdef INET6
  1781. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
  1782. size += sizeof(struct sockaddr_in6);
  1783. else
  1784. size += sizeof(struct sockaddr_in);
  1785. #else
  1786. size += sizeof(struct sockaddr_in);
  1787. #endif
  1788. break;
  1789. #endif
  1790. #ifdef INET6
  1791. case AF_INET6:
  1792. size += sizeof(struct sockaddr_in6);
  1793. break;
  1794. #endif
  1795. #if defined(__Userspace__)
  1796. case AF_CONN:
  1797. size += sizeof(struct sockaddr_conn);
  1798. break;
  1799. #endif
  1800. default:
  1801. break;
  1802. }
  1803. }
  1804. }
  1805. } else {
  1806. struct sctp_laddr *laddr;
  1807. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  1808. switch (laddr->ifa->address.sa.sa_family) {
  1809. #ifdef INET
  1810. case AF_INET:
  1811. #ifdef INET6
  1812. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4))
  1813. size += sizeof(struct sockaddr_in6);
  1814. else
  1815. size += sizeof(struct sockaddr_in);
  1816. #else
  1817. size += sizeof(struct sockaddr_in);
  1818. #endif
  1819. break;
  1820. #endif
  1821. #ifdef INET6
  1822. case AF_INET6:
  1823. size += sizeof(struct sockaddr_in6);
  1824. break;
  1825. #endif
  1826. #if defined(__Userspace__)
  1827. case AF_CONN:
  1828. size += sizeof(struct sockaddr_conn);
  1829. break;
  1830. #endif
  1831. default:
  1832. break;
  1833. }
  1834. }
  1835. }
  1836. return (size);
  1837. }
  1838. static size_t
  1839. sctp_max_size_addresses(struct sctp_inpcb *inp)
  1840. {
  1841. size_t size;
  1842. #ifdef SCTP_MVRF
  1843. int id;
  1844. #endif
  1845. SCTP_IPI_ADDR_RLOCK();
  1846. #ifdef SCTP_MVRF
  1847. /*
  1848. * FIX ME: ?? this WILL count duplicate addresses if they appear
  1849. * in more than one VRF.
  1850. */
  1851. /* Maximum size of all addresses for all VRFs on the endpoint */
  1852. size = 0;
  1853. for (id = 0; id < inp->num_vrfs; id++) {
  1854. size += sctp_max_size_addresses_vrf(inp, inp->m_vrf_ids[id]);
  1855. }
  1856. #else
  1857. /* Maximum size of all addresses for the endpoint's default VRF */
  1858. size = sctp_max_size_addresses_vrf(inp, inp->def_vrf_id);
  1859. #endif
  1860. SCTP_IPI_ADDR_RUNLOCK();
  1861. return (size);
  1862. }
  1863. static int
  1864. sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
  1865. size_t optsize, void *p, int delay)
  1866. {
  1867. int error;
  1868. int creat_lock_on = 0;
  1869. struct sctp_tcb *stcb = NULL;
  1870. struct sockaddr *sa;
  1871. unsigned int num_v6 = 0, num_v4 = 0, *totaddrp, totaddr;
  1872. uint32_t vrf_id;
  1873. sctp_assoc_t *a_id;
  1874. SCTPDBG(SCTP_DEBUG_PCB1, "Connectx called\n");
  1875. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  1876. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  1877. /* We are already connected AND the TCP model */
  1878. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
  1879. return (EADDRINUSE);
  1880. }
  1881. if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
  1882. (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
  1883. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  1884. return (EINVAL);
  1885. }
  1886. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  1887. SCTP_INP_RLOCK(inp);
  1888. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  1889. SCTP_INP_RUNLOCK(inp);
  1890. }
  1891. if (stcb) {
  1892. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  1893. return (EALREADY);
  1894. }
  1895. SCTP_INP_INCR_REF(inp);
  1896. SCTP_ASOC_CREATE_LOCK(inp);
  1897. creat_lock_on = 1;
  1898. if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
  1899. (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
  1900. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
  1901. error = EFAULT;
  1902. goto out_now;
  1903. }
  1904. totaddrp = (unsigned int *)optval;
  1905. totaddr = *totaddrp;
  1906. sa = (struct sockaddr *)(totaddrp + 1);
  1907. error = sctp_connectx_helper_find(inp, sa, totaddr, &num_v4, &num_v6, (unsigned int)(optsize - sizeof(int)));
  1908. if (error != 0) {
  1909. /* Already have or am bring up an association */
  1910. SCTP_ASOC_CREATE_UNLOCK(inp);
  1911. creat_lock_on = 0;
  1912. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  1913. goto out_now;
  1914. }
  1915. #ifdef INET6
  1916. if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
  1917. (num_v6 > 0)) {
  1918. error = EINVAL;
  1919. goto out_now;
  1920. }
  1921. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
  1922. (num_v4 > 0)) {
  1923. if (SCTP_IPV6_V6ONLY(inp)) {
  1924. /*
  1925. * if IPV6_V6ONLY flag, ignore connections destined
  1926. * to a v4 addr or v4-mapped addr
  1927. */
  1928. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  1929. error = EINVAL;
  1930. goto out_now;
  1931. }
  1932. }
  1933. #endif /* INET6 */
  1934. if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
  1935. /* Bind a ephemeral port */
  1936. error = sctp_inpcb_bind(so, NULL, NULL, p);
  1937. if (error) {
  1938. goto out_now;
  1939. }
  1940. }
  1941. /* FIX ME: do we want to pass in a vrf on the connect call? */
  1942. vrf_id = inp->def_vrf_id;
  1943. /* We are GOOD to go */
  1944. stcb = sctp_aloc_assoc_connected(inp, sa, &error, 0, 0, vrf_id,
  1945. inp->sctp_ep.pre_open_stream_count,
  1946. inp->sctp_ep.port,
  1947. #if defined(__FreeBSD__) && !defined(__Userspace__)
  1948. (struct thread *)p,
  1949. #elif defined(_WIN32) && !defined(__Userspace__)
  1950. (PKTHREAD)p,
  1951. #else
  1952. (struct proc *)p,
  1953. #endif
  1954. SCTP_INITIALIZE_AUTH_PARAMS);
  1955. if (stcb == NULL) {
  1956. /* Gak! no memory */
  1957. goto out_now;
  1958. }
  1959. SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
  1960. /* move to second address */
  1961. switch (sa->sa_family) {
  1962. #ifdef INET
  1963. case AF_INET:
  1964. sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
  1965. break;
  1966. #endif
  1967. #ifdef INET6
  1968. case AF_INET6:
  1969. sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
  1970. break;
  1971. #endif
  1972. default:
  1973. break;
  1974. }
  1975. error = 0;
  1976. sctp_connectx_helper_add(stcb, sa, (totaddr-1), &error);
  1977. /* Fill in the return id */
  1978. if (error) {
  1979. goto out_now;
  1980. }
  1981. a_id = (sctp_assoc_t *)optval;
  1982. *a_id = sctp_get_associd(stcb);
  1983. if (delay) {
  1984. /* doing delayed connection */
  1985. stcb->asoc.delayed_connection = 1;
  1986. sctp_timer_start(SCTP_TIMER_TYPE_INIT, inp, stcb, stcb->asoc.primary_destination);
  1987. } else {
  1988. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  1989. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  1990. }
  1991. SCTP_TCB_UNLOCK(stcb);
  1992. out_now:
  1993. if (creat_lock_on) {
  1994. SCTP_ASOC_CREATE_UNLOCK(inp);
  1995. }
  1996. SCTP_INP_DECR_REF(inp);
  1997. return (error);
  1998. }
  1999. #define SCTP_FIND_STCB(inp, stcb, assoc_id) { \
  2000. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||\
  2001. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { \
  2002. SCTP_INP_RLOCK(inp); \
  2003. stcb = LIST_FIRST(&inp->sctp_asoc_list); \
  2004. if (stcb) { \
  2005. SCTP_TCB_LOCK(stcb); \
  2006. } \
  2007. SCTP_INP_RUNLOCK(inp); \
  2008. } else if (assoc_id > SCTP_ALL_ASSOC) { \
  2009. stcb = sctp_findassociation_ep_asocid(inp, assoc_id, 1); \
  2010. if (stcb == NULL) { \
  2011. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT); \
  2012. error = ENOENT; \
  2013. break; \
  2014. } \
  2015. } else { \
  2016. stcb = NULL; \
  2017. } \
  2018. }
  2019. #define SCTP_CHECK_AND_CAST(destp, srcp, type, size) {\
  2020. if (size < sizeof(type)) { \
  2021. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); \
  2022. error = EINVAL; \
  2023. break; \
  2024. } else { \
  2025. destp = (type *)srcp; \
  2026. } \
  2027. }
  2028. #if defined(__Userspace__)
  2029. int
  2030. #else
  2031. static int
  2032. #endif
  2033. sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
  2034. void *p) {
  2035. struct sctp_inpcb *inp = NULL;
  2036. int error, val = 0;
  2037. struct sctp_tcb *stcb = NULL;
  2038. if (optval == NULL) {
  2039. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2040. return (EINVAL);
  2041. }
  2042. inp = (struct sctp_inpcb *)so->so_pcb;
  2043. if (inp == NULL) {
  2044. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2045. return EINVAL;
  2046. }
  2047. error = 0;
  2048. switch (optname) {
  2049. case SCTP_NODELAY:
  2050. case SCTP_AUTOCLOSE:
  2051. case SCTP_EXPLICIT_EOR:
  2052. case SCTP_AUTO_ASCONF:
  2053. case SCTP_DISABLE_FRAGMENTS:
  2054. case SCTP_I_WANT_MAPPED_V4_ADDR:
  2055. case SCTP_USE_EXT_RCVINFO:
  2056. SCTP_INP_RLOCK(inp);
  2057. switch (optname) {
  2058. case SCTP_DISABLE_FRAGMENTS:
  2059. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT);
  2060. break;
  2061. case SCTP_I_WANT_MAPPED_V4_ADDR:
  2062. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4);
  2063. break;
  2064. case SCTP_AUTO_ASCONF:
  2065. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  2066. /* only valid for bound all sockets */
  2067. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF);
  2068. } else {
  2069. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2070. error = EINVAL;
  2071. goto flags_out;
  2072. }
  2073. break;
  2074. case SCTP_EXPLICIT_EOR:
  2075. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR);
  2076. break;
  2077. case SCTP_NODELAY:
  2078. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY);
  2079. break;
  2080. case SCTP_USE_EXT_RCVINFO:
  2081. val = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXT_RCVINFO);
  2082. break;
  2083. case SCTP_AUTOCLOSE:
  2084. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))
  2085. val = sctp_ticks_to_secs(inp->sctp_ep.auto_close_time);
  2086. else
  2087. val = 0;
  2088. break;
  2089. default:
  2090. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
  2091. error = ENOPROTOOPT;
  2092. } /* end switch (sopt->sopt_name) */
  2093. if (*optsize < sizeof(val)) {
  2094. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2095. error = EINVAL;
  2096. }
  2097. flags_out:
  2098. SCTP_INP_RUNLOCK(inp);
  2099. if (error == 0) {
  2100. /* return the option value */
  2101. *(int *)optval = val;
  2102. *optsize = sizeof(val);
  2103. }
  2104. break;
  2105. case SCTP_GET_PACKET_LOG:
  2106. {
  2107. #ifdef SCTP_PACKET_LOGGING
  2108. uint8_t *target;
  2109. int ret;
  2110. SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize);
  2111. ret = sctp_copy_out_packet_log(target , (int)*optsize);
  2112. *optsize = ret;
  2113. #else
  2114. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  2115. error = EOPNOTSUPP;
  2116. #endif
  2117. break;
  2118. }
  2119. case SCTP_REUSE_PORT:
  2120. {
  2121. uint32_t *value;
  2122. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) {
  2123. /* Can't do this for a 1-m socket */
  2124. error = EINVAL;
  2125. break;
  2126. }
  2127. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2128. *value = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE);
  2129. *optsize = sizeof(uint32_t);
  2130. break;
  2131. }
  2132. case SCTP_PARTIAL_DELIVERY_POINT:
  2133. {
  2134. uint32_t *value;
  2135. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2136. *value = inp->partial_delivery_point;
  2137. *optsize = sizeof(uint32_t);
  2138. break;
  2139. }
  2140. case SCTP_FRAGMENT_INTERLEAVE:
  2141. {
  2142. uint32_t *value;
  2143. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2144. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) {
  2145. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) {
  2146. *value = SCTP_FRAG_LEVEL_2;
  2147. } else {
  2148. *value = SCTP_FRAG_LEVEL_1;
  2149. }
  2150. } else {
  2151. *value = SCTP_FRAG_LEVEL_0;
  2152. }
  2153. *optsize = sizeof(uint32_t);
  2154. break;
  2155. }
  2156. case SCTP_INTERLEAVING_SUPPORTED:
  2157. {
  2158. struct sctp_assoc_value *av;
  2159. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2160. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2161. if (stcb) {
  2162. av->assoc_value = stcb->asoc.idata_supported;
  2163. SCTP_TCB_UNLOCK(stcb);
  2164. } else {
  2165. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2166. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2167. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2168. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2169. SCTP_INP_RLOCK(inp);
  2170. if (inp->idata_supported) {
  2171. av->assoc_value = 1;
  2172. } else {
  2173. av->assoc_value = 0;
  2174. }
  2175. SCTP_INP_RUNLOCK(inp);
  2176. } else {
  2177. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2178. error = EINVAL;
  2179. }
  2180. }
  2181. if (error == 0) {
  2182. *optsize = sizeof(struct sctp_assoc_value);
  2183. }
  2184. break;
  2185. }
  2186. case SCTP_CMT_ON_OFF:
  2187. {
  2188. struct sctp_assoc_value *av;
  2189. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2190. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2191. if (stcb) {
  2192. av->assoc_value = stcb->asoc.sctp_cmt_on_off;
  2193. SCTP_TCB_UNLOCK(stcb);
  2194. } else {
  2195. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2196. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2197. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2198. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2199. SCTP_INP_RLOCK(inp);
  2200. av->assoc_value = inp->sctp_cmt_on_off;
  2201. SCTP_INP_RUNLOCK(inp);
  2202. } else {
  2203. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2204. error = EINVAL;
  2205. }
  2206. }
  2207. if (error == 0) {
  2208. *optsize = sizeof(struct sctp_assoc_value);
  2209. }
  2210. break;
  2211. }
  2212. case SCTP_PLUGGABLE_CC:
  2213. {
  2214. struct sctp_assoc_value *av;
  2215. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2216. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2217. if (stcb) {
  2218. av->assoc_value = stcb->asoc.congestion_control_module;
  2219. SCTP_TCB_UNLOCK(stcb);
  2220. } else {
  2221. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2222. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2223. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2224. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2225. SCTP_INP_RLOCK(inp);
  2226. av->assoc_value = inp->sctp_ep.sctp_default_cc_module;
  2227. SCTP_INP_RUNLOCK(inp);
  2228. } else {
  2229. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2230. error = EINVAL;
  2231. }
  2232. }
  2233. if (error == 0) {
  2234. *optsize = sizeof(struct sctp_assoc_value);
  2235. }
  2236. break;
  2237. }
  2238. case SCTP_CC_OPTION:
  2239. {
  2240. struct sctp_cc_option *cc_opt;
  2241. SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, *optsize);
  2242. SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
  2243. if (stcb == NULL) {
  2244. error = EINVAL;
  2245. } else {
  2246. if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
  2247. error = ENOTSUP;
  2248. } else {
  2249. error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 0, cc_opt);
  2250. *optsize = sizeof(struct sctp_cc_option);
  2251. }
  2252. SCTP_TCB_UNLOCK(stcb);
  2253. }
  2254. break;
  2255. }
  2256. case SCTP_PLUGGABLE_SS:
  2257. {
  2258. struct sctp_assoc_value *av;
  2259. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2260. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2261. if (stcb) {
  2262. av->assoc_value = stcb->asoc.stream_scheduling_module;
  2263. SCTP_TCB_UNLOCK(stcb);
  2264. } else {
  2265. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2266. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2267. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2268. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2269. SCTP_INP_RLOCK(inp);
  2270. av->assoc_value = inp->sctp_ep.sctp_default_ss_module;
  2271. SCTP_INP_RUNLOCK(inp);
  2272. } else {
  2273. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2274. error = EINVAL;
  2275. }
  2276. }
  2277. if (error == 0) {
  2278. *optsize = sizeof(struct sctp_assoc_value);
  2279. }
  2280. break;
  2281. }
  2282. case SCTP_SS_VALUE:
  2283. {
  2284. struct sctp_stream_value *av;
  2285. SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, *optsize);
  2286. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2287. if (stcb) {
  2288. if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
  2289. (stcb->asoc.ss_functions.sctp_ss_get_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
  2290. &av->stream_value) < 0)) {
  2291. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2292. error = EINVAL;
  2293. } else {
  2294. *optsize = sizeof(struct sctp_stream_value);
  2295. }
  2296. SCTP_TCB_UNLOCK(stcb);
  2297. } else {
  2298. /* Can't get stream value without association */
  2299. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2300. error = EINVAL;
  2301. }
  2302. break;
  2303. }
  2304. case SCTP_GET_ADDR_LEN:
  2305. {
  2306. struct sctp_assoc_value *av;
  2307. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2308. error = EINVAL;
  2309. #ifdef INET
  2310. if (av->assoc_value == AF_INET) {
  2311. av->assoc_value = sizeof(struct sockaddr_in);
  2312. error = 0;
  2313. }
  2314. #endif
  2315. #ifdef INET6
  2316. if (av->assoc_value == AF_INET6) {
  2317. av->assoc_value = sizeof(struct sockaddr_in6);
  2318. error = 0;
  2319. }
  2320. #endif
  2321. #if defined(__Userspace__)
  2322. if (av->assoc_value == AF_CONN) {
  2323. av->assoc_value = sizeof(struct sockaddr_conn);
  2324. error = 0;
  2325. }
  2326. #endif
  2327. if (error) {
  2328. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2329. } else {
  2330. *optsize = sizeof(struct sctp_assoc_value);
  2331. }
  2332. break;
  2333. }
  2334. case SCTP_GET_ASSOC_NUMBER:
  2335. {
  2336. uint32_t *value, cnt;
  2337. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2338. SCTP_INP_RLOCK(inp);
  2339. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2340. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
  2341. /* Can't do this for a 1-1 socket */
  2342. error = EINVAL;
  2343. SCTP_INP_RUNLOCK(inp);
  2344. break;
  2345. }
  2346. cnt = 0;
  2347. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  2348. cnt++;
  2349. }
  2350. SCTP_INP_RUNLOCK(inp);
  2351. *value = cnt;
  2352. *optsize = sizeof(uint32_t);
  2353. break;
  2354. }
  2355. case SCTP_GET_ASSOC_ID_LIST:
  2356. {
  2357. struct sctp_assoc_ids *ids;
  2358. uint32_t at;
  2359. size_t limit;
  2360. SCTP_CHECK_AND_CAST(ids, optval, struct sctp_assoc_ids, *optsize);
  2361. SCTP_INP_RLOCK(inp);
  2362. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2363. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
  2364. /* Can't do this for a 1-1 socket */
  2365. error = EINVAL;
  2366. SCTP_INP_RUNLOCK(inp);
  2367. break;
  2368. }
  2369. at = 0;
  2370. limit = (*optsize - sizeof(uint32_t)) / sizeof(sctp_assoc_t);
  2371. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  2372. if (at < limit) {
  2373. ids->gaids_assoc_id[at++] = sctp_get_associd(stcb);
  2374. if (at == 0) {
  2375. error = EINVAL;
  2376. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2377. break;
  2378. }
  2379. } else {
  2380. error = EINVAL;
  2381. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2382. break;
  2383. }
  2384. }
  2385. SCTP_INP_RUNLOCK(inp);
  2386. if (error == 0) {
  2387. ids->gaids_number_of_ids = at;
  2388. *optsize = ((at * sizeof(sctp_assoc_t)) + sizeof(uint32_t));
  2389. }
  2390. break;
  2391. }
  2392. case SCTP_CONTEXT:
  2393. {
  2394. struct sctp_assoc_value *av;
  2395. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2396. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2397. if (stcb) {
  2398. av->assoc_value = stcb->asoc.context;
  2399. SCTP_TCB_UNLOCK(stcb);
  2400. } else {
  2401. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2402. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2403. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2404. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2405. SCTP_INP_RLOCK(inp);
  2406. av->assoc_value = inp->sctp_context;
  2407. SCTP_INP_RUNLOCK(inp);
  2408. } else {
  2409. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2410. error = EINVAL;
  2411. }
  2412. }
  2413. if (error == 0) {
  2414. *optsize = sizeof(struct sctp_assoc_value);
  2415. }
  2416. break;
  2417. }
  2418. case SCTP_VRF_ID:
  2419. {
  2420. uint32_t *default_vrfid;
  2421. SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, *optsize);
  2422. *default_vrfid = inp->def_vrf_id;
  2423. *optsize = sizeof(uint32_t);
  2424. break;
  2425. }
  2426. case SCTP_GET_ASOC_VRF:
  2427. {
  2428. struct sctp_assoc_value *id;
  2429. SCTP_CHECK_AND_CAST(id, optval, struct sctp_assoc_value, *optsize);
  2430. SCTP_FIND_STCB(inp, stcb, id->assoc_id);
  2431. if (stcb == NULL) {
  2432. error = EINVAL;
  2433. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2434. } else {
  2435. id->assoc_value = stcb->asoc.vrf_id;
  2436. SCTP_TCB_UNLOCK(stcb);
  2437. *optsize = sizeof(struct sctp_assoc_value);
  2438. }
  2439. break;
  2440. }
  2441. case SCTP_GET_VRF_IDS:
  2442. {
  2443. #ifdef SCTP_MVRF
  2444. int siz_needed;
  2445. uint32_t *vrf_ids;
  2446. SCTP_CHECK_AND_CAST(vrf_ids, optval, uint32_t, *optsize);
  2447. siz_needed = inp->num_vrfs * sizeof(uint32_t);
  2448. if (*optsize < siz_needed) {
  2449. error = EINVAL;
  2450. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2451. } else {
  2452. memcpy(vrf_ids, inp->m_vrf_ids, siz_needed);
  2453. *optsize = siz_needed;
  2454. }
  2455. #else
  2456. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  2457. error = EOPNOTSUPP;
  2458. #endif
  2459. break;
  2460. }
  2461. case SCTP_GET_NONCE_VALUES:
  2462. {
  2463. struct sctp_get_nonce_values *gnv;
  2464. SCTP_CHECK_AND_CAST(gnv, optval, struct sctp_get_nonce_values, *optsize);
  2465. SCTP_FIND_STCB(inp, stcb, gnv->gn_assoc_id);
  2466. if (stcb) {
  2467. gnv->gn_peers_tag = stcb->asoc.peer_vtag;
  2468. gnv->gn_local_tag = stcb->asoc.my_vtag;
  2469. SCTP_TCB_UNLOCK(stcb);
  2470. *optsize = sizeof(struct sctp_get_nonce_values);
  2471. } else {
  2472. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
  2473. error = ENOTCONN;
  2474. }
  2475. break;
  2476. }
  2477. case SCTP_DELAYED_SACK:
  2478. {
  2479. struct sctp_sack_info *sack;
  2480. SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, *optsize);
  2481. SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
  2482. if (stcb) {
  2483. sack->sack_delay = stcb->asoc.delayed_ack;
  2484. sack->sack_freq = stcb->asoc.sack_freq;
  2485. SCTP_TCB_UNLOCK(stcb);
  2486. } else {
  2487. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2488. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2489. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2490. (sack->sack_assoc_id == SCTP_FUTURE_ASSOC))) {
  2491. SCTP_INP_RLOCK(inp);
  2492. sack->sack_delay = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]);
  2493. sack->sack_freq = inp->sctp_ep.sctp_sack_freq;
  2494. SCTP_INP_RUNLOCK(inp);
  2495. } else {
  2496. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2497. error = EINVAL;
  2498. }
  2499. }
  2500. if (error == 0) {
  2501. *optsize = sizeof(struct sctp_sack_info);
  2502. }
  2503. break;
  2504. }
  2505. case SCTP_GET_SNDBUF_USE:
  2506. {
  2507. struct sctp_sockstat *ss;
  2508. SCTP_CHECK_AND_CAST(ss, optval, struct sctp_sockstat, *optsize);
  2509. SCTP_FIND_STCB(inp, stcb, ss->ss_assoc_id);
  2510. if (stcb) {
  2511. ss->ss_total_sndbuf = stcb->asoc.total_output_queue_size;
  2512. ss->ss_total_recv_buf = (stcb->asoc.size_on_reasm_queue +
  2513. stcb->asoc.size_on_all_streams);
  2514. SCTP_TCB_UNLOCK(stcb);
  2515. *optsize = sizeof(struct sctp_sockstat);
  2516. } else {
  2517. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
  2518. error = ENOTCONN;
  2519. }
  2520. break;
  2521. }
  2522. case SCTP_MAX_BURST:
  2523. {
  2524. struct sctp_assoc_value *av;
  2525. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2526. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2527. if (stcb) {
  2528. av->assoc_value = stcb->asoc.max_burst;
  2529. SCTP_TCB_UNLOCK(stcb);
  2530. } else {
  2531. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2532. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2533. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2534. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2535. SCTP_INP_RLOCK(inp);
  2536. av->assoc_value = inp->sctp_ep.max_burst;
  2537. SCTP_INP_RUNLOCK(inp);
  2538. } else {
  2539. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2540. error = EINVAL;
  2541. }
  2542. }
  2543. if (error == 0) {
  2544. *optsize = sizeof(struct sctp_assoc_value);
  2545. }
  2546. break;
  2547. }
  2548. case SCTP_MAXSEG:
  2549. {
  2550. struct sctp_assoc_value *av;
  2551. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  2552. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  2553. if (stcb) {
  2554. av->assoc_value = stcb->asoc.sctp_frag_point;
  2555. SCTP_TCB_UNLOCK(stcb);
  2556. } else {
  2557. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2558. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2559. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2560. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  2561. SCTP_INP_RLOCK(inp);
  2562. av->assoc_value = inp->sctp_frag_point;
  2563. SCTP_INP_RUNLOCK(inp);
  2564. } else {
  2565. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2566. error = EINVAL;
  2567. }
  2568. }
  2569. if (error == 0) {
  2570. *optsize = sizeof(struct sctp_assoc_value);
  2571. }
  2572. break;
  2573. }
  2574. case SCTP_GET_STAT_LOG:
  2575. error = sctp_fill_stat_log(optval, optsize);
  2576. break;
  2577. case SCTP_EVENTS:
  2578. {
  2579. struct sctp_event_subscribe *events;
  2580. SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, *optsize);
  2581. memset(events, 0, sizeof(struct sctp_event_subscribe));
  2582. SCTP_INP_RLOCK(inp);
  2583. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT))
  2584. events->sctp_data_io_event = 1;
  2585. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT))
  2586. events->sctp_association_event = 1;
  2587. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT))
  2588. events->sctp_address_event = 1;
  2589. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT))
  2590. events->sctp_send_failure_event = 1;
  2591. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR))
  2592. events->sctp_peer_error_event = 1;
  2593. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT))
  2594. events->sctp_shutdown_event = 1;
  2595. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT))
  2596. events->sctp_partial_delivery_event = 1;
  2597. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT))
  2598. events->sctp_adaptation_layer_event = 1;
  2599. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT))
  2600. events->sctp_authentication_event = 1;
  2601. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT))
  2602. events->sctp_sender_dry_event = 1;
  2603. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
  2604. events->sctp_stream_reset_event = 1;
  2605. SCTP_INP_RUNLOCK(inp);
  2606. *optsize = sizeof(struct sctp_event_subscribe);
  2607. break;
  2608. }
  2609. case SCTP_ADAPTATION_LAYER:
  2610. {
  2611. uint32_t *value;
  2612. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2613. SCTP_INP_RLOCK(inp);
  2614. *value = inp->sctp_ep.adaptation_layer_indicator;
  2615. SCTP_INP_RUNLOCK(inp);
  2616. *optsize = sizeof(uint32_t);
  2617. break;
  2618. }
  2619. case SCTP_SET_INITIAL_DBG_SEQ:
  2620. {
  2621. uint32_t *value;
  2622. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2623. SCTP_INP_RLOCK(inp);
  2624. *value = inp->sctp_ep.initial_sequence_debug;
  2625. SCTP_INP_RUNLOCK(inp);
  2626. *optsize = sizeof(uint32_t);
  2627. break;
  2628. }
  2629. case SCTP_GET_LOCAL_ADDR_SIZE:
  2630. {
  2631. uint32_t *value;
  2632. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2633. SCTP_INP_RLOCK(inp);
  2634. *value = (uint32_t)sctp_max_size_addresses(inp);
  2635. SCTP_INP_RUNLOCK(inp);
  2636. *optsize = sizeof(uint32_t);
  2637. break;
  2638. }
  2639. case SCTP_GET_REMOTE_ADDR_SIZE:
  2640. {
  2641. uint32_t *value;
  2642. struct sctp_nets *net;
  2643. size_t size;
  2644. SCTP_CHECK_AND_CAST(value, optval, uint32_t, *optsize);
  2645. /* FIXME MT: change to sctp_assoc_value? */
  2646. SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t)*value);
  2647. if (stcb != NULL) {
  2648. size = 0;
  2649. /* Count the sizes */
  2650. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  2651. switch (net->ro._l_addr.sa.sa_family) {
  2652. #ifdef INET
  2653. case AF_INET:
  2654. #ifdef INET6
  2655. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
  2656. size += sizeof(struct sockaddr_in6);
  2657. } else {
  2658. size += sizeof(struct sockaddr_in);
  2659. }
  2660. #else
  2661. size += sizeof(struct sockaddr_in);
  2662. #endif
  2663. break;
  2664. #endif
  2665. #ifdef INET6
  2666. case AF_INET6:
  2667. size += sizeof(struct sockaddr_in6);
  2668. break;
  2669. #endif
  2670. #if defined(__Userspace__)
  2671. case AF_CONN:
  2672. size += sizeof(struct sockaddr_conn);
  2673. break;
  2674. #endif
  2675. default:
  2676. break;
  2677. }
  2678. }
  2679. SCTP_TCB_UNLOCK(stcb);
  2680. *value = (uint32_t)size;
  2681. *optsize = sizeof(uint32_t);
  2682. } else {
  2683. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2684. ((sctp_assoc_t)*value <= SCTP_ALL_ASSOC)) {
  2685. error = EINVAL;
  2686. } else {
  2687. error = ENOENT;
  2688. }
  2689. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2690. }
  2691. break;
  2692. }
  2693. case SCTP_GET_PEER_ADDRESSES:
  2694. /*
  2695. * Get the address information, an array is passed in to
  2696. * fill up we pack it.
  2697. */
  2698. {
  2699. size_t cpsz, left;
  2700. struct sockaddr *addr;
  2701. struct sctp_nets *net;
  2702. struct sctp_getaddresses *saddr;
  2703. SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
  2704. SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
  2705. if (stcb != NULL) {
  2706. left = *optsize - offsetof(struct sctp_getaddresses, addr);
  2707. *optsize = offsetof(struct sctp_getaddresses, addr);
  2708. addr = &saddr->addr[0].sa;
  2709. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  2710. switch (net->ro._l_addr.sa.sa_family) {
  2711. #ifdef INET
  2712. case AF_INET:
  2713. #ifdef INET6
  2714. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
  2715. cpsz = sizeof(struct sockaddr_in6);
  2716. } else {
  2717. cpsz = sizeof(struct sockaddr_in);
  2718. }
  2719. #else
  2720. cpsz = sizeof(struct sockaddr_in);
  2721. #endif
  2722. break;
  2723. #endif
  2724. #ifdef INET6
  2725. case AF_INET6:
  2726. cpsz = sizeof(struct sockaddr_in6);
  2727. break;
  2728. #endif
  2729. #if defined(__Userspace__)
  2730. case AF_CONN:
  2731. cpsz = sizeof(struct sockaddr_conn);
  2732. break;
  2733. #endif
  2734. default:
  2735. cpsz = 0;
  2736. break;
  2737. }
  2738. if (cpsz == 0) {
  2739. break;
  2740. }
  2741. if (left < cpsz) {
  2742. /* not enough room. */
  2743. break;
  2744. }
  2745. #if defined(INET) && defined(INET6)
  2746. if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) &&
  2747. (net->ro._l_addr.sa.sa_family == AF_INET)) {
  2748. /* Must map the address */
  2749. in6_sin_2_v4mapsin6(&net->ro._l_addr.sin,
  2750. (struct sockaddr_in6 *)addr);
  2751. } else {
  2752. memcpy(addr, &net->ro._l_addr, cpsz);
  2753. }
  2754. #else
  2755. memcpy(addr, &net->ro._l_addr, cpsz);
  2756. #endif
  2757. ((struct sockaddr_in *)addr)->sin_port = stcb->rport;
  2758. addr = (struct sockaddr *)((caddr_t)addr + cpsz);
  2759. left -= cpsz;
  2760. *optsize += cpsz;
  2761. }
  2762. SCTP_TCB_UNLOCK(stcb);
  2763. } else {
  2764. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2765. (saddr->sget_assoc_id <= SCTP_ALL_ASSOC)) {
  2766. error = EINVAL;
  2767. } else {
  2768. error = ENOENT;
  2769. }
  2770. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2771. }
  2772. break;
  2773. }
  2774. case SCTP_GET_LOCAL_ADDRESSES:
  2775. {
  2776. size_t limit, actual;
  2777. struct sctp_getaddresses *saddr;
  2778. SCTP_CHECK_AND_CAST(saddr, optval, struct sctp_getaddresses, *optsize);
  2779. SCTP_FIND_STCB(inp, stcb, saddr->sget_assoc_id);
  2780. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2781. ((saddr->sget_assoc_id == SCTP_CURRENT_ASSOC) ||
  2782. (saddr->sget_assoc_id == SCTP_ALL_ASSOC))) {
  2783. error = EINVAL;
  2784. } else {
  2785. limit = *optsize - offsetof(struct sctp_getaddresses, addr);
  2786. actual = sctp_fill_up_addresses(inp, stcb, limit, &saddr->addr[0].sa);
  2787. *optsize = offsetof(struct sctp_getaddresses, addr) + actual;
  2788. }
  2789. if (stcb != NULL) {
  2790. SCTP_TCB_UNLOCK(stcb);
  2791. }
  2792. break;
  2793. }
  2794. case SCTP_PEER_ADDR_PARAMS:
  2795. {
  2796. struct sctp_paddrparams *paddrp;
  2797. struct sctp_nets *net;
  2798. struct sockaddr *addr;
  2799. #if defined(INET) && defined(INET6)
  2800. struct sockaddr_in sin_store;
  2801. #endif
  2802. SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, *optsize);
  2803. SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
  2804. #if defined(INET) && defined(INET6)
  2805. if (paddrp->spp_address.ss_family == AF_INET6) {
  2806. struct sockaddr_in6 *sin6;
  2807. sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
  2808. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  2809. in6_sin6_2_sin(&sin_store, sin6);
  2810. addr = (struct sockaddr *)&sin_store;
  2811. } else {
  2812. addr = (struct sockaddr *)&paddrp->spp_address;
  2813. }
  2814. } else {
  2815. addr = (struct sockaddr *)&paddrp->spp_address;
  2816. }
  2817. #else
  2818. addr = (struct sockaddr *)&paddrp->spp_address;
  2819. #endif
  2820. if (stcb != NULL) {
  2821. net = sctp_findnet(stcb, addr);
  2822. } else {
  2823. /* We increment here since sctp_findassociation_ep_addr() wil
  2824. * do a decrement if it finds the stcb as long as the locked
  2825. * tcb (last argument) is NOT a TCB.. aka NULL.
  2826. */
  2827. net = NULL;
  2828. SCTP_INP_INCR_REF(inp);
  2829. stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
  2830. if (stcb == NULL) {
  2831. SCTP_INP_DECR_REF(inp);
  2832. }
  2833. }
  2834. if ((stcb != NULL) && (net == NULL)) {
  2835. #ifdef INET
  2836. if (addr->sa_family == AF_INET) {
  2837. struct sockaddr_in *sin;
  2838. sin = (struct sockaddr_in *)addr;
  2839. if (sin->sin_addr.s_addr != INADDR_ANY) {
  2840. error = EINVAL;
  2841. SCTP_TCB_UNLOCK(stcb);
  2842. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2843. break;
  2844. }
  2845. } else
  2846. #endif
  2847. #ifdef INET6
  2848. if (addr->sa_family == AF_INET6) {
  2849. struct sockaddr_in6 *sin6;
  2850. sin6 = (struct sockaddr_in6 *)addr;
  2851. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  2852. error = EINVAL;
  2853. SCTP_TCB_UNLOCK(stcb);
  2854. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2855. break;
  2856. }
  2857. } else
  2858. #endif
  2859. #if defined(__Userspace__)
  2860. if (addr->sa_family == AF_CONN) {
  2861. struct sockaddr_conn *sconn;
  2862. sconn = (struct sockaddr_conn *)addr;
  2863. if (sconn->sconn_addr != NULL) {
  2864. error = EINVAL;
  2865. SCTP_TCB_UNLOCK(stcb);
  2866. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2867. break;
  2868. }
  2869. } else
  2870. #endif
  2871. {
  2872. error = EAFNOSUPPORT;
  2873. SCTP_TCB_UNLOCK(stcb);
  2874. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  2875. break;
  2876. }
  2877. }
  2878. if (stcb != NULL) {
  2879. /* Applies to the specific association */
  2880. paddrp->spp_flags = 0;
  2881. if (net != NULL) {
  2882. paddrp->spp_hbinterval = net->heart_beat_delay;
  2883. paddrp->spp_pathmaxrxt = net->failure_threshold;
  2884. paddrp->spp_pathmtu = net->mtu;
  2885. switch (net->ro._l_addr.sa.sa_family) {
  2886. #ifdef INET
  2887. case AF_INET:
  2888. paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD;
  2889. break;
  2890. #endif
  2891. #ifdef INET6
  2892. case AF_INET6:
  2893. paddrp->spp_pathmtu -= SCTP_MIN_OVERHEAD;
  2894. break;
  2895. #endif
  2896. #if defined(__Userspace__)
  2897. case AF_CONN:
  2898. paddrp->spp_pathmtu -= sizeof(struct sctphdr);
  2899. break;
  2900. #endif
  2901. default:
  2902. break;
  2903. }
  2904. /* get flags for HB */
  2905. if (net->dest_state & SCTP_ADDR_NOHB) {
  2906. paddrp->spp_flags |= SPP_HB_DISABLE;
  2907. } else {
  2908. paddrp->spp_flags |= SPP_HB_ENABLE;
  2909. }
  2910. /* get flags for PMTU */
  2911. if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
  2912. paddrp->spp_flags |= SPP_PMTUD_DISABLE;
  2913. } else {
  2914. paddrp->spp_flags |= SPP_PMTUD_ENABLE;
  2915. }
  2916. if (net->dscp & 0x01) {
  2917. paddrp->spp_dscp = net->dscp & 0xfc;
  2918. paddrp->spp_flags |= SPP_DSCP;
  2919. }
  2920. #ifdef INET6
  2921. if ((net->ro._l_addr.sa.sa_family == AF_INET6) &&
  2922. (net->flowlabel & 0x80000000)) {
  2923. paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff;
  2924. paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
  2925. }
  2926. #endif
  2927. } else {
  2928. /*
  2929. * No destination so return default
  2930. * value
  2931. */
  2932. paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
  2933. paddrp->spp_pathmtu = stcb->asoc.default_mtu;
  2934. if (stcb->asoc.default_dscp & 0x01) {
  2935. paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc;
  2936. paddrp->spp_flags |= SPP_DSCP;
  2937. }
  2938. #ifdef INET6
  2939. if (stcb->asoc.default_flowlabel & 0x80000000) {
  2940. paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff;
  2941. paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
  2942. }
  2943. #endif
  2944. /* default settings should be these */
  2945. if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
  2946. paddrp->spp_flags |= SPP_HB_DISABLE;
  2947. } else {
  2948. paddrp->spp_flags |= SPP_HB_ENABLE;
  2949. }
  2950. if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
  2951. paddrp->spp_flags |= SPP_PMTUD_DISABLE;
  2952. } else {
  2953. paddrp->spp_flags |= SPP_PMTUD_ENABLE;
  2954. }
  2955. paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
  2956. }
  2957. paddrp->spp_assoc_id = sctp_get_associd(stcb);
  2958. SCTP_TCB_UNLOCK(stcb);
  2959. } else {
  2960. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  2961. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  2962. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  2963. (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) {
  2964. /* Use endpoint defaults */
  2965. SCTP_INP_RLOCK(inp);
  2966. paddrp->spp_pathmaxrxt = inp->sctp_ep.def_net_failure;
  2967. paddrp->spp_hbinterval = sctp_ticks_to_msecs(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
  2968. paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
  2969. /* get inp's default */
  2970. if (inp->sctp_ep.default_dscp & 0x01) {
  2971. paddrp->spp_dscp = inp->sctp_ep.default_dscp & 0xfc;
  2972. paddrp->spp_flags |= SPP_DSCP;
  2973. }
  2974. #ifdef INET6
  2975. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
  2976. (inp->sctp_ep.default_flowlabel & 0x80000000)) {
  2977. paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff;
  2978. paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
  2979. }
  2980. #endif
  2981. paddrp->spp_pathmtu = inp->sctp_ep.default_mtu;
  2982. if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
  2983. paddrp->spp_flags |= SPP_HB_ENABLE;
  2984. } else {
  2985. paddrp->spp_flags |= SPP_HB_DISABLE;
  2986. }
  2987. if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
  2988. paddrp->spp_flags |= SPP_PMTUD_ENABLE;
  2989. } else {
  2990. paddrp->spp_flags |= SPP_PMTUD_DISABLE;
  2991. }
  2992. SCTP_INP_RUNLOCK(inp);
  2993. } else {
  2994. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  2995. error = EINVAL;
  2996. }
  2997. }
  2998. if (error == 0) {
  2999. *optsize = sizeof(struct sctp_paddrparams);
  3000. }
  3001. break;
  3002. }
  3003. case SCTP_GET_PEER_ADDR_INFO:
  3004. {
  3005. struct sctp_paddrinfo *paddri;
  3006. struct sctp_nets *net;
  3007. struct sockaddr *addr;
  3008. #if defined(INET) && defined(INET6)
  3009. struct sockaddr_in sin_store;
  3010. #endif
  3011. SCTP_CHECK_AND_CAST(paddri, optval, struct sctp_paddrinfo, *optsize);
  3012. SCTP_FIND_STCB(inp, stcb, paddri->spinfo_assoc_id);
  3013. #if defined(INET) && defined(INET6)
  3014. if (paddri->spinfo_address.ss_family == AF_INET6) {
  3015. struct sockaddr_in6 *sin6;
  3016. sin6 = (struct sockaddr_in6 *)&paddri->spinfo_address;
  3017. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  3018. in6_sin6_2_sin(&sin_store, sin6);
  3019. addr = (struct sockaddr *)&sin_store;
  3020. } else {
  3021. addr = (struct sockaddr *)&paddri->spinfo_address;
  3022. }
  3023. } else {
  3024. addr = (struct sockaddr *)&paddri->spinfo_address;
  3025. }
  3026. #else
  3027. addr = (struct sockaddr *)&paddri->spinfo_address;
  3028. #endif
  3029. if (stcb != NULL) {
  3030. net = sctp_findnet(stcb, addr);
  3031. } else {
  3032. /* We increment here since sctp_findassociation_ep_addr() wil
  3033. * do a decrement if it finds the stcb as long as the locked
  3034. * tcb (last argument) is NOT a TCB.. aka NULL.
  3035. */
  3036. net = NULL;
  3037. SCTP_INP_INCR_REF(inp);
  3038. stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
  3039. if (stcb == NULL) {
  3040. SCTP_INP_DECR_REF(inp);
  3041. }
  3042. }
  3043. if ((stcb != NULL) && (net != NULL)) {
  3044. if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
  3045. /* It's unconfirmed */
  3046. paddri->spinfo_state = SCTP_UNCONFIRMED;
  3047. } else if (net->dest_state & SCTP_ADDR_REACHABLE) {
  3048. /* It's active */
  3049. paddri->spinfo_state = SCTP_ACTIVE;
  3050. } else {
  3051. /* It's inactive */
  3052. paddri->spinfo_state = SCTP_INACTIVE;
  3053. }
  3054. paddri->spinfo_cwnd = net->cwnd;
  3055. paddri->spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
  3056. paddri->spinfo_rto = net->RTO;
  3057. paddri->spinfo_assoc_id = sctp_get_associd(stcb);
  3058. paddri->spinfo_mtu = net->mtu;
  3059. switch (addr->sa_family) {
  3060. #if defined(INET)
  3061. case AF_INET:
  3062. paddri->spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
  3063. break;
  3064. #endif
  3065. #if defined(INET6)
  3066. case AF_INET6:
  3067. paddri->spinfo_mtu -= SCTP_MIN_OVERHEAD;
  3068. break;
  3069. #endif
  3070. #if defined(__Userspace__)
  3071. case AF_CONN:
  3072. paddri->spinfo_mtu -= sizeof(struct sctphdr);
  3073. break;
  3074. #endif
  3075. default:
  3076. break;
  3077. }
  3078. SCTP_TCB_UNLOCK(stcb);
  3079. *optsize = sizeof(struct sctp_paddrinfo);
  3080. } else {
  3081. if (stcb != NULL) {
  3082. SCTP_TCB_UNLOCK(stcb);
  3083. }
  3084. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  3085. error = ENOENT;
  3086. }
  3087. break;
  3088. }
  3089. case SCTP_PCB_STATUS:
  3090. {
  3091. struct sctp_pcbinfo *spcb;
  3092. SCTP_CHECK_AND_CAST(spcb, optval, struct sctp_pcbinfo, *optsize);
  3093. sctp_fill_pcbinfo(spcb);
  3094. *optsize = sizeof(struct sctp_pcbinfo);
  3095. break;
  3096. }
  3097. case SCTP_STATUS:
  3098. {
  3099. struct sctp_nets *net;
  3100. struct sctp_status *sstat;
  3101. SCTP_CHECK_AND_CAST(sstat, optval, struct sctp_status, *optsize);
  3102. SCTP_FIND_STCB(inp, stcb, sstat->sstat_assoc_id);
  3103. if (stcb == NULL) {
  3104. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3105. error = EINVAL;
  3106. break;
  3107. }
  3108. sstat->sstat_state = sctp_map_assoc_state(stcb->asoc.state);
  3109. sstat->sstat_assoc_id = sctp_get_associd(stcb);
  3110. sstat->sstat_rwnd = stcb->asoc.peers_rwnd;
  3111. sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt;
  3112. /*
  3113. * We can't include chunks that have been passed to
  3114. * the socket layer. Only things in queue.
  3115. */
  3116. sstat->sstat_penddata = (stcb->asoc.cnt_on_reasm_queue +
  3117. stcb->asoc.cnt_on_all_streams);
  3118. sstat->sstat_instrms = stcb->asoc.streamincnt;
  3119. sstat->sstat_outstrms = stcb->asoc.streamoutcnt;
  3120. sstat->sstat_fragmentation_point = sctp_get_frag_point(stcb);
  3121. net = stcb->asoc.primary_destination;
  3122. if (net != NULL) {
  3123. #ifdef HAVE_SA_LEN
  3124. memcpy(&sstat->sstat_primary.spinfo_address,
  3125. &net->ro._l_addr,
  3126. ((struct sockaddr *)(&net->ro._l_addr))->sa_len);
  3127. #else
  3128. switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
  3129. #if defined(INET)
  3130. case AF_INET:
  3131. memcpy(&sstat->sstat_primary.spinfo_address,
  3132. &net->ro._l_addr,
  3133. sizeof(struct sockaddr_in));
  3134. break;
  3135. #endif
  3136. #if defined(INET6)
  3137. case AF_INET6:
  3138. memcpy(&sstat->sstat_primary.spinfo_address,
  3139. &net->ro._l_addr,
  3140. sizeof(struct sockaddr_in6));
  3141. break;
  3142. #endif
  3143. #if defined(__Userspace__)
  3144. case AF_CONN:
  3145. memcpy(&sstat->sstat_primary.spinfo_address,
  3146. &net->ro._l_addr,
  3147. sizeof(struct sockaddr_conn));
  3148. break;
  3149. #endif
  3150. default:
  3151. break;
  3152. }
  3153. #endif
  3154. ((struct sockaddr_in *)&sstat->sstat_primary.spinfo_address)->sin_port = stcb->rport;
  3155. /*
  3156. * Again the user can get info from sctp_constants.h
  3157. * for what the state of the network is.
  3158. */
  3159. if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
  3160. /* It's unconfirmed */
  3161. sstat->sstat_primary.spinfo_state = SCTP_UNCONFIRMED;
  3162. } else if (net->dest_state & SCTP_ADDR_REACHABLE) {
  3163. /* It's active */
  3164. sstat->sstat_primary.spinfo_state = SCTP_ACTIVE;
  3165. } else {
  3166. /* It's inactive */
  3167. sstat->sstat_primary.spinfo_state = SCTP_INACTIVE;
  3168. }
  3169. sstat->sstat_primary.spinfo_cwnd = net->cwnd;
  3170. sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
  3171. sstat->sstat_primary.spinfo_rto = net->RTO;
  3172. sstat->sstat_primary.spinfo_mtu = net->mtu;
  3173. switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
  3174. #if defined(INET)
  3175. case AF_INET:
  3176. sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
  3177. break;
  3178. #endif
  3179. #if defined(INET6)
  3180. case AF_INET6:
  3181. sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD;
  3182. break;
  3183. #endif
  3184. #if defined(__Userspace__)
  3185. case AF_CONN:
  3186. sstat->sstat_primary.spinfo_mtu -= sizeof(struct sctphdr);
  3187. break;
  3188. #endif
  3189. default:
  3190. break;
  3191. }
  3192. } else {
  3193. memset(&sstat->sstat_primary, 0, sizeof(struct sctp_paddrinfo));
  3194. }
  3195. sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
  3196. SCTP_TCB_UNLOCK(stcb);
  3197. *optsize = sizeof(struct sctp_status);
  3198. break;
  3199. }
  3200. case SCTP_RTOINFO:
  3201. {
  3202. struct sctp_rtoinfo *srto;
  3203. SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, *optsize);
  3204. SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
  3205. if (stcb) {
  3206. srto->srto_initial = stcb->asoc.initial_rto;
  3207. srto->srto_max = stcb->asoc.maxrto;
  3208. srto->srto_min = stcb->asoc.minrto;
  3209. SCTP_TCB_UNLOCK(stcb);
  3210. } else {
  3211. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3212. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3213. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3214. (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) {
  3215. SCTP_INP_RLOCK(inp);
  3216. srto->srto_initial = inp->sctp_ep.initial_rto;
  3217. srto->srto_max = inp->sctp_ep.sctp_maxrto;
  3218. srto->srto_min = inp->sctp_ep.sctp_minrto;
  3219. SCTP_INP_RUNLOCK(inp);
  3220. } else {
  3221. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3222. error = EINVAL;
  3223. }
  3224. }
  3225. if (error == 0) {
  3226. *optsize = sizeof(struct sctp_rtoinfo);
  3227. }
  3228. break;
  3229. }
  3230. case SCTP_TIMEOUTS:
  3231. {
  3232. struct sctp_timeouts *stimo;
  3233. SCTP_CHECK_AND_CAST(stimo, optval, struct sctp_timeouts, *optsize);
  3234. SCTP_FIND_STCB(inp, stcb, stimo->stimo_assoc_id);
  3235. if (stcb) {
  3236. stimo->stimo_init= stcb->asoc.timoinit;
  3237. stimo->stimo_data= stcb->asoc.timodata;
  3238. stimo->stimo_sack= stcb->asoc.timosack;
  3239. stimo->stimo_shutdown= stcb->asoc.timoshutdown;
  3240. stimo->stimo_heartbeat= stcb->asoc.timoheartbeat;
  3241. stimo->stimo_cookie= stcb->asoc.timocookie;
  3242. stimo->stimo_shutdownack= stcb->asoc.timoshutdownack;
  3243. SCTP_TCB_UNLOCK(stcb);
  3244. *optsize = sizeof(struct sctp_timeouts);
  3245. } else {
  3246. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3247. error = EINVAL;
  3248. }
  3249. break;
  3250. }
  3251. case SCTP_ASSOCINFO:
  3252. {
  3253. struct sctp_assocparams *sasoc;
  3254. SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, *optsize);
  3255. SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
  3256. if (stcb) {
  3257. sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(stcb->asoc.cookie_life);
  3258. sasoc->sasoc_asocmaxrxt = stcb->asoc.max_send_times;
  3259. sasoc->sasoc_number_peer_destinations = stcb->asoc.numnets;
  3260. sasoc->sasoc_peer_rwnd = stcb->asoc.peers_rwnd;
  3261. sasoc->sasoc_local_rwnd = stcb->asoc.my_rwnd;
  3262. SCTP_TCB_UNLOCK(stcb);
  3263. } else {
  3264. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3265. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3266. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3267. (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
  3268. SCTP_INP_RLOCK(inp);
  3269. sasoc->sasoc_cookie_life = sctp_ticks_to_msecs(inp->sctp_ep.def_cookie_life);
  3270. sasoc->sasoc_asocmaxrxt = inp->sctp_ep.max_send_times;
  3271. sasoc->sasoc_number_peer_destinations = 0;
  3272. sasoc->sasoc_peer_rwnd = 0;
  3273. sasoc->sasoc_local_rwnd = (uint32_t)sbspace(&inp->sctp_socket->so_rcv);
  3274. SCTP_INP_RUNLOCK(inp);
  3275. } else {
  3276. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3277. error = EINVAL;
  3278. }
  3279. }
  3280. if (error == 0) {
  3281. *optsize = sizeof(struct sctp_assocparams);
  3282. }
  3283. break;
  3284. }
  3285. case SCTP_DEFAULT_SEND_PARAM:
  3286. {
  3287. struct sctp_sndrcvinfo *s_info;
  3288. SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, *optsize);
  3289. SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
  3290. if (stcb) {
  3291. memcpy(s_info, &stcb->asoc.def_send, sizeof(stcb->asoc.def_send));
  3292. SCTP_TCB_UNLOCK(stcb);
  3293. } else {
  3294. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3295. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3296. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3297. (s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC))) {
  3298. SCTP_INP_RLOCK(inp);
  3299. memcpy(s_info, &inp->def_send, sizeof(inp->def_send));
  3300. SCTP_INP_RUNLOCK(inp);
  3301. } else {
  3302. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3303. error = EINVAL;
  3304. }
  3305. }
  3306. if (error == 0) {
  3307. *optsize = sizeof(struct sctp_sndrcvinfo);
  3308. }
  3309. break;
  3310. }
  3311. case SCTP_INITMSG:
  3312. {
  3313. struct sctp_initmsg *sinit;
  3314. SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, *optsize);
  3315. SCTP_INP_RLOCK(inp);
  3316. sinit->sinit_num_ostreams = inp->sctp_ep.pre_open_stream_count;
  3317. sinit->sinit_max_instreams = inp->sctp_ep.max_open_streams_intome;
  3318. sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
  3319. sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
  3320. SCTP_INP_RUNLOCK(inp);
  3321. *optsize = sizeof(struct sctp_initmsg);
  3322. break;
  3323. }
  3324. case SCTP_PRIMARY_ADDR:
  3325. /* we allow a "get" operation on this */
  3326. {
  3327. struct sctp_setprim *ssp;
  3328. SCTP_CHECK_AND_CAST(ssp, optval, struct sctp_setprim, *optsize);
  3329. SCTP_FIND_STCB(inp, stcb, ssp->ssp_assoc_id);
  3330. if (stcb) {
  3331. union sctp_sockstore *addr;
  3332. addr = &stcb->asoc.primary_destination->ro._l_addr;
  3333. switch (addr->sa.sa_family) {
  3334. #ifdef INET
  3335. case AF_INET:
  3336. #ifdef INET6
  3337. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NEEDS_MAPPED_V4)) {
  3338. in6_sin_2_v4mapsin6(&addr->sin,
  3339. (struct sockaddr_in6 *)&ssp->ssp_addr);
  3340. } else {
  3341. memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
  3342. }
  3343. #else
  3344. memcpy(&ssp->ssp_addr, &addr->sin, sizeof(struct sockaddr_in));
  3345. #endif
  3346. break;
  3347. #endif
  3348. #ifdef INET6
  3349. case AF_INET6:
  3350. memcpy(&ssp->ssp_addr, &addr->sin6, sizeof(struct sockaddr_in6));
  3351. break;
  3352. #endif
  3353. #if defined(__Userspace__)
  3354. case AF_CONN:
  3355. memcpy(&ssp->ssp_addr, &addr->sconn, sizeof(struct sockaddr_conn));
  3356. break;
  3357. #endif
  3358. default:
  3359. break;
  3360. }
  3361. SCTP_TCB_UNLOCK(stcb);
  3362. *optsize = sizeof(struct sctp_setprim);
  3363. } else {
  3364. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3365. error = EINVAL;
  3366. }
  3367. break;
  3368. }
  3369. case SCTP_HMAC_IDENT:
  3370. {
  3371. struct sctp_hmacalgo *shmac;
  3372. sctp_hmaclist_t *hmaclist;
  3373. size_t size;
  3374. int i;
  3375. SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, *optsize);
  3376. SCTP_INP_RLOCK(inp);
  3377. hmaclist = inp->sctp_ep.local_hmacs;
  3378. if (hmaclist == NULL) {
  3379. /* no HMACs to return */
  3380. *optsize = sizeof(*shmac);
  3381. SCTP_INP_RUNLOCK(inp);
  3382. break;
  3383. }
  3384. /* is there room for all of the hmac ids? */
  3385. size = sizeof(*shmac) + (hmaclist->num_algo *
  3386. sizeof(shmac->shmac_idents[0]));
  3387. if (*optsize < size) {
  3388. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3389. error = EINVAL;
  3390. SCTP_INP_RUNLOCK(inp);
  3391. break;
  3392. }
  3393. /* copy in the list */
  3394. shmac->shmac_number_of_idents = hmaclist->num_algo;
  3395. for (i = 0; i < hmaclist->num_algo; i++) {
  3396. shmac->shmac_idents[i] = hmaclist->hmac[i];
  3397. }
  3398. SCTP_INP_RUNLOCK(inp);
  3399. *optsize = size;
  3400. break;
  3401. }
  3402. case SCTP_AUTH_ACTIVE_KEY:
  3403. {
  3404. struct sctp_authkeyid *scact;
  3405. SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, *optsize);
  3406. SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
  3407. if (stcb) {
  3408. /* get the active key on the assoc */
  3409. scact->scact_keynumber = stcb->asoc.authinfo.active_keyid;
  3410. SCTP_TCB_UNLOCK(stcb);
  3411. } else {
  3412. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3413. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3414. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3415. (scact->scact_assoc_id == SCTP_FUTURE_ASSOC))) {
  3416. /* get the endpoint active key */
  3417. SCTP_INP_RLOCK(inp);
  3418. scact->scact_keynumber = inp->sctp_ep.default_keyid;
  3419. SCTP_INP_RUNLOCK(inp);
  3420. } else {
  3421. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3422. error = EINVAL;
  3423. }
  3424. }
  3425. if (error == 0) {
  3426. *optsize = sizeof(struct sctp_authkeyid);
  3427. }
  3428. break;
  3429. }
  3430. case SCTP_LOCAL_AUTH_CHUNKS:
  3431. {
  3432. struct sctp_authchunks *sac;
  3433. sctp_auth_chklist_t *chklist = NULL;
  3434. size_t size = 0;
  3435. SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
  3436. SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
  3437. if (stcb) {
  3438. /* get off the assoc */
  3439. chklist = stcb->asoc.local_auth_chunks;
  3440. /* is there enough space? */
  3441. size = sctp_auth_get_chklist_size(chklist);
  3442. if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
  3443. error = EINVAL;
  3444. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3445. } else {
  3446. /* copy in the chunks */
  3447. (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
  3448. sac->gauth_number_of_chunks = (uint32_t)size;
  3449. *optsize = sizeof(struct sctp_authchunks) + size;
  3450. }
  3451. SCTP_TCB_UNLOCK(stcb);
  3452. } else {
  3453. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3454. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3455. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3456. (sac->gauth_assoc_id == SCTP_FUTURE_ASSOC))) {
  3457. /* get off the endpoint */
  3458. SCTP_INP_RLOCK(inp);
  3459. chklist = inp->sctp_ep.local_auth_chunks;
  3460. /* is there enough space? */
  3461. size = sctp_auth_get_chklist_size(chklist);
  3462. if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
  3463. error = EINVAL;
  3464. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3465. } else {
  3466. /* copy in the chunks */
  3467. (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
  3468. sac->gauth_number_of_chunks = (uint32_t)size;
  3469. *optsize = sizeof(struct sctp_authchunks) + size;
  3470. }
  3471. SCTP_INP_RUNLOCK(inp);
  3472. } else {
  3473. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3474. error = EINVAL;
  3475. }
  3476. }
  3477. break;
  3478. }
  3479. case SCTP_PEER_AUTH_CHUNKS:
  3480. {
  3481. struct sctp_authchunks *sac;
  3482. sctp_auth_chklist_t *chklist = NULL;
  3483. size_t size = 0;
  3484. SCTP_CHECK_AND_CAST(sac, optval, struct sctp_authchunks, *optsize);
  3485. SCTP_FIND_STCB(inp, stcb, sac->gauth_assoc_id);
  3486. if (stcb) {
  3487. /* get off the assoc */
  3488. chklist = stcb->asoc.peer_auth_chunks;
  3489. /* is there enough space? */
  3490. size = sctp_auth_get_chklist_size(chklist);
  3491. if (*optsize < (sizeof(struct sctp_authchunks) + size)) {
  3492. error = EINVAL;
  3493. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3494. } else {
  3495. /* copy in the chunks */
  3496. (void)sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
  3497. sac->gauth_number_of_chunks = (uint32_t)size;
  3498. *optsize = sizeof(struct sctp_authchunks) + size;
  3499. }
  3500. SCTP_TCB_UNLOCK(stcb);
  3501. } else {
  3502. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  3503. error = ENOENT;
  3504. }
  3505. break;
  3506. }
  3507. #if defined(HAVE_SCTP_PEELOFF_SOCKOPT)
  3508. case SCTP_PEELOFF:
  3509. {
  3510. struct sctp_peeloff_opt *peeloff;
  3511. SCTP_CHECK_AND_CAST(peeloff, optval, struct sctp_peeloff_opt, *optsize);
  3512. /* do the peeloff */
  3513. error = sctp_peeloff_option(p, peeloff);
  3514. if (error == 0) {
  3515. *optsize = sizeof(struct sctp_peeloff_opt);
  3516. }
  3517. }
  3518. break;
  3519. #endif /* HAVE_SCTP_PEELOFF_SOCKOPT */
  3520. case SCTP_EVENT:
  3521. {
  3522. struct sctp_event *event;
  3523. uint32_t event_type;
  3524. SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, *optsize);
  3525. SCTP_FIND_STCB(inp, stcb, event->se_assoc_id);
  3526. switch (event->se_type) {
  3527. case SCTP_ASSOC_CHANGE:
  3528. event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT;
  3529. break;
  3530. case SCTP_PEER_ADDR_CHANGE:
  3531. event_type = SCTP_PCB_FLAGS_RECVPADDREVNT;
  3532. break;
  3533. case SCTP_REMOTE_ERROR:
  3534. event_type = SCTP_PCB_FLAGS_RECVPEERERR;
  3535. break;
  3536. case SCTP_SEND_FAILED:
  3537. event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
  3538. break;
  3539. case SCTP_SHUTDOWN_EVENT:
  3540. event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
  3541. break;
  3542. case SCTP_ADAPTATION_INDICATION:
  3543. event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT;
  3544. break;
  3545. case SCTP_PARTIAL_DELIVERY_EVENT:
  3546. event_type = SCTP_PCB_FLAGS_PDAPIEVNT;
  3547. break;
  3548. case SCTP_AUTHENTICATION_EVENT:
  3549. event_type = SCTP_PCB_FLAGS_AUTHEVNT;
  3550. break;
  3551. case SCTP_STREAM_RESET_EVENT:
  3552. event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT;
  3553. break;
  3554. case SCTP_SENDER_DRY_EVENT:
  3555. event_type = SCTP_PCB_FLAGS_DRYEVNT;
  3556. break;
  3557. case SCTP_NOTIFICATIONS_STOPPED_EVENT:
  3558. event_type = 0;
  3559. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
  3560. error = ENOTSUP;
  3561. break;
  3562. case SCTP_ASSOC_RESET_EVENT:
  3563. event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT;
  3564. break;
  3565. case SCTP_STREAM_CHANGE_EVENT:
  3566. event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
  3567. break;
  3568. case SCTP_SEND_FAILED_EVENT:
  3569. event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
  3570. break;
  3571. default:
  3572. event_type = 0;
  3573. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3574. error = EINVAL;
  3575. break;
  3576. }
  3577. if (event_type > 0) {
  3578. if (stcb) {
  3579. event->se_on = sctp_stcb_is_feature_on(inp, stcb, event_type);
  3580. } else {
  3581. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3582. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3583. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3584. (event->se_assoc_id == SCTP_FUTURE_ASSOC))) {
  3585. SCTP_INP_RLOCK(inp);
  3586. event->se_on = sctp_is_feature_on(inp, event_type);
  3587. SCTP_INP_RUNLOCK(inp);
  3588. } else {
  3589. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3590. error = EINVAL;
  3591. }
  3592. }
  3593. }
  3594. if (stcb != NULL) {
  3595. SCTP_TCB_UNLOCK(stcb);
  3596. }
  3597. if (error == 0) {
  3598. *optsize = sizeof(struct sctp_event);
  3599. }
  3600. break;
  3601. }
  3602. case SCTP_RECVRCVINFO:
  3603. if (*optsize < sizeof(int)) {
  3604. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3605. error = EINVAL;
  3606. } else {
  3607. SCTP_INP_RLOCK(inp);
  3608. *(int *)optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
  3609. SCTP_INP_RUNLOCK(inp);
  3610. *optsize = sizeof(int);
  3611. }
  3612. break;
  3613. case SCTP_RECVNXTINFO:
  3614. if (*optsize < sizeof(int)) {
  3615. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3616. error = EINVAL;
  3617. } else {
  3618. SCTP_INP_RLOCK(inp);
  3619. *(int *)optval = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
  3620. SCTP_INP_RUNLOCK(inp);
  3621. *optsize = sizeof(int);
  3622. }
  3623. break;
  3624. case SCTP_DEFAULT_SNDINFO:
  3625. {
  3626. struct sctp_sndinfo *info;
  3627. SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, *optsize);
  3628. SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id);
  3629. if (stcb) {
  3630. info->snd_sid = stcb->asoc.def_send.sinfo_stream;
  3631. info->snd_flags = stcb->asoc.def_send.sinfo_flags;
  3632. info->snd_flags &= 0xfff0;
  3633. info->snd_ppid = stcb->asoc.def_send.sinfo_ppid;
  3634. info->snd_context = stcb->asoc.def_send.sinfo_context;
  3635. SCTP_TCB_UNLOCK(stcb);
  3636. } else {
  3637. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3638. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3639. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3640. (info->snd_assoc_id == SCTP_FUTURE_ASSOC))) {
  3641. SCTP_INP_RLOCK(inp);
  3642. info->snd_sid = inp->def_send.sinfo_stream;
  3643. info->snd_flags = inp->def_send.sinfo_flags;
  3644. info->snd_flags &= 0xfff0;
  3645. info->snd_ppid = inp->def_send.sinfo_ppid;
  3646. info->snd_context = inp->def_send.sinfo_context;
  3647. SCTP_INP_RUNLOCK(inp);
  3648. } else {
  3649. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3650. error = EINVAL;
  3651. }
  3652. }
  3653. if (error == 0) {
  3654. *optsize = sizeof(struct sctp_sndinfo);
  3655. }
  3656. break;
  3657. }
  3658. case SCTP_DEFAULT_PRINFO:
  3659. {
  3660. struct sctp_default_prinfo *info;
  3661. SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize);
  3662. SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
  3663. if (stcb) {
  3664. info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
  3665. info->pr_value = stcb->asoc.def_send.sinfo_timetolive;
  3666. SCTP_TCB_UNLOCK(stcb);
  3667. } else {
  3668. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3669. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3670. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3671. (info->pr_assoc_id == SCTP_FUTURE_ASSOC))) {
  3672. SCTP_INP_RLOCK(inp);
  3673. info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
  3674. info->pr_value = inp->def_send.sinfo_timetolive;
  3675. SCTP_INP_RUNLOCK(inp);
  3676. } else {
  3677. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3678. error = EINVAL;
  3679. }
  3680. }
  3681. if (error == 0) {
  3682. *optsize = sizeof(struct sctp_default_prinfo);
  3683. }
  3684. break;
  3685. }
  3686. case SCTP_PEER_ADDR_THLDS:
  3687. {
  3688. struct sctp_paddrthlds *thlds;
  3689. struct sctp_nets *net;
  3690. struct sockaddr *addr;
  3691. #if defined(INET) && defined(INET6)
  3692. struct sockaddr_in sin_store;
  3693. #endif
  3694. SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, *optsize);
  3695. SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
  3696. #if defined(INET) && defined(INET6)
  3697. if (thlds->spt_address.ss_family == AF_INET6) {
  3698. struct sockaddr_in6 *sin6;
  3699. sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
  3700. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  3701. in6_sin6_2_sin(&sin_store, sin6);
  3702. addr = (struct sockaddr *)&sin_store;
  3703. } else {
  3704. addr = (struct sockaddr *)&thlds->spt_address;
  3705. }
  3706. } else {
  3707. addr = (struct sockaddr *)&thlds->spt_address;
  3708. }
  3709. #else
  3710. addr = (struct sockaddr *)&thlds->spt_address;
  3711. #endif
  3712. if (stcb != NULL) {
  3713. net = sctp_findnet(stcb, addr);
  3714. } else {
  3715. /* We increment here since sctp_findassociation_ep_addr() wil
  3716. * do a decrement if it finds the stcb as long as the locked
  3717. * tcb (last argument) is NOT a TCB.. aka NULL.
  3718. */
  3719. net = NULL;
  3720. SCTP_INP_INCR_REF(inp);
  3721. stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
  3722. if (stcb == NULL) {
  3723. SCTP_INP_DECR_REF(inp);
  3724. }
  3725. }
  3726. if ((stcb != NULL) && (net == NULL)) {
  3727. #ifdef INET
  3728. if (addr->sa_family == AF_INET) {
  3729. struct sockaddr_in *sin;
  3730. sin = (struct sockaddr_in *)addr;
  3731. if (sin->sin_addr.s_addr != INADDR_ANY) {
  3732. error = EINVAL;
  3733. SCTP_TCB_UNLOCK(stcb);
  3734. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3735. break;
  3736. }
  3737. } else
  3738. #endif
  3739. #ifdef INET6
  3740. if (addr->sa_family == AF_INET6) {
  3741. struct sockaddr_in6 *sin6;
  3742. sin6 = (struct sockaddr_in6 *)addr;
  3743. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  3744. error = EINVAL;
  3745. SCTP_TCB_UNLOCK(stcb);
  3746. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3747. break;
  3748. }
  3749. } else
  3750. #endif
  3751. #if defined(__Userspace__)
  3752. if (addr->sa_family == AF_CONN) {
  3753. struct sockaddr_conn *sconn;
  3754. sconn = (struct sockaddr_conn *)addr;
  3755. if (sconn->sconn_addr != NULL) {
  3756. error = EINVAL;
  3757. SCTP_TCB_UNLOCK(stcb);
  3758. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3759. break;
  3760. }
  3761. } else
  3762. #endif
  3763. {
  3764. error = EAFNOSUPPORT;
  3765. SCTP_TCB_UNLOCK(stcb);
  3766. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3767. break;
  3768. }
  3769. }
  3770. if (stcb != NULL) {
  3771. if (net != NULL) {
  3772. thlds->spt_pathmaxrxt = net->failure_threshold;
  3773. thlds->spt_pathpfthld = net->pf_threshold;
  3774. thlds->spt_pathcpthld = 0xffff;
  3775. } else {
  3776. thlds->spt_pathmaxrxt = stcb->asoc.def_net_failure;
  3777. thlds->spt_pathpfthld = stcb->asoc.def_net_pf_threshold;
  3778. thlds->spt_pathcpthld = 0xffff;
  3779. }
  3780. thlds->spt_assoc_id = sctp_get_associd(stcb);
  3781. SCTP_TCB_UNLOCK(stcb);
  3782. } else {
  3783. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3784. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3785. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3786. (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) {
  3787. /* Use endpoint defaults */
  3788. SCTP_INP_RLOCK(inp);
  3789. thlds->spt_pathmaxrxt = inp->sctp_ep.def_net_failure;
  3790. thlds->spt_pathpfthld = inp->sctp_ep.def_net_pf_threshold;
  3791. thlds->spt_pathcpthld = 0xffff;
  3792. SCTP_INP_RUNLOCK(inp);
  3793. } else {
  3794. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3795. error = EINVAL;
  3796. }
  3797. }
  3798. if (error == 0) {
  3799. *optsize = sizeof(struct sctp_paddrthlds);
  3800. }
  3801. break;
  3802. }
  3803. case SCTP_REMOTE_UDP_ENCAPS_PORT:
  3804. {
  3805. struct sctp_udpencaps *encaps;
  3806. struct sctp_nets *net;
  3807. struct sockaddr *addr;
  3808. #if defined(INET) && defined(INET6)
  3809. struct sockaddr_in sin_store;
  3810. #endif
  3811. SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, *optsize);
  3812. SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
  3813. #if defined(INET) && defined(INET6)
  3814. if (encaps->sue_address.ss_family == AF_INET6) {
  3815. struct sockaddr_in6 *sin6;
  3816. sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
  3817. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  3818. in6_sin6_2_sin(&sin_store, sin6);
  3819. addr = (struct sockaddr *)&sin_store;
  3820. } else {
  3821. addr = (struct sockaddr *)&encaps->sue_address;
  3822. }
  3823. } else {
  3824. addr = (struct sockaddr *)&encaps->sue_address;
  3825. }
  3826. #else
  3827. addr = (struct sockaddr *)&encaps->sue_address;
  3828. #endif
  3829. if (stcb) {
  3830. net = sctp_findnet(stcb, addr);
  3831. } else {
  3832. /* We increment here since sctp_findassociation_ep_addr() wil
  3833. * do a decrement if it finds the stcb as long as the locked
  3834. * tcb (last argument) is NOT a TCB.. aka NULL.
  3835. */
  3836. net = NULL;
  3837. SCTP_INP_INCR_REF(inp);
  3838. stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
  3839. if (stcb == NULL) {
  3840. SCTP_INP_DECR_REF(inp);
  3841. }
  3842. }
  3843. if ((stcb != NULL) && (net == NULL)) {
  3844. #ifdef INET
  3845. if (addr->sa_family == AF_INET) {
  3846. struct sockaddr_in *sin;
  3847. sin = (struct sockaddr_in *)addr;
  3848. if (sin->sin_addr.s_addr != INADDR_ANY) {
  3849. error = EINVAL;
  3850. SCTP_TCB_UNLOCK(stcb);
  3851. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3852. break;
  3853. }
  3854. } else
  3855. #endif
  3856. #ifdef INET6
  3857. if (addr->sa_family == AF_INET6) {
  3858. struct sockaddr_in6 *sin6;
  3859. sin6 = (struct sockaddr_in6 *)addr;
  3860. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  3861. error = EINVAL;
  3862. SCTP_TCB_UNLOCK(stcb);
  3863. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3864. break;
  3865. }
  3866. } else
  3867. #endif
  3868. #if defined(__Userspace__)
  3869. if (addr->sa_family == AF_CONN) {
  3870. struct sockaddr_conn *sconn;
  3871. sconn = (struct sockaddr_conn *)addr;
  3872. if (sconn->sconn_addr != NULL) {
  3873. error = EINVAL;
  3874. SCTP_TCB_UNLOCK(stcb);
  3875. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3876. break;
  3877. }
  3878. } else
  3879. #endif
  3880. {
  3881. error = EAFNOSUPPORT;
  3882. SCTP_TCB_UNLOCK(stcb);
  3883. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  3884. break;
  3885. }
  3886. }
  3887. if (stcb != NULL) {
  3888. if (net) {
  3889. encaps->sue_port = net->port;
  3890. } else {
  3891. encaps->sue_port = stcb->asoc.port;
  3892. }
  3893. SCTP_TCB_UNLOCK(stcb);
  3894. } else {
  3895. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3896. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3897. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3898. (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) {
  3899. SCTP_INP_RLOCK(inp);
  3900. encaps->sue_port = inp->sctp_ep.port;
  3901. SCTP_INP_RUNLOCK(inp);
  3902. } else {
  3903. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3904. error = EINVAL;
  3905. }
  3906. }
  3907. if (error == 0) {
  3908. *optsize = sizeof(struct sctp_udpencaps);
  3909. }
  3910. break;
  3911. }
  3912. case SCTP_ECN_SUPPORTED:
  3913. {
  3914. struct sctp_assoc_value *av;
  3915. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  3916. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  3917. if (stcb) {
  3918. av->assoc_value = stcb->asoc.ecn_supported;
  3919. SCTP_TCB_UNLOCK(stcb);
  3920. } else {
  3921. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3922. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3923. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3924. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  3925. SCTP_INP_RLOCK(inp);
  3926. av->assoc_value = inp->ecn_supported;
  3927. SCTP_INP_RUNLOCK(inp);
  3928. } else {
  3929. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3930. error = EINVAL;
  3931. }
  3932. }
  3933. if (error == 0) {
  3934. *optsize = sizeof(struct sctp_assoc_value);
  3935. }
  3936. break;
  3937. }
  3938. case SCTP_PR_SUPPORTED:
  3939. {
  3940. struct sctp_assoc_value *av;
  3941. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  3942. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  3943. if (stcb) {
  3944. av->assoc_value = stcb->asoc.prsctp_supported;
  3945. SCTP_TCB_UNLOCK(stcb);
  3946. } else {
  3947. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3948. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3949. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3950. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  3951. SCTP_INP_RLOCK(inp);
  3952. av->assoc_value = inp->prsctp_supported;
  3953. SCTP_INP_RUNLOCK(inp);
  3954. } else {
  3955. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3956. error = EINVAL;
  3957. }
  3958. }
  3959. if (error == 0) {
  3960. *optsize = sizeof(struct sctp_assoc_value);
  3961. }
  3962. break;
  3963. }
  3964. case SCTP_AUTH_SUPPORTED:
  3965. {
  3966. struct sctp_assoc_value *av;
  3967. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  3968. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  3969. if (stcb) {
  3970. av->assoc_value = stcb->asoc.auth_supported;
  3971. SCTP_TCB_UNLOCK(stcb);
  3972. } else {
  3973. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  3974. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  3975. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  3976. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  3977. SCTP_INP_RLOCK(inp);
  3978. av->assoc_value = inp->auth_supported;
  3979. SCTP_INP_RUNLOCK(inp);
  3980. } else {
  3981. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  3982. error = EINVAL;
  3983. }
  3984. }
  3985. if (error == 0) {
  3986. *optsize = sizeof(struct sctp_assoc_value);
  3987. }
  3988. break;
  3989. }
  3990. case SCTP_ASCONF_SUPPORTED:
  3991. {
  3992. struct sctp_assoc_value *av;
  3993. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  3994. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  3995. if (stcb) {
  3996. av->assoc_value = stcb->asoc.asconf_supported;
  3997. SCTP_TCB_UNLOCK(stcb);
  3998. } else {
  3999. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4000. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4001. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4002. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4003. SCTP_INP_RLOCK(inp);
  4004. av->assoc_value = inp->asconf_supported;
  4005. SCTP_INP_RUNLOCK(inp);
  4006. } else {
  4007. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4008. error = EINVAL;
  4009. }
  4010. }
  4011. if (error == 0) {
  4012. *optsize = sizeof(struct sctp_assoc_value);
  4013. }
  4014. break;
  4015. }
  4016. case SCTP_RECONFIG_SUPPORTED:
  4017. {
  4018. struct sctp_assoc_value *av;
  4019. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  4020. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4021. if (stcb) {
  4022. av->assoc_value = stcb->asoc.reconfig_supported;
  4023. SCTP_TCB_UNLOCK(stcb);
  4024. } else {
  4025. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4026. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4027. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4028. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4029. SCTP_INP_RLOCK(inp);
  4030. av->assoc_value = inp->reconfig_supported;
  4031. SCTP_INP_RUNLOCK(inp);
  4032. } else {
  4033. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4034. error = EINVAL;
  4035. }
  4036. }
  4037. if (error == 0) {
  4038. *optsize = sizeof(struct sctp_assoc_value);
  4039. }
  4040. break;
  4041. }
  4042. case SCTP_NRSACK_SUPPORTED:
  4043. {
  4044. struct sctp_assoc_value *av;
  4045. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  4046. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4047. if (stcb) {
  4048. av->assoc_value = stcb->asoc.nrsack_supported;
  4049. SCTP_TCB_UNLOCK(stcb);
  4050. } else {
  4051. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4052. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4053. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4054. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4055. SCTP_INP_RLOCK(inp);
  4056. av->assoc_value = inp->nrsack_supported;
  4057. SCTP_INP_RUNLOCK(inp);
  4058. } else {
  4059. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4060. error = EINVAL;
  4061. }
  4062. }
  4063. if (error == 0) {
  4064. *optsize = sizeof(struct sctp_assoc_value);
  4065. }
  4066. break;
  4067. }
  4068. case SCTP_PKTDROP_SUPPORTED:
  4069. {
  4070. struct sctp_assoc_value *av;
  4071. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  4072. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4073. if (stcb) {
  4074. av->assoc_value = stcb->asoc.pktdrop_supported;
  4075. SCTP_TCB_UNLOCK(stcb);
  4076. } else {
  4077. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4078. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4079. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4080. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4081. SCTP_INP_RLOCK(inp);
  4082. av->assoc_value = inp->pktdrop_supported;
  4083. SCTP_INP_RUNLOCK(inp);
  4084. } else {
  4085. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4086. error = EINVAL;
  4087. }
  4088. }
  4089. if (error == 0) {
  4090. *optsize = sizeof(struct sctp_assoc_value);
  4091. }
  4092. break;
  4093. }
  4094. case SCTP_ENABLE_STREAM_RESET:
  4095. {
  4096. struct sctp_assoc_value *av;
  4097. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  4098. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4099. if (stcb) {
  4100. av->assoc_value = (uint32_t)stcb->asoc.local_strreset_support;
  4101. SCTP_TCB_UNLOCK(stcb);
  4102. } else {
  4103. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4104. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4105. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4106. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4107. SCTP_INP_RLOCK(inp);
  4108. av->assoc_value = (uint32_t)inp->local_strreset_support;
  4109. SCTP_INP_RUNLOCK(inp);
  4110. } else {
  4111. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4112. error = EINVAL;
  4113. }
  4114. }
  4115. if (error == 0) {
  4116. *optsize = sizeof(struct sctp_assoc_value);
  4117. }
  4118. break;
  4119. }
  4120. case SCTP_PR_STREAM_STATUS:
  4121. {
  4122. struct sctp_prstatus *sprstat;
  4123. uint16_t sid;
  4124. uint16_t policy;
  4125. SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
  4126. SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
  4127. sid = sprstat->sprstat_sid;
  4128. policy = sprstat->sprstat_policy;
  4129. #if defined(SCTP_DETAILED_STR_STATS)
  4130. if ((stcb != NULL) &&
  4131. (sid < stcb->asoc.streamoutcnt) &&
  4132. (policy != SCTP_PR_SCTP_NONE) &&
  4133. ((policy <= SCTP_PR_SCTP_MAX) ||
  4134. (policy == SCTP_PR_SCTP_ALL))) {
  4135. if (policy == SCTP_PR_SCTP_ALL) {
  4136. sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
  4137. sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
  4138. } else {
  4139. sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy];
  4140. sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy];
  4141. }
  4142. #else
  4143. if ((stcb != NULL) &&
  4144. (sid < stcb->asoc.streamoutcnt) &&
  4145. (policy == SCTP_PR_SCTP_ALL)) {
  4146. sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
  4147. sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
  4148. #endif
  4149. } else {
  4150. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4151. error = EINVAL;
  4152. }
  4153. if (stcb != NULL) {
  4154. SCTP_TCB_UNLOCK(stcb);
  4155. }
  4156. if (error == 0) {
  4157. *optsize = sizeof(struct sctp_prstatus);
  4158. }
  4159. break;
  4160. }
  4161. case SCTP_PR_ASSOC_STATUS:
  4162. {
  4163. struct sctp_prstatus *sprstat;
  4164. uint16_t policy;
  4165. SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
  4166. SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
  4167. policy = sprstat->sprstat_policy;
  4168. if ((stcb != NULL) &&
  4169. (policy != SCTP_PR_SCTP_NONE) &&
  4170. ((policy <= SCTP_PR_SCTP_MAX) ||
  4171. (policy == SCTP_PR_SCTP_ALL))) {
  4172. if (policy == SCTP_PR_SCTP_ALL) {
  4173. sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0];
  4174. sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0];
  4175. } else {
  4176. sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy];
  4177. sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy];
  4178. }
  4179. } else {
  4180. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4181. error = EINVAL;
  4182. }
  4183. if (stcb != NULL) {
  4184. SCTP_TCB_UNLOCK(stcb);
  4185. }
  4186. if (error == 0) {
  4187. *optsize = sizeof(struct sctp_prstatus);
  4188. }
  4189. break;
  4190. }
  4191. case SCTP_MAX_CWND:
  4192. {
  4193. struct sctp_assoc_value *av;
  4194. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
  4195. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4196. if (stcb) {
  4197. av->assoc_value = stcb->asoc.max_cwnd;
  4198. SCTP_TCB_UNLOCK(stcb);
  4199. } else {
  4200. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4201. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4202. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4203. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4204. SCTP_INP_RLOCK(inp);
  4205. av->assoc_value = inp->max_cwnd;
  4206. SCTP_INP_RUNLOCK(inp);
  4207. } else {
  4208. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4209. error = EINVAL;
  4210. }
  4211. }
  4212. if (error == 0) {
  4213. *optsize = sizeof(struct sctp_assoc_value);
  4214. }
  4215. break;
  4216. }
  4217. default:
  4218. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
  4219. error = ENOPROTOOPT;
  4220. break;
  4221. } /* end switch (sopt->sopt_name) */
  4222. if (error) {
  4223. *optsize = 0;
  4224. }
  4225. return (error);
  4226. }
  4227. #if defined(__Userspace__)
  4228. int
  4229. #else
  4230. static int
  4231. #endif
  4232. sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
  4233. void *p)
  4234. {
  4235. int error, set_opt;
  4236. uint32_t *mopt;
  4237. struct sctp_tcb *stcb = NULL;
  4238. struct sctp_inpcb *inp = NULL;
  4239. uint32_t vrf_id;
  4240. if (optval == NULL) {
  4241. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4242. return (EINVAL);
  4243. }
  4244. inp = (struct sctp_inpcb *)so->so_pcb;
  4245. if (inp == NULL) {
  4246. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4247. return (EINVAL);
  4248. }
  4249. vrf_id = inp->def_vrf_id;
  4250. error = 0;
  4251. switch (optname) {
  4252. case SCTP_NODELAY:
  4253. case SCTP_AUTOCLOSE:
  4254. case SCTP_AUTO_ASCONF:
  4255. case SCTP_EXPLICIT_EOR:
  4256. case SCTP_DISABLE_FRAGMENTS:
  4257. case SCTP_USE_EXT_RCVINFO:
  4258. case SCTP_I_WANT_MAPPED_V4_ADDR:
  4259. /* copy in the option value */
  4260. SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize);
  4261. set_opt = 0;
  4262. if (error)
  4263. break;
  4264. switch (optname) {
  4265. case SCTP_DISABLE_FRAGMENTS:
  4266. set_opt = SCTP_PCB_FLAGS_NO_FRAGMENT;
  4267. break;
  4268. case SCTP_AUTO_ASCONF:
  4269. /*
  4270. * NOTE: we don't really support this flag
  4271. */
  4272. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  4273. /* only valid for bound all sockets */
  4274. if ((SCTP_BASE_SYSCTL(sctp_auto_asconf) == 0) &&
  4275. (*mopt != 0)) {
  4276. /* forbidden by admin */
  4277. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EPERM);
  4278. return (EPERM);
  4279. }
  4280. set_opt = SCTP_PCB_FLAGS_AUTO_ASCONF;
  4281. } else {
  4282. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4283. return (EINVAL);
  4284. }
  4285. break;
  4286. case SCTP_EXPLICIT_EOR:
  4287. set_opt = SCTP_PCB_FLAGS_EXPLICIT_EOR;
  4288. break;
  4289. case SCTP_USE_EXT_RCVINFO:
  4290. set_opt = SCTP_PCB_FLAGS_EXT_RCVINFO;
  4291. break;
  4292. case SCTP_I_WANT_MAPPED_V4_ADDR:
  4293. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  4294. set_opt = SCTP_PCB_FLAGS_NEEDS_MAPPED_V4;
  4295. } else {
  4296. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4297. return (EINVAL);
  4298. }
  4299. break;
  4300. case SCTP_NODELAY:
  4301. set_opt = SCTP_PCB_FLAGS_NODELAY;
  4302. break;
  4303. case SCTP_AUTOCLOSE:
  4304. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4305. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
  4306. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4307. return (EINVAL);
  4308. }
  4309. set_opt = SCTP_PCB_FLAGS_AUTOCLOSE;
  4310. /*
  4311. * The value is in ticks. Note this does not effect
  4312. * old associations, only new ones.
  4313. */
  4314. inp->sctp_ep.auto_close_time = sctp_secs_to_ticks(*mopt);
  4315. break;
  4316. }
  4317. SCTP_INP_WLOCK(inp);
  4318. if (*mopt != 0) {
  4319. sctp_feature_on(inp, set_opt);
  4320. } else {
  4321. sctp_feature_off(inp, set_opt);
  4322. }
  4323. SCTP_INP_WUNLOCK(inp);
  4324. break;
  4325. case SCTP_REUSE_PORT:
  4326. {
  4327. SCTP_CHECK_AND_CAST(mopt, optval, uint32_t, optsize);
  4328. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
  4329. /* Can't set it after we are bound */
  4330. error = EINVAL;
  4331. break;
  4332. }
  4333. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE)) {
  4334. /* Can't do this for a 1-m socket */
  4335. error = EINVAL;
  4336. break;
  4337. }
  4338. if (optval)
  4339. sctp_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE);
  4340. else
  4341. sctp_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE);
  4342. break;
  4343. }
  4344. case SCTP_PARTIAL_DELIVERY_POINT:
  4345. {
  4346. uint32_t *value;
  4347. SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
  4348. if (*value > SCTP_SB_LIMIT_RCV(so)) {
  4349. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4350. error = EINVAL;
  4351. break;
  4352. }
  4353. inp->partial_delivery_point = *value;
  4354. break;
  4355. }
  4356. case SCTP_FRAGMENT_INTERLEAVE:
  4357. /* not yet until we re-write sctp_recvmsg() */
  4358. {
  4359. uint32_t *level;
  4360. SCTP_CHECK_AND_CAST(level, optval, uint32_t, optsize);
  4361. if (*level == SCTP_FRAG_LEVEL_2) {
  4362. sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
  4363. sctp_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
  4364. } else if (*level == SCTP_FRAG_LEVEL_1) {
  4365. sctp_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
  4366. sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
  4367. } else if (*level == SCTP_FRAG_LEVEL_0) {
  4368. sctp_feature_off(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
  4369. sctp_feature_off(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS);
  4370. } else {
  4371. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4372. error = EINVAL;
  4373. }
  4374. break;
  4375. }
  4376. case SCTP_INTERLEAVING_SUPPORTED:
  4377. {
  4378. struct sctp_assoc_value *av;
  4379. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  4380. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4381. if (stcb) {
  4382. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4383. error = EINVAL;
  4384. SCTP_TCB_UNLOCK(stcb);
  4385. } else {
  4386. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4387. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4388. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4389. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  4390. SCTP_INP_WLOCK(inp);
  4391. if (av->assoc_value == 0) {
  4392. inp->idata_supported = 0;
  4393. } else {
  4394. if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE)) &&
  4395. (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS))) {
  4396. inp->idata_supported = 1;
  4397. } else {
  4398. /* Must have Frag interleave and stream interleave on */
  4399. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4400. error = EINVAL;
  4401. }
  4402. }
  4403. SCTP_INP_WUNLOCK(inp);
  4404. } else {
  4405. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4406. error = EINVAL;
  4407. }
  4408. }
  4409. break;
  4410. }
  4411. case SCTP_CMT_ON_OFF:
  4412. if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
  4413. struct sctp_assoc_value *av;
  4414. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  4415. if (av->assoc_value > SCTP_CMT_MAX) {
  4416. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4417. error = EINVAL;
  4418. break;
  4419. }
  4420. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4421. if (stcb) {
  4422. stcb->asoc.sctp_cmt_on_off = av->assoc_value;
  4423. SCTP_TCB_UNLOCK(stcb);
  4424. } else {
  4425. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4426. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4427. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4428. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  4429. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  4430. SCTP_INP_WLOCK(inp);
  4431. inp->sctp_cmt_on_off = av->assoc_value;
  4432. SCTP_INP_WUNLOCK(inp);
  4433. }
  4434. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4435. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  4436. (av->assoc_id == SCTP_ALL_ASSOC))) {
  4437. SCTP_INP_RLOCK(inp);
  4438. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4439. SCTP_TCB_LOCK(stcb);
  4440. stcb->asoc.sctp_cmt_on_off = av->assoc_value;
  4441. SCTP_TCB_UNLOCK(stcb);
  4442. }
  4443. SCTP_INP_RUNLOCK(inp);
  4444. }
  4445. }
  4446. } else {
  4447. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
  4448. error = ENOPROTOOPT;
  4449. }
  4450. break;
  4451. case SCTP_PLUGGABLE_CC:
  4452. {
  4453. struct sctp_assoc_value *av;
  4454. struct sctp_nets *net;
  4455. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  4456. if ((av->assoc_value != SCTP_CC_RFC2581) &&
  4457. (av->assoc_value != SCTP_CC_HSTCP) &&
  4458. (av->assoc_value != SCTP_CC_HTCP) &&
  4459. (av->assoc_value != SCTP_CC_RTCC)) {
  4460. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4461. error = EINVAL;
  4462. break;
  4463. }
  4464. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4465. if (stcb) {
  4466. stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value];
  4467. stcb->asoc.congestion_control_module = av->assoc_value;
  4468. if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) {
  4469. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  4470. stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
  4471. }
  4472. }
  4473. SCTP_TCB_UNLOCK(stcb);
  4474. } else {
  4475. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4476. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4477. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4478. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  4479. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  4480. SCTP_INP_WLOCK(inp);
  4481. inp->sctp_ep.sctp_default_cc_module = av->assoc_value;
  4482. SCTP_INP_WUNLOCK(inp);
  4483. }
  4484. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4485. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  4486. (av->assoc_id == SCTP_ALL_ASSOC))) {
  4487. SCTP_INP_RLOCK(inp);
  4488. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4489. SCTP_TCB_LOCK(stcb);
  4490. stcb->asoc.cc_functions = sctp_cc_functions[av->assoc_value];
  4491. stcb->asoc.congestion_control_module = av->assoc_value;
  4492. if (stcb->asoc.cc_functions.sctp_set_initial_cc_param != NULL) {
  4493. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  4494. stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
  4495. }
  4496. }
  4497. SCTP_TCB_UNLOCK(stcb);
  4498. }
  4499. SCTP_INP_RUNLOCK(inp);
  4500. }
  4501. }
  4502. break;
  4503. }
  4504. case SCTP_CC_OPTION:
  4505. {
  4506. struct sctp_cc_option *cc_opt;
  4507. SCTP_CHECK_AND_CAST(cc_opt, optval, struct sctp_cc_option, optsize);
  4508. SCTP_FIND_STCB(inp, stcb, cc_opt->aid_value.assoc_id);
  4509. if (stcb == NULL) {
  4510. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4511. (cc_opt->aid_value.assoc_id == SCTP_CURRENT_ASSOC)) {
  4512. SCTP_INP_RLOCK(inp);
  4513. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4514. SCTP_TCB_LOCK(stcb);
  4515. if (stcb->asoc.cc_functions.sctp_cwnd_socket_option) {
  4516. (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1, cc_opt);
  4517. }
  4518. SCTP_TCB_UNLOCK(stcb);
  4519. }
  4520. SCTP_INP_RUNLOCK(inp);
  4521. } else {
  4522. error = EINVAL;
  4523. }
  4524. } else {
  4525. if (stcb->asoc.cc_functions.sctp_cwnd_socket_option == NULL) {
  4526. error = ENOTSUP;
  4527. } else {
  4528. error = (*stcb->asoc.cc_functions.sctp_cwnd_socket_option)(stcb, 1,
  4529. cc_opt);
  4530. }
  4531. SCTP_TCB_UNLOCK(stcb);
  4532. }
  4533. break;
  4534. }
  4535. case SCTP_PLUGGABLE_SS:
  4536. {
  4537. struct sctp_assoc_value *av;
  4538. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  4539. if ((av->assoc_value != SCTP_SS_DEFAULT) &&
  4540. (av->assoc_value != SCTP_SS_ROUND_ROBIN) &&
  4541. (av->assoc_value != SCTP_SS_ROUND_ROBIN_PACKET) &&
  4542. (av->assoc_value != SCTP_SS_PRIORITY) &&
  4543. (av->assoc_value != SCTP_SS_FAIR_BANDWITH) &&
  4544. (av->assoc_value != SCTP_SS_FIRST_COME)) {
  4545. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4546. error = EINVAL;
  4547. break;
  4548. }
  4549. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4550. if (stcb) {
  4551. stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
  4552. stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
  4553. stcb->asoc.stream_scheduling_module = av->assoc_value;
  4554. stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
  4555. SCTP_TCB_UNLOCK(stcb);
  4556. } else {
  4557. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4558. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4559. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4560. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  4561. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  4562. SCTP_INP_WLOCK(inp);
  4563. inp->sctp_ep.sctp_default_ss_module = av->assoc_value;
  4564. SCTP_INP_WUNLOCK(inp);
  4565. }
  4566. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4567. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  4568. (av->assoc_id == SCTP_ALL_ASSOC))) {
  4569. SCTP_INP_RLOCK(inp);
  4570. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4571. SCTP_TCB_LOCK(stcb);
  4572. stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
  4573. stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
  4574. stcb->asoc.stream_scheduling_module = av->assoc_value;
  4575. stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
  4576. SCTP_TCB_UNLOCK(stcb);
  4577. }
  4578. SCTP_INP_RUNLOCK(inp);
  4579. }
  4580. }
  4581. break;
  4582. }
  4583. case SCTP_SS_VALUE:
  4584. {
  4585. struct sctp_stream_value *av;
  4586. SCTP_CHECK_AND_CAST(av, optval, struct sctp_stream_value, optsize);
  4587. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4588. if (stcb) {
  4589. if ((av->stream_id >= stcb->asoc.streamoutcnt) ||
  4590. (stcb->asoc.ss_functions.sctp_ss_set_value(stcb, &stcb->asoc, &stcb->asoc.strmout[av->stream_id],
  4591. av->stream_value) < 0)) {
  4592. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4593. error = EINVAL;
  4594. }
  4595. SCTP_TCB_UNLOCK(stcb);
  4596. } else {
  4597. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4598. (av->assoc_id == SCTP_CURRENT_ASSOC)) {
  4599. SCTP_INP_RLOCK(inp);
  4600. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4601. SCTP_TCB_LOCK(stcb);
  4602. if (av->stream_id < stcb->asoc.streamoutcnt) {
  4603. stcb->asoc.ss_functions.sctp_ss_set_value(stcb,
  4604. &stcb->asoc,
  4605. &stcb->asoc.strmout[av->stream_id],
  4606. av->stream_value);
  4607. }
  4608. SCTP_TCB_UNLOCK(stcb);
  4609. }
  4610. SCTP_INP_RUNLOCK(inp);
  4611. } else {
  4612. /* Can't set stream value without association */
  4613. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4614. error = EINVAL;
  4615. }
  4616. }
  4617. break;
  4618. }
  4619. case SCTP_CLR_STAT_LOG:
  4620. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  4621. error = EOPNOTSUPP;
  4622. break;
  4623. case SCTP_CONTEXT:
  4624. {
  4625. struct sctp_assoc_value *av;
  4626. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  4627. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  4628. if (stcb) {
  4629. stcb->asoc.context = av->assoc_value;
  4630. SCTP_TCB_UNLOCK(stcb);
  4631. } else {
  4632. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4633. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4634. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4635. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  4636. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  4637. SCTP_INP_WLOCK(inp);
  4638. inp->sctp_context = av->assoc_value;
  4639. SCTP_INP_WUNLOCK(inp);
  4640. }
  4641. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4642. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  4643. (av->assoc_id == SCTP_ALL_ASSOC))) {
  4644. SCTP_INP_RLOCK(inp);
  4645. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4646. SCTP_TCB_LOCK(stcb);
  4647. stcb->asoc.context = av->assoc_value;
  4648. SCTP_TCB_UNLOCK(stcb);
  4649. }
  4650. SCTP_INP_RUNLOCK(inp);
  4651. }
  4652. }
  4653. break;
  4654. }
  4655. case SCTP_VRF_ID:
  4656. {
  4657. uint32_t *default_vrfid;
  4658. #ifdef SCTP_MVRF
  4659. int i;
  4660. #endif
  4661. SCTP_CHECK_AND_CAST(default_vrfid, optval, uint32_t, optsize);
  4662. if (*default_vrfid > SCTP_MAX_VRF_ID) {
  4663. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4664. error = EINVAL;
  4665. break;
  4666. }
  4667. #ifdef SCTP_MVRF
  4668. for (i = 0; i < inp->num_vrfs; i++) {
  4669. /* The VRF must be in the VRF list */
  4670. if (*default_vrfid == inp->m_vrf_ids[i]) {
  4671. SCTP_INP_WLOCK(inp);
  4672. inp->def_vrf_id = *default_vrfid;
  4673. SCTP_INP_WUNLOCK(inp);
  4674. goto sctp_done;
  4675. }
  4676. }
  4677. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4678. error = EINVAL;
  4679. #else
  4680. inp->def_vrf_id = *default_vrfid;
  4681. #endif
  4682. #ifdef SCTP_MVRF
  4683. sctp_done:
  4684. #endif
  4685. break;
  4686. }
  4687. case SCTP_DEL_VRF_ID:
  4688. {
  4689. #ifdef SCTP_MVRF
  4690. uint32_t *del_vrfid;
  4691. int i, fnd = 0;
  4692. SCTP_CHECK_AND_CAST(del_vrfid, optval, uint32_t, optsize);
  4693. if (*del_vrfid > SCTP_MAX_VRF_ID) {
  4694. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4695. error = EINVAL;
  4696. break;
  4697. }
  4698. if (inp->num_vrfs == 1) {
  4699. /* Can't delete last one */
  4700. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4701. error = EINVAL;
  4702. break;
  4703. }
  4704. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
  4705. /* Can't add more once you are bound */
  4706. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4707. error = EINVAL;
  4708. break;
  4709. }
  4710. SCTP_INP_WLOCK(inp);
  4711. for (i = 0; i < inp->num_vrfs; i++) {
  4712. if (*del_vrfid == inp->m_vrf_ids[i]) {
  4713. fnd = 1;
  4714. break;
  4715. }
  4716. }
  4717. if (!fnd) {
  4718. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4719. error = EINVAL;
  4720. break;
  4721. }
  4722. if (i != (inp->num_vrfs - 1)) {
  4723. /* Take bottom one and move to this slot */
  4724. inp->m_vrf_ids[i] = inp->m_vrf_ids[(inp->num_vrfs-1)];
  4725. }
  4726. if (*del_vrfid == inp->def_vrf_id) {
  4727. /* Take the first one as the new default */
  4728. inp->def_vrf_id = inp->m_vrf_ids[0];
  4729. }
  4730. /* Drop the number by one killing last one */
  4731. inp->num_vrfs--;
  4732. #else
  4733. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  4734. error = EOPNOTSUPP;
  4735. #endif
  4736. break;
  4737. }
  4738. case SCTP_ADD_VRF_ID:
  4739. {
  4740. #ifdef SCTP_MVRF
  4741. uint32_t *add_vrfid;
  4742. int i;
  4743. SCTP_CHECK_AND_CAST(add_vrfid, optval, uint32_t, optsize);
  4744. if (*add_vrfid > SCTP_MAX_VRF_ID) {
  4745. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4746. error = EINVAL;
  4747. break;
  4748. }
  4749. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 0) {
  4750. /* Can't add more once you are bound */
  4751. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4752. error = EINVAL;
  4753. break;
  4754. }
  4755. SCTP_INP_WLOCK(inp);
  4756. /* Verify its not already here */
  4757. for (i = 0; i < inp->num_vrfs; i++) {
  4758. if (*add_vrfid == inp->m_vrf_ids[i]) {
  4759. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  4760. error = EALREADY;
  4761. SCTP_INP_WUNLOCK(inp);
  4762. break;
  4763. }
  4764. }
  4765. if ((inp->num_vrfs + 1) > inp->vrf_size) {
  4766. /* need to grow array */
  4767. uint32_t *tarray;
  4768. SCTP_MALLOC(tarray, uint32_t *,
  4769. (sizeof(uint32_t) * (inp->vrf_size + SCTP_DEFAULT_VRF_SIZE)),
  4770. SCTP_M_MVRF);
  4771. if (tarray == NULL) {
  4772. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  4773. error = ENOMEM;
  4774. SCTP_INP_WUNLOCK(inp);
  4775. break;
  4776. }
  4777. memcpy(tarray, inp->m_vrf_ids, (sizeof(uint32_t) * inp->vrf_size));
  4778. SCTP_FREE(inp->m_vrf_ids, SCTP_M_MVRF);
  4779. inp->m_vrf_ids = tarray;
  4780. inp->vrf_size += SCTP_DEFAULT_VRF_SIZE;
  4781. }
  4782. inp->m_vrf_ids[inp->num_vrfs] = *add_vrfid;
  4783. inp->num_vrfs++;
  4784. SCTP_INP_WUNLOCK(inp);
  4785. #else
  4786. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  4787. error = EOPNOTSUPP;
  4788. #endif
  4789. break;
  4790. }
  4791. case SCTP_DELAYED_SACK:
  4792. {
  4793. struct sctp_sack_info *sack;
  4794. SCTP_CHECK_AND_CAST(sack, optval, struct sctp_sack_info, optsize);
  4795. SCTP_FIND_STCB(inp, stcb, sack->sack_assoc_id);
  4796. if (sack->sack_delay) {
  4797. if (sack->sack_delay > SCTP_MAX_SACK_DELAY) {
  4798. error = EINVAL;
  4799. if (stcb != NULL) {
  4800. SCTP_TCB_UNLOCK(stcb);
  4801. }
  4802. break;
  4803. }
  4804. }
  4805. if (stcb) {
  4806. if (sack->sack_delay) {
  4807. stcb->asoc.delayed_ack = sack->sack_delay;
  4808. }
  4809. if (sack->sack_freq) {
  4810. stcb->asoc.sack_freq = sack->sack_freq;
  4811. }
  4812. SCTP_TCB_UNLOCK(stcb);
  4813. } else {
  4814. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4815. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4816. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4817. ((sack->sack_assoc_id == SCTP_FUTURE_ASSOC) ||
  4818. (sack->sack_assoc_id == SCTP_ALL_ASSOC)))) {
  4819. SCTP_INP_WLOCK(inp);
  4820. if (sack->sack_delay) {
  4821. inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV] = sctp_msecs_to_ticks(sack->sack_delay);
  4822. }
  4823. if (sack->sack_freq) {
  4824. inp->sctp_ep.sctp_sack_freq = sack->sack_freq;
  4825. }
  4826. SCTP_INP_WUNLOCK(inp);
  4827. }
  4828. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4829. ((sack->sack_assoc_id == SCTP_CURRENT_ASSOC) ||
  4830. (sack->sack_assoc_id == SCTP_ALL_ASSOC))) {
  4831. SCTP_INP_RLOCK(inp);
  4832. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4833. SCTP_TCB_LOCK(stcb);
  4834. if (sack->sack_delay) {
  4835. stcb->asoc.delayed_ack = sack->sack_delay;
  4836. }
  4837. if (sack->sack_freq) {
  4838. stcb->asoc.sack_freq = sack->sack_freq;
  4839. }
  4840. SCTP_TCB_UNLOCK(stcb);
  4841. }
  4842. SCTP_INP_RUNLOCK(inp);
  4843. }
  4844. }
  4845. break;
  4846. }
  4847. case SCTP_AUTH_CHUNK:
  4848. {
  4849. struct sctp_authchunk *sauth;
  4850. SCTP_CHECK_AND_CAST(sauth, optval, struct sctp_authchunk, optsize);
  4851. SCTP_INP_WLOCK(inp);
  4852. if (sctp_auth_add_chunk(sauth->sauth_chunk, inp->sctp_ep.local_auth_chunks)) {
  4853. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4854. error = EINVAL;
  4855. } else {
  4856. inp->auth_supported = 1;
  4857. }
  4858. SCTP_INP_WUNLOCK(inp);
  4859. break;
  4860. }
  4861. case SCTP_AUTH_KEY:
  4862. {
  4863. struct sctp_authkey *sca;
  4864. struct sctp_keyhead *shared_keys;
  4865. sctp_sharedkey_t *shared_key;
  4866. sctp_key_t *key = NULL;
  4867. size_t size;
  4868. SCTP_CHECK_AND_CAST(sca, optval, struct sctp_authkey, optsize);
  4869. if (sca->sca_keylength == 0) {
  4870. size = optsize - sizeof(struct sctp_authkey);
  4871. } else {
  4872. if (sca->sca_keylength + sizeof(struct sctp_authkey) <= optsize) {
  4873. size = sca->sca_keylength;
  4874. } else {
  4875. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4876. error = EINVAL;
  4877. break;
  4878. }
  4879. }
  4880. SCTP_FIND_STCB(inp, stcb, sca->sca_assoc_id);
  4881. if (stcb) {
  4882. shared_keys = &stcb->asoc.shared_keys;
  4883. /* clear the cached keys for this key id */
  4884. sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
  4885. /*
  4886. * create the new shared key and
  4887. * insert/replace it
  4888. */
  4889. if (size > 0) {
  4890. key = sctp_set_key(sca->sca_key, (uint32_t) size);
  4891. if (key == NULL) {
  4892. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  4893. error = ENOMEM;
  4894. SCTP_TCB_UNLOCK(stcb);
  4895. break;
  4896. }
  4897. }
  4898. shared_key = sctp_alloc_sharedkey();
  4899. if (shared_key == NULL) {
  4900. sctp_free_key(key);
  4901. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  4902. error = ENOMEM;
  4903. SCTP_TCB_UNLOCK(stcb);
  4904. break;
  4905. }
  4906. shared_key->key = key;
  4907. shared_key->keyid = sca->sca_keynumber;
  4908. error = sctp_insert_sharedkey(shared_keys, shared_key);
  4909. SCTP_TCB_UNLOCK(stcb);
  4910. } else {
  4911. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  4912. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  4913. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4914. ((sca->sca_assoc_id == SCTP_FUTURE_ASSOC) ||
  4915. (sca->sca_assoc_id == SCTP_ALL_ASSOC)))) {
  4916. SCTP_INP_WLOCK(inp);
  4917. shared_keys = &inp->sctp_ep.shared_keys;
  4918. /*
  4919. * clear the cached keys on all assocs for
  4920. * this key id
  4921. */
  4922. sctp_clear_cachedkeys_ep(inp, sca->sca_keynumber);
  4923. /*
  4924. * create the new shared key and
  4925. * insert/replace it
  4926. */
  4927. if (size > 0) {
  4928. key = sctp_set_key(sca->sca_key, (uint32_t) size);
  4929. if (key == NULL) {
  4930. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  4931. error = ENOMEM;
  4932. SCTP_INP_WUNLOCK(inp);
  4933. break;
  4934. }
  4935. }
  4936. shared_key = sctp_alloc_sharedkey();
  4937. if (shared_key == NULL) {
  4938. sctp_free_key(key);
  4939. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  4940. error = ENOMEM;
  4941. SCTP_INP_WUNLOCK(inp);
  4942. break;
  4943. }
  4944. shared_key->key = key;
  4945. shared_key->keyid = sca->sca_keynumber;
  4946. error = sctp_insert_sharedkey(shared_keys, shared_key);
  4947. SCTP_INP_WUNLOCK(inp);
  4948. }
  4949. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  4950. ((sca->sca_assoc_id == SCTP_CURRENT_ASSOC) ||
  4951. (sca->sca_assoc_id == SCTP_ALL_ASSOC))) {
  4952. SCTP_INP_RLOCK(inp);
  4953. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  4954. SCTP_TCB_LOCK(stcb);
  4955. shared_keys = &stcb->asoc.shared_keys;
  4956. /* clear the cached keys for this key id */
  4957. sctp_clear_cachedkeys(stcb, sca->sca_keynumber);
  4958. /*
  4959. * create the new shared key and
  4960. * insert/replace it
  4961. */
  4962. if (size > 0) {
  4963. key = sctp_set_key(sca->sca_key, (uint32_t) size);
  4964. if (key == NULL) {
  4965. SCTP_TCB_UNLOCK(stcb);
  4966. continue;
  4967. }
  4968. }
  4969. shared_key = sctp_alloc_sharedkey();
  4970. if (shared_key == NULL) {
  4971. sctp_free_key(key);
  4972. SCTP_TCB_UNLOCK(stcb);
  4973. continue;
  4974. }
  4975. shared_key->key = key;
  4976. shared_key->keyid = sca->sca_keynumber;
  4977. error = sctp_insert_sharedkey(shared_keys, shared_key);
  4978. SCTP_TCB_UNLOCK(stcb);
  4979. }
  4980. SCTP_INP_RUNLOCK(inp);
  4981. }
  4982. }
  4983. break;
  4984. }
  4985. case SCTP_HMAC_IDENT:
  4986. {
  4987. struct sctp_hmacalgo *shmac;
  4988. sctp_hmaclist_t *hmaclist;
  4989. uint16_t hmacid;
  4990. uint32_t i;
  4991. SCTP_CHECK_AND_CAST(shmac, optval, struct sctp_hmacalgo, optsize);
  4992. if ((optsize < sizeof(struct sctp_hmacalgo) + shmac->shmac_number_of_idents * sizeof(uint16_t)) ||
  4993. (shmac->shmac_number_of_idents > 0xffff)) {
  4994. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  4995. error = EINVAL;
  4996. break;
  4997. }
  4998. hmaclist = sctp_alloc_hmaclist((uint16_t)shmac->shmac_number_of_idents);
  4999. if (hmaclist == NULL) {
  5000. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  5001. error = ENOMEM;
  5002. break;
  5003. }
  5004. for (i = 0; i < shmac->shmac_number_of_idents; i++) {
  5005. hmacid = shmac->shmac_idents[i];
  5006. if (sctp_auth_add_hmacid(hmaclist, hmacid)) {
  5007. /* invalid HMACs were found */;
  5008. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5009. error = EINVAL;
  5010. sctp_free_hmaclist(hmaclist);
  5011. goto sctp_set_hmac_done;
  5012. }
  5013. }
  5014. for (i = 0; i < hmaclist->num_algo; i++) {
  5015. if (hmaclist->hmac[i] == SCTP_AUTH_HMAC_ID_SHA1) {
  5016. /* already in list */
  5017. break;
  5018. }
  5019. }
  5020. if (i == hmaclist->num_algo) {
  5021. /* not found in list */
  5022. sctp_free_hmaclist(hmaclist);
  5023. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5024. error = EINVAL;
  5025. break;
  5026. }
  5027. /* set it on the endpoint */
  5028. SCTP_INP_WLOCK(inp);
  5029. if (inp->sctp_ep.local_hmacs)
  5030. sctp_free_hmaclist(inp->sctp_ep.local_hmacs);
  5031. inp->sctp_ep.local_hmacs = hmaclist;
  5032. SCTP_INP_WUNLOCK(inp);
  5033. sctp_set_hmac_done:
  5034. break;
  5035. }
  5036. case SCTP_AUTH_ACTIVE_KEY:
  5037. {
  5038. struct sctp_authkeyid *scact;
  5039. SCTP_CHECK_AND_CAST(scact, optval, struct sctp_authkeyid, optsize);
  5040. SCTP_FIND_STCB(inp, stcb, scact->scact_assoc_id);
  5041. /* set the active key on the right place */
  5042. if (stcb) {
  5043. /* set the active key on the assoc */
  5044. if (sctp_auth_setactivekey(stcb,
  5045. scact->scact_keynumber)) {
  5046. SCTP_LTRACE_ERR_RET(inp, NULL, NULL,
  5047. SCTP_FROM_SCTP_USRREQ,
  5048. EINVAL);
  5049. error = EINVAL;
  5050. }
  5051. SCTP_TCB_UNLOCK(stcb);
  5052. } else {
  5053. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5054. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5055. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5056. ((scact->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
  5057. (scact->scact_assoc_id == SCTP_ALL_ASSOC)))) {
  5058. SCTP_INP_WLOCK(inp);
  5059. if (sctp_auth_setactivekey_ep(inp, scact->scact_keynumber)) {
  5060. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5061. error = EINVAL;
  5062. }
  5063. SCTP_INP_WUNLOCK(inp);
  5064. }
  5065. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5066. ((scact->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
  5067. (scact->scact_assoc_id == SCTP_ALL_ASSOC))) {
  5068. SCTP_INP_RLOCK(inp);
  5069. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5070. SCTP_TCB_LOCK(stcb);
  5071. sctp_auth_setactivekey(stcb, scact->scact_keynumber);
  5072. SCTP_TCB_UNLOCK(stcb);
  5073. }
  5074. SCTP_INP_RUNLOCK(inp);
  5075. }
  5076. }
  5077. break;
  5078. }
  5079. case SCTP_AUTH_DELETE_KEY:
  5080. {
  5081. struct sctp_authkeyid *scdel;
  5082. SCTP_CHECK_AND_CAST(scdel, optval, struct sctp_authkeyid, optsize);
  5083. SCTP_FIND_STCB(inp, stcb, scdel->scact_assoc_id);
  5084. /* delete the key from the right place */
  5085. if (stcb) {
  5086. if (sctp_delete_sharedkey(stcb, scdel->scact_keynumber)) {
  5087. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5088. error = EINVAL;
  5089. }
  5090. SCTP_TCB_UNLOCK(stcb);
  5091. } else {
  5092. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5093. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5094. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5095. ((scdel->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
  5096. (scdel->scact_assoc_id == SCTP_ALL_ASSOC)))) {
  5097. SCTP_INP_WLOCK(inp);
  5098. if (sctp_delete_sharedkey_ep(inp, scdel->scact_keynumber)) {
  5099. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5100. error = EINVAL;
  5101. }
  5102. SCTP_INP_WUNLOCK(inp);
  5103. }
  5104. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5105. ((scdel->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
  5106. (scdel->scact_assoc_id == SCTP_ALL_ASSOC))) {
  5107. SCTP_INP_RLOCK(inp);
  5108. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5109. SCTP_TCB_LOCK(stcb);
  5110. sctp_delete_sharedkey(stcb, scdel->scact_keynumber);
  5111. SCTP_TCB_UNLOCK(stcb);
  5112. }
  5113. SCTP_INP_RUNLOCK(inp);
  5114. }
  5115. }
  5116. break;
  5117. }
  5118. case SCTP_AUTH_DEACTIVATE_KEY:
  5119. {
  5120. struct sctp_authkeyid *keyid;
  5121. SCTP_CHECK_AND_CAST(keyid, optval, struct sctp_authkeyid, optsize);
  5122. SCTP_FIND_STCB(inp, stcb, keyid->scact_assoc_id);
  5123. /* deactivate the key from the right place */
  5124. if (stcb) {
  5125. if (sctp_deact_sharedkey(stcb, keyid->scact_keynumber)) {
  5126. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5127. error = EINVAL;
  5128. }
  5129. SCTP_TCB_UNLOCK(stcb);
  5130. } else {
  5131. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5132. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5133. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5134. ((keyid->scact_assoc_id == SCTP_FUTURE_ASSOC) ||
  5135. (keyid->scact_assoc_id == SCTP_ALL_ASSOC)))) {
  5136. SCTP_INP_WLOCK(inp);
  5137. if (sctp_deact_sharedkey_ep(inp, keyid->scact_keynumber)) {
  5138. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5139. error = EINVAL;
  5140. }
  5141. SCTP_INP_WUNLOCK(inp);
  5142. }
  5143. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5144. ((keyid->scact_assoc_id == SCTP_CURRENT_ASSOC) ||
  5145. (keyid->scact_assoc_id == SCTP_ALL_ASSOC))) {
  5146. SCTP_INP_RLOCK(inp);
  5147. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5148. SCTP_TCB_LOCK(stcb);
  5149. sctp_deact_sharedkey(stcb, keyid->scact_keynumber);
  5150. SCTP_TCB_UNLOCK(stcb);
  5151. }
  5152. SCTP_INP_RUNLOCK(inp);
  5153. }
  5154. }
  5155. break;
  5156. }
  5157. case SCTP_ENABLE_STREAM_RESET:
  5158. {
  5159. struct sctp_assoc_value *av;
  5160. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  5161. if (av->assoc_value & (~SCTP_ENABLE_VALUE_MASK)) {
  5162. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5163. error = EINVAL;
  5164. break;
  5165. }
  5166. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  5167. if (stcb) {
  5168. stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value;
  5169. SCTP_TCB_UNLOCK(stcb);
  5170. } else {
  5171. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5172. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5173. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5174. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  5175. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  5176. SCTP_INP_WLOCK(inp);
  5177. inp->local_strreset_support = (uint8_t)av->assoc_value;
  5178. SCTP_INP_WUNLOCK(inp);
  5179. }
  5180. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5181. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  5182. (av->assoc_id == SCTP_ALL_ASSOC))) {
  5183. SCTP_INP_RLOCK(inp);
  5184. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5185. SCTP_TCB_LOCK(stcb);
  5186. stcb->asoc.local_strreset_support = (uint8_t)av->assoc_value;
  5187. SCTP_TCB_UNLOCK(stcb);
  5188. }
  5189. SCTP_INP_RUNLOCK(inp);
  5190. }
  5191. }
  5192. break;
  5193. }
  5194. case SCTP_RESET_STREAMS:
  5195. {
  5196. struct sctp_reset_streams *strrst;
  5197. int i, send_out = 0;
  5198. int send_in = 0;
  5199. SCTP_CHECK_AND_CAST(strrst, optval, struct sctp_reset_streams, optsize);
  5200. SCTP_FIND_STCB(inp, stcb, strrst->srs_assoc_id);
  5201. if (stcb == NULL) {
  5202. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  5203. error = ENOENT;
  5204. break;
  5205. }
  5206. if (stcb->asoc.reconfig_supported == 0) {
  5207. /*
  5208. * Peer does not support the chunk type.
  5209. */
  5210. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  5211. error = EOPNOTSUPP;
  5212. SCTP_TCB_UNLOCK(stcb);
  5213. break;
  5214. }
  5215. if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
  5216. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5217. error = EINVAL;
  5218. SCTP_TCB_UNLOCK(stcb);
  5219. break;
  5220. }
  5221. if (sizeof(struct sctp_reset_streams) +
  5222. strrst->srs_number_streams * sizeof(uint16_t) > optsize) {
  5223. error = EINVAL;
  5224. SCTP_TCB_UNLOCK(stcb);
  5225. break;
  5226. }
  5227. if (strrst->srs_flags & SCTP_STREAM_RESET_INCOMING) {
  5228. send_in = 1;
  5229. if (stcb->asoc.stream_reset_outstanding) {
  5230. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  5231. error = EALREADY;
  5232. SCTP_TCB_UNLOCK(stcb);
  5233. break;
  5234. }
  5235. }
  5236. if (strrst->srs_flags & SCTP_STREAM_RESET_OUTGOING) {
  5237. send_out = 1;
  5238. }
  5239. if ((strrst->srs_number_streams > SCTP_MAX_STREAMS_AT_ONCE_RESET) && send_in) {
  5240. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOMEM);
  5241. error = ENOMEM;
  5242. SCTP_TCB_UNLOCK(stcb);
  5243. break;
  5244. }
  5245. if ((send_in == 0) && (send_out == 0)) {
  5246. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5247. error = EINVAL;
  5248. SCTP_TCB_UNLOCK(stcb);
  5249. break;
  5250. }
  5251. for (i = 0; i < strrst->srs_number_streams; i++) {
  5252. if ((send_in) &&
  5253. (strrst->srs_stream_list[i] >= stcb->asoc.streamincnt)) {
  5254. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5255. error = EINVAL;
  5256. break;
  5257. }
  5258. if ((send_out) &&
  5259. (strrst->srs_stream_list[i] >= stcb->asoc.streamoutcnt)) {
  5260. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5261. error = EINVAL;
  5262. break;
  5263. }
  5264. }
  5265. if (error) {
  5266. SCTP_TCB_UNLOCK(stcb);
  5267. break;
  5268. }
  5269. if (send_out) {
  5270. int cnt;
  5271. uint16_t strm;
  5272. if (strrst->srs_number_streams) {
  5273. for (i = 0, cnt = 0; i < strrst->srs_number_streams; i++) {
  5274. strm = strrst->srs_stream_list[i];
  5275. if (stcb->asoc.strmout[strm].state == SCTP_STREAM_OPEN) {
  5276. stcb->asoc.strmout[strm].state = SCTP_STREAM_RESET_PENDING;
  5277. cnt++;
  5278. }
  5279. }
  5280. } else {
  5281. /* Its all */
  5282. for (i = 0, cnt = 0; i < stcb->asoc.streamoutcnt; i++) {
  5283. if (stcb->asoc.strmout[i].state == SCTP_STREAM_OPEN) {
  5284. stcb->asoc.strmout[i].state = SCTP_STREAM_RESET_PENDING;
  5285. cnt++;
  5286. }
  5287. }
  5288. }
  5289. }
  5290. if (send_in) {
  5291. error = sctp_send_str_reset_req(stcb, strrst->srs_number_streams,
  5292. strrst->srs_stream_list,
  5293. send_in, 0, 0, 0, 0, 0);
  5294. } else {
  5295. error = sctp_send_stream_reset_out_if_possible(stcb, SCTP_SO_LOCKED);
  5296. }
  5297. if (error == 0) {
  5298. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
  5299. } else {
  5300. /*
  5301. * For outgoing streams don't report any problems in
  5302. * sending the request to the application.
  5303. * XXX: Double check resetting incoming streams.
  5304. */
  5305. error = 0;
  5306. }
  5307. SCTP_TCB_UNLOCK(stcb);
  5308. break;
  5309. }
  5310. case SCTP_ADD_STREAMS:
  5311. {
  5312. struct sctp_add_streams *stradd;
  5313. uint8_t addstream = 0;
  5314. uint16_t add_o_strmcnt = 0;
  5315. uint16_t add_i_strmcnt = 0;
  5316. SCTP_CHECK_AND_CAST(stradd, optval, struct sctp_add_streams, optsize);
  5317. SCTP_FIND_STCB(inp, stcb, stradd->sas_assoc_id);
  5318. if (stcb == NULL) {
  5319. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  5320. error = ENOENT;
  5321. break;
  5322. }
  5323. if (stcb->asoc.reconfig_supported == 0) {
  5324. /*
  5325. * Peer does not support the chunk type.
  5326. */
  5327. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  5328. error = EOPNOTSUPP;
  5329. SCTP_TCB_UNLOCK(stcb);
  5330. break;
  5331. }
  5332. if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
  5333. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5334. error = EINVAL;
  5335. SCTP_TCB_UNLOCK(stcb);
  5336. break;
  5337. }
  5338. if (stcb->asoc.stream_reset_outstanding) {
  5339. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  5340. error = EALREADY;
  5341. SCTP_TCB_UNLOCK(stcb);
  5342. break;
  5343. }
  5344. if ((stradd->sas_outstrms == 0) &&
  5345. (stradd->sas_instrms == 0)) {
  5346. error = EINVAL;
  5347. goto skip_stuff;
  5348. }
  5349. if (stradd->sas_outstrms) {
  5350. addstream = 1;
  5351. /* We allocate here */
  5352. add_o_strmcnt = stradd->sas_outstrms;
  5353. if ((((int)add_o_strmcnt) + ((int)stcb->asoc.streamoutcnt)) > 0x0000ffff) {
  5354. /* You can't have more than 64k */
  5355. error = EINVAL;
  5356. goto skip_stuff;
  5357. }
  5358. }
  5359. if (stradd->sas_instrms) {
  5360. int cnt;
  5361. addstream |= 2;
  5362. /* We allocate inside sctp_send_str_reset_req() */
  5363. add_i_strmcnt = stradd->sas_instrms;
  5364. cnt = add_i_strmcnt;
  5365. cnt += stcb->asoc.streamincnt;
  5366. if (cnt > 0x0000ffff) {
  5367. /* You can't have more than 64k */
  5368. error = EINVAL;
  5369. goto skip_stuff;
  5370. }
  5371. if (cnt > (int)stcb->asoc.max_inbound_streams) {
  5372. /* More than you are allowed */
  5373. error = EINVAL;
  5374. goto skip_stuff;
  5375. }
  5376. }
  5377. error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 0, addstream, add_o_strmcnt, add_i_strmcnt, 0);
  5378. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
  5379. skip_stuff:
  5380. SCTP_TCB_UNLOCK(stcb);
  5381. break;
  5382. }
  5383. case SCTP_RESET_ASSOC:
  5384. {
  5385. int i;
  5386. uint32_t *value;
  5387. SCTP_CHECK_AND_CAST(value, optval, uint32_t, optsize);
  5388. SCTP_FIND_STCB(inp, stcb, (sctp_assoc_t) *value);
  5389. if (stcb == NULL) {
  5390. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  5391. error = ENOENT;
  5392. break;
  5393. }
  5394. if (stcb->asoc.reconfig_supported == 0) {
  5395. /*
  5396. * Peer does not support the chunk type.
  5397. */
  5398. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  5399. error = EOPNOTSUPP;
  5400. SCTP_TCB_UNLOCK(stcb);
  5401. break;
  5402. }
  5403. if (SCTP_GET_STATE(stcb) != SCTP_STATE_OPEN) {
  5404. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5405. error = EINVAL;
  5406. SCTP_TCB_UNLOCK(stcb);
  5407. break;
  5408. }
  5409. if (stcb->asoc.stream_reset_outstanding) {
  5410. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  5411. error = EALREADY;
  5412. SCTP_TCB_UNLOCK(stcb);
  5413. break;
  5414. }
  5415. /* Is there any data pending in the send or sent queues? */
  5416. if (!TAILQ_EMPTY(&stcb->asoc.send_queue) ||
  5417. !TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
  5418. busy_out:
  5419. error = EBUSY;
  5420. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  5421. SCTP_TCB_UNLOCK(stcb);
  5422. break;
  5423. }
  5424. /* Do any streams have data queued? */
  5425. for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
  5426. if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
  5427. goto busy_out;
  5428. }
  5429. }
  5430. error = sctp_send_str_reset_req(stcb, 0, NULL, 0, 1, 0, 0, 0, 0);
  5431. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_STRRST_REQ, SCTP_SO_LOCKED);
  5432. SCTP_TCB_UNLOCK(stcb);
  5433. break;
  5434. }
  5435. case SCTP_CONNECT_X:
  5436. if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
  5437. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5438. error = EINVAL;
  5439. break;
  5440. }
  5441. error = sctp_do_connect_x(so, inp, optval, optsize, p, 0);
  5442. break;
  5443. case SCTP_CONNECT_X_DELAYED:
  5444. if (optsize < (sizeof(int) + sizeof(struct sockaddr_in))) {
  5445. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5446. error = EINVAL;
  5447. break;
  5448. }
  5449. error = sctp_do_connect_x(so, inp, optval, optsize, p, 1);
  5450. break;
  5451. case SCTP_CONNECT_X_COMPLETE:
  5452. {
  5453. struct sockaddr *sa;
  5454. /* FIXME MT: check correct? */
  5455. SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
  5456. /* find tcb */
  5457. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  5458. SCTP_INP_RLOCK(inp);
  5459. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  5460. if (stcb) {
  5461. SCTP_TCB_LOCK(stcb);
  5462. }
  5463. SCTP_INP_RUNLOCK(inp);
  5464. } else {
  5465. /* We increment here since sctp_findassociation_ep_addr() wil
  5466. * do a decrement if it finds the stcb as long as the locked
  5467. * tcb (last argument) is NOT a TCB.. aka NULL.
  5468. */
  5469. SCTP_INP_INCR_REF(inp);
  5470. stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL);
  5471. if (stcb == NULL) {
  5472. SCTP_INP_DECR_REF(inp);
  5473. }
  5474. }
  5475. if (stcb == NULL) {
  5476. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  5477. error = ENOENT;
  5478. break;
  5479. }
  5480. if (stcb->asoc.delayed_connection == 1) {
  5481. stcb->asoc.delayed_connection = 0;
  5482. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  5483. sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb,
  5484. stcb->asoc.primary_destination,
  5485. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
  5486. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  5487. } else {
  5488. /*
  5489. * already expired or did not use delayed
  5490. * connectx
  5491. */
  5492. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  5493. error = EALREADY;
  5494. }
  5495. SCTP_TCB_UNLOCK(stcb);
  5496. break;
  5497. }
  5498. case SCTP_MAX_BURST:
  5499. {
  5500. struct sctp_assoc_value *av;
  5501. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  5502. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  5503. if (stcb) {
  5504. stcb->asoc.max_burst = av->assoc_value;
  5505. SCTP_TCB_UNLOCK(stcb);
  5506. } else {
  5507. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5508. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5509. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5510. ((av->assoc_id == SCTP_FUTURE_ASSOC) ||
  5511. (av->assoc_id == SCTP_ALL_ASSOC)))) {
  5512. SCTP_INP_WLOCK(inp);
  5513. inp->sctp_ep.max_burst = av->assoc_value;
  5514. SCTP_INP_WUNLOCK(inp);
  5515. }
  5516. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5517. ((av->assoc_id == SCTP_CURRENT_ASSOC) ||
  5518. (av->assoc_id == SCTP_ALL_ASSOC))) {
  5519. SCTP_INP_RLOCK(inp);
  5520. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5521. SCTP_TCB_LOCK(stcb);
  5522. stcb->asoc.max_burst = av->assoc_value;
  5523. SCTP_TCB_UNLOCK(stcb);
  5524. }
  5525. SCTP_INP_RUNLOCK(inp);
  5526. }
  5527. }
  5528. break;
  5529. }
  5530. case SCTP_MAXSEG:
  5531. {
  5532. struct sctp_assoc_value *av;
  5533. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  5534. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  5535. if (stcb) {
  5536. stcb->asoc.sctp_frag_point = av->assoc_value;
  5537. SCTP_TCB_UNLOCK(stcb);
  5538. } else {
  5539. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5540. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5541. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5542. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  5543. SCTP_INP_WLOCK(inp);
  5544. inp->sctp_frag_point = av->assoc_value;
  5545. SCTP_INP_WUNLOCK(inp);
  5546. } else {
  5547. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5548. error = EINVAL;
  5549. }
  5550. }
  5551. break;
  5552. }
  5553. case SCTP_EVENTS:
  5554. {
  5555. struct sctp_event_subscribe *events;
  5556. SCTP_CHECK_AND_CAST(events, optval, struct sctp_event_subscribe, optsize);
  5557. SCTP_INP_WLOCK(inp);
  5558. if (events->sctp_data_io_event) {
  5559. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
  5560. } else {
  5561. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT);
  5562. }
  5563. if (events->sctp_association_event) {
  5564. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
  5565. } else {
  5566. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVASSOCEVNT);
  5567. }
  5568. if (events->sctp_address_event) {
  5569. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
  5570. } else {
  5571. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPADDREVNT);
  5572. }
  5573. if (events->sctp_send_failure_event) {
  5574. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
  5575. } else {
  5576. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
  5577. }
  5578. if (events->sctp_peer_error_event) {
  5579. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVPEERERR);
  5580. } else {
  5581. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVPEERERR);
  5582. }
  5583. if (events->sctp_shutdown_event) {
  5584. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
  5585. } else {
  5586. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
  5587. }
  5588. if (events->sctp_partial_delivery_event) {
  5589. sctp_feature_on(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
  5590. } else {
  5591. sctp_feature_off(inp, SCTP_PCB_FLAGS_PDAPIEVNT);
  5592. }
  5593. if (events->sctp_adaptation_layer_event) {
  5594. sctp_feature_on(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
  5595. } else {
  5596. sctp_feature_off(inp, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
  5597. }
  5598. if (events->sctp_authentication_event) {
  5599. sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTHEVNT);
  5600. } else {
  5601. sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTHEVNT);
  5602. }
  5603. if (events->sctp_sender_dry_event) {
  5604. sctp_feature_on(inp, SCTP_PCB_FLAGS_DRYEVNT);
  5605. } else {
  5606. sctp_feature_off(inp, SCTP_PCB_FLAGS_DRYEVNT);
  5607. }
  5608. if (events->sctp_stream_reset_event) {
  5609. sctp_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
  5610. } else {
  5611. sctp_feature_off(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
  5612. }
  5613. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5614. SCTP_TCB_LOCK(stcb);
  5615. if (events->sctp_association_event) {
  5616. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT);
  5617. } else {
  5618. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT);
  5619. }
  5620. if (events->sctp_address_event) {
  5621. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT);
  5622. } else {
  5623. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT);
  5624. }
  5625. if (events->sctp_send_failure_event) {
  5626. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
  5627. } else {
  5628. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT);
  5629. }
  5630. if (events->sctp_peer_error_event) {
  5631. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR);
  5632. } else {
  5633. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVPEERERR);
  5634. }
  5635. if (events->sctp_shutdown_event) {
  5636. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
  5637. } else {
  5638. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT);
  5639. }
  5640. if (events->sctp_partial_delivery_event) {
  5641. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT);
  5642. } else {
  5643. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_PDAPIEVNT);
  5644. }
  5645. if (events->sctp_adaptation_layer_event) {
  5646. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
  5647. } else {
  5648. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT);
  5649. }
  5650. if (events->sctp_authentication_event) {
  5651. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT);
  5652. } else {
  5653. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_AUTHEVNT);
  5654. }
  5655. if (events->sctp_sender_dry_event) {
  5656. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT);
  5657. } else {
  5658. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DRYEVNT);
  5659. }
  5660. if (events->sctp_stream_reset_event) {
  5661. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
  5662. } else {
  5663. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT);
  5664. }
  5665. SCTP_TCB_UNLOCK(stcb);
  5666. }
  5667. /* Send up the sender dry event only for 1-to-1 style sockets. */
  5668. if (events->sctp_sender_dry_event) {
  5669. if (((inp->sctp_flags & (SCTP_PCB_FLAGS_TCPTYPE | SCTP_PCB_FLAGS_IN_TCPPOOL)) != 0) &&
  5670. !SCTP_IS_LISTENING(inp)) {
  5671. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  5672. if (stcb != NULL) {
  5673. SCTP_TCB_LOCK(stcb);
  5674. if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
  5675. TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
  5676. (stcb->asoc.stream_queue_cnt == 0)) {
  5677. sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED);
  5678. }
  5679. SCTP_TCB_UNLOCK(stcb);
  5680. }
  5681. }
  5682. }
  5683. SCTP_INP_WUNLOCK(inp);
  5684. break;
  5685. }
  5686. case SCTP_ADAPTATION_LAYER:
  5687. {
  5688. struct sctp_setadaptation *adap_bits;
  5689. SCTP_CHECK_AND_CAST(adap_bits, optval, struct sctp_setadaptation, optsize);
  5690. SCTP_INP_WLOCK(inp);
  5691. inp->sctp_ep.adaptation_layer_indicator = adap_bits->ssb_adaptation_ind;
  5692. inp->sctp_ep.adaptation_layer_indicator_provided = 1;
  5693. SCTP_INP_WUNLOCK(inp);
  5694. break;
  5695. }
  5696. #ifdef SCTP_DEBUG
  5697. case SCTP_SET_INITIAL_DBG_SEQ:
  5698. {
  5699. uint32_t *vvv;
  5700. SCTP_CHECK_AND_CAST(vvv, optval, uint32_t, optsize);
  5701. SCTP_INP_WLOCK(inp);
  5702. inp->sctp_ep.initial_sequence_debug = *vvv;
  5703. SCTP_INP_WUNLOCK(inp);
  5704. break;
  5705. }
  5706. #endif
  5707. case SCTP_DEFAULT_SEND_PARAM:
  5708. {
  5709. struct sctp_sndrcvinfo *s_info;
  5710. SCTP_CHECK_AND_CAST(s_info, optval, struct sctp_sndrcvinfo, optsize);
  5711. SCTP_FIND_STCB(inp, stcb, s_info->sinfo_assoc_id);
  5712. if (stcb) {
  5713. if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) {
  5714. memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send)));
  5715. } else {
  5716. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5717. error = EINVAL;
  5718. }
  5719. SCTP_TCB_UNLOCK(stcb);
  5720. } else {
  5721. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  5722. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  5723. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5724. ((s_info->sinfo_assoc_id == SCTP_FUTURE_ASSOC) ||
  5725. (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC)))) {
  5726. SCTP_INP_WLOCK(inp);
  5727. memcpy(&inp->def_send, s_info, min(optsize, sizeof(inp->def_send)));
  5728. SCTP_INP_WUNLOCK(inp);
  5729. }
  5730. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  5731. ((s_info->sinfo_assoc_id == SCTP_CURRENT_ASSOC) ||
  5732. (s_info->sinfo_assoc_id == SCTP_ALL_ASSOC))) {
  5733. SCTP_INP_RLOCK(inp);
  5734. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  5735. SCTP_TCB_LOCK(stcb);
  5736. if (s_info->sinfo_stream < stcb->asoc.streamoutcnt) {
  5737. memcpy(&stcb->asoc.def_send, s_info, min(optsize, sizeof(stcb->asoc.def_send)));
  5738. }
  5739. SCTP_TCB_UNLOCK(stcb);
  5740. }
  5741. SCTP_INP_RUNLOCK(inp);
  5742. }
  5743. }
  5744. break;
  5745. }
  5746. case SCTP_PEER_ADDR_PARAMS:
  5747. {
  5748. struct sctp_paddrparams *paddrp;
  5749. struct sctp_nets *net;
  5750. struct sockaddr *addr;
  5751. #if defined(INET) && defined(INET6)
  5752. struct sockaddr_in sin_store;
  5753. #endif
  5754. SCTP_CHECK_AND_CAST(paddrp, optval, struct sctp_paddrparams, optsize);
  5755. SCTP_FIND_STCB(inp, stcb, paddrp->spp_assoc_id);
  5756. #if defined(INET) && defined(INET6)
  5757. if (paddrp->spp_address.ss_family == AF_INET6) {
  5758. struct sockaddr_in6 *sin6;
  5759. sin6 = (struct sockaddr_in6 *)&paddrp->spp_address;
  5760. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  5761. in6_sin6_2_sin(&sin_store, sin6);
  5762. addr = (struct sockaddr *)&sin_store;
  5763. } else {
  5764. addr = (struct sockaddr *)&paddrp->spp_address;
  5765. }
  5766. } else {
  5767. addr = (struct sockaddr *)&paddrp->spp_address;
  5768. }
  5769. #else
  5770. addr = (struct sockaddr *)&paddrp->spp_address;
  5771. #endif
  5772. if (stcb != NULL) {
  5773. net = sctp_findnet(stcb, addr);
  5774. } else {
  5775. /* We increment here since sctp_findassociation_ep_addr() wil
  5776. * do a decrement if it finds the stcb as long as the locked
  5777. * tcb (last argument) is NOT a TCB.. aka NULL.
  5778. */
  5779. net = NULL;
  5780. SCTP_INP_INCR_REF(inp);
  5781. stcb = sctp_findassociation_ep_addr(&inp, addr,
  5782. &net, NULL, NULL);
  5783. if (stcb == NULL) {
  5784. SCTP_INP_DECR_REF(inp);
  5785. }
  5786. }
  5787. if ((stcb != NULL) && (net == NULL)) {
  5788. #ifdef INET
  5789. if (addr->sa_family == AF_INET) {
  5790. struct sockaddr_in *sin;
  5791. sin = (struct sockaddr_in *)addr;
  5792. if (sin->sin_addr.s_addr != INADDR_ANY) {
  5793. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5794. SCTP_TCB_UNLOCK(stcb);
  5795. error = EINVAL;
  5796. break;
  5797. }
  5798. } else
  5799. #endif
  5800. #ifdef INET6
  5801. if (addr->sa_family == AF_INET6) {
  5802. struct sockaddr_in6 *sin6;
  5803. sin6 = (struct sockaddr_in6 *)addr;
  5804. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  5805. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5806. SCTP_TCB_UNLOCK(stcb);
  5807. error = EINVAL;
  5808. break;
  5809. }
  5810. } else
  5811. #endif
  5812. #if defined(__Userspace__)
  5813. if (addr->sa_family == AF_CONN) {
  5814. struct sockaddr_conn *sconn;
  5815. sconn = (struct sockaddr_conn *)addr;
  5816. if (sconn->sconn_addr != NULL) {
  5817. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5818. SCTP_TCB_UNLOCK(stcb);
  5819. error = EINVAL;
  5820. break;
  5821. }
  5822. } else
  5823. #endif
  5824. {
  5825. error = EAFNOSUPPORT;
  5826. SCTP_TCB_UNLOCK(stcb);
  5827. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  5828. break;
  5829. }
  5830. }
  5831. /* sanity checks */
  5832. if ((paddrp->spp_flags & SPP_HB_ENABLE) && (paddrp->spp_flags & SPP_HB_DISABLE)) {
  5833. if (stcb)
  5834. SCTP_TCB_UNLOCK(stcb);
  5835. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5836. return (EINVAL);
  5837. }
  5838. if ((paddrp->spp_flags & SPP_PMTUD_ENABLE) && (paddrp->spp_flags & SPP_PMTUD_DISABLE)) {
  5839. if (stcb)
  5840. SCTP_TCB_UNLOCK(stcb);
  5841. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5842. return (EINVAL);
  5843. }
  5844. if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) &&
  5845. (paddrp->spp_pathmtu > 0) &&
  5846. ((paddrp->spp_pathmtu < SCTP_SMALLEST_PMTU) ||
  5847. (paddrp->spp_pathmtu > SCTP_LARGEST_PMTU))) {
  5848. if (stcb)
  5849. SCTP_TCB_UNLOCK(stcb);
  5850. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  5851. return (EINVAL);
  5852. }
  5853. if (stcb != NULL) {
  5854. /************************TCB SPECIFIC SET ******************/
  5855. if (net != NULL) {
  5856. /************************NET SPECIFIC SET ******************/
  5857. if (paddrp->spp_flags & SPP_HB_DISABLE) {
  5858. if (((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) &&
  5859. ((net->dest_state & SCTP_ADDR_NOHB) == 0)) {
  5860. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
  5861. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9);
  5862. }
  5863. net->dest_state |= SCTP_ADDR_NOHB;
  5864. }
  5865. if (paddrp->spp_flags & SPP_HB_ENABLE) {
  5866. if (paddrp->spp_hbinterval) {
  5867. net->heart_beat_delay = paddrp->spp_hbinterval;
  5868. } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
  5869. net->heart_beat_delay = 0;
  5870. }
  5871. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
  5872. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
  5873. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
  5874. net->dest_state &= ~SCTP_ADDR_NOHB;
  5875. }
  5876. if (paddrp->spp_flags & SPP_HB_DEMAND) {
  5877. if (SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
  5878. sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
  5879. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED);
  5880. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
  5881. }
  5882. }
  5883. if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
  5884. if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  5885. sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
  5886. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
  5887. }
  5888. net->dest_state |= SCTP_ADDR_NO_PMTUD;
  5889. if (paddrp->spp_pathmtu > 0) {
  5890. net->mtu = paddrp->spp_pathmtu;
  5891. switch (net->ro._l_addr.sa.sa_family) {
  5892. #ifdef INET
  5893. case AF_INET:
  5894. net->mtu += SCTP_MIN_V4_OVERHEAD;
  5895. break;
  5896. #endif
  5897. #ifdef INET6
  5898. case AF_INET6:
  5899. net->mtu += SCTP_MIN_OVERHEAD;
  5900. break;
  5901. #endif
  5902. #if defined(__Userspace__)
  5903. case AF_CONN:
  5904. net->mtu += sizeof(struct sctphdr);
  5905. break;
  5906. #endif
  5907. default:
  5908. break;
  5909. }
  5910. if (net->mtu < stcb->asoc.smallest_mtu) {
  5911. sctp_pathmtu_adjustment(stcb, net->mtu, true);
  5912. }
  5913. }
  5914. }
  5915. if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
  5916. if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  5917. sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
  5918. }
  5919. net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
  5920. }
  5921. if (paddrp->spp_pathmaxrxt > 0) {
  5922. if (net->dest_state & SCTP_ADDR_PF) {
  5923. if (net->error_count > paddrp->spp_pathmaxrxt) {
  5924. net->dest_state &= ~SCTP_ADDR_PF;
  5925. }
  5926. } else {
  5927. if ((net->error_count <= paddrp->spp_pathmaxrxt) &&
  5928. (net->error_count > net->pf_threshold)) {
  5929. net->dest_state |= SCTP_ADDR_PF;
  5930. sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
  5931. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
  5932. stcb->sctp_ep, stcb, net,
  5933. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12);
  5934. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
  5935. }
  5936. }
  5937. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  5938. if (net->error_count > paddrp->spp_pathmaxrxt) {
  5939. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  5940. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
  5941. }
  5942. } else {
  5943. if (net->error_count <= paddrp->spp_pathmaxrxt) {
  5944. net->dest_state |= SCTP_ADDR_REACHABLE;
  5945. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
  5946. }
  5947. }
  5948. net->failure_threshold = paddrp->spp_pathmaxrxt;
  5949. }
  5950. if (paddrp->spp_flags & SPP_DSCP) {
  5951. net->dscp = paddrp->spp_dscp & 0xfc;
  5952. net->dscp |= 0x01;
  5953. }
  5954. #ifdef INET6
  5955. if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
  5956. if (net->ro._l_addr.sa.sa_family == AF_INET6) {
  5957. net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
  5958. net->flowlabel |= 0x80000000;
  5959. }
  5960. }
  5961. #endif
  5962. } else {
  5963. /************************ASSOC ONLY -- NO NET SPECIFIC SET ******************/
  5964. if (paddrp->spp_pathmaxrxt > 0) {
  5965. stcb->asoc.def_net_failure = paddrp->spp_pathmaxrxt;
  5966. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  5967. if (net->dest_state & SCTP_ADDR_PF) {
  5968. if (net->error_count > paddrp->spp_pathmaxrxt) {
  5969. net->dest_state &= ~SCTP_ADDR_PF;
  5970. }
  5971. } else {
  5972. if ((net->error_count <= paddrp->spp_pathmaxrxt) &&
  5973. (net->error_count > net->pf_threshold)) {
  5974. net->dest_state |= SCTP_ADDR_PF;
  5975. sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
  5976. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
  5977. stcb->sctp_ep, stcb, net,
  5978. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_13);
  5979. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
  5980. }
  5981. }
  5982. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  5983. if (net->error_count > paddrp->spp_pathmaxrxt) {
  5984. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  5985. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
  5986. }
  5987. } else {
  5988. if (net->error_count <= paddrp->spp_pathmaxrxt) {
  5989. net->dest_state |= SCTP_ADDR_REACHABLE;
  5990. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
  5991. }
  5992. }
  5993. net->failure_threshold = paddrp->spp_pathmaxrxt;
  5994. }
  5995. }
  5996. if (paddrp->spp_flags & SPP_HB_ENABLE) {
  5997. if (paddrp->spp_hbinterval != 0) {
  5998. stcb->asoc.heart_beat_delay = paddrp->spp_hbinterval;
  5999. } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
  6000. stcb->asoc.heart_beat_delay = 0;
  6001. }
  6002. /* Turn back on the timer */
  6003. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6004. if (paddrp->spp_hbinterval != 0) {
  6005. net->heart_beat_delay = paddrp->spp_hbinterval;
  6006. } else if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
  6007. net->heart_beat_delay = 0;
  6008. }
  6009. if (net->dest_state & SCTP_ADDR_NOHB) {
  6010. net->dest_state &= ~SCTP_ADDR_NOHB;
  6011. }
  6012. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
  6013. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_14);
  6014. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
  6015. }
  6016. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
  6017. }
  6018. if (paddrp->spp_flags & SPP_HB_DISABLE) {
  6019. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6020. if ((net->dest_state & SCTP_ADDR_NOHB) == 0) {
  6021. net->dest_state |= SCTP_ADDR_NOHB;
  6022. if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
  6023. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
  6024. inp, stcb, net,
  6025. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_15);
  6026. }
  6027. }
  6028. }
  6029. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
  6030. }
  6031. if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
  6032. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6033. if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  6034. sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
  6035. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_16);
  6036. }
  6037. net->dest_state |= SCTP_ADDR_NO_PMTUD;
  6038. if (paddrp->spp_pathmtu > 0) {
  6039. net->mtu = paddrp->spp_pathmtu;
  6040. switch (net->ro._l_addr.sa.sa_family) {
  6041. #ifdef INET
  6042. case AF_INET:
  6043. net->mtu += SCTP_MIN_V4_OVERHEAD;
  6044. break;
  6045. #endif
  6046. #ifdef INET6
  6047. case AF_INET6:
  6048. net->mtu += SCTP_MIN_OVERHEAD;
  6049. break;
  6050. #endif
  6051. #if defined(__Userspace__)
  6052. case AF_CONN:
  6053. net->mtu += sizeof(struct sctphdr);
  6054. break;
  6055. #endif
  6056. default:
  6057. break;
  6058. }
  6059. if (net->mtu < stcb->asoc.smallest_mtu) {
  6060. sctp_pathmtu_adjustment(stcb, net->mtu, true);
  6061. }
  6062. }
  6063. }
  6064. if (paddrp->spp_pathmtu > 0) {
  6065. stcb->asoc.default_mtu = paddrp->spp_pathmtu;
  6066. }
  6067. sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
  6068. }
  6069. if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
  6070. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6071. if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
  6072. sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
  6073. }
  6074. net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
  6075. }
  6076. stcb->asoc.default_mtu = 0;
  6077. sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
  6078. }
  6079. if (paddrp->spp_flags & SPP_DSCP) {
  6080. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6081. net->dscp = paddrp->spp_dscp & 0xfc;
  6082. net->dscp |= 0x01;
  6083. }
  6084. stcb->asoc.default_dscp = paddrp->spp_dscp & 0xfc;
  6085. stcb->asoc.default_dscp |= 0x01;
  6086. }
  6087. #ifdef INET6
  6088. if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
  6089. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6090. if (net->ro._l_addr.sa.sa_family == AF_INET6) {
  6091. net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
  6092. net->flowlabel |= 0x80000000;
  6093. }
  6094. }
  6095. stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
  6096. stcb->asoc.default_flowlabel |= 0x80000000;
  6097. }
  6098. #endif
  6099. }
  6100. SCTP_TCB_UNLOCK(stcb);
  6101. } else {
  6102. /************************NO TCB, SET TO default stuff ******************/
  6103. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6104. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6105. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6106. (paddrp->spp_assoc_id == SCTP_FUTURE_ASSOC))) {
  6107. SCTP_INP_WLOCK(inp);
  6108. /*
  6109. * For the TOS/FLOWLABEL stuff you set it
  6110. * with the options on the socket
  6111. */
  6112. if (paddrp->spp_pathmaxrxt > 0) {
  6113. inp->sctp_ep.def_net_failure = paddrp->spp_pathmaxrxt;
  6114. }
  6115. if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO)
  6116. inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
  6117. else if (paddrp->spp_hbinterval != 0) {
  6118. if (paddrp->spp_hbinterval > SCTP_MAX_HB_INTERVAL)
  6119. paddrp->spp_hbinterval= SCTP_MAX_HB_INTERVAL;
  6120. inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
  6121. }
  6122. if (paddrp->spp_flags & SPP_HB_ENABLE) {
  6123. if (paddrp->spp_flags & SPP_HB_TIME_IS_ZERO) {
  6124. inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = 0;
  6125. } else if (paddrp->spp_hbinterval) {
  6126. inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT] = sctp_msecs_to_ticks(paddrp->spp_hbinterval);
  6127. }
  6128. sctp_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
  6129. } else if (paddrp->spp_flags & SPP_HB_DISABLE) {
  6130. sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
  6131. }
  6132. if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
  6133. inp->sctp_ep.default_mtu = 0;
  6134. sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
  6135. } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
  6136. if (paddrp->spp_pathmtu > 0) {
  6137. inp->sctp_ep.default_mtu = paddrp->spp_pathmtu;
  6138. }
  6139. sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
  6140. }
  6141. if (paddrp->spp_flags & SPP_DSCP) {
  6142. inp->sctp_ep.default_dscp = paddrp->spp_dscp & 0xfc;
  6143. inp->sctp_ep.default_dscp |= 0x01;
  6144. }
  6145. #ifdef INET6
  6146. if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
  6147. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  6148. inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
  6149. inp->sctp_ep.default_flowlabel |= 0x80000000;
  6150. }
  6151. }
  6152. #endif
  6153. SCTP_INP_WUNLOCK(inp);
  6154. } else {
  6155. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6156. error = EINVAL;
  6157. }
  6158. }
  6159. break;
  6160. }
  6161. case SCTP_RTOINFO:
  6162. {
  6163. struct sctp_rtoinfo *srto;
  6164. uint32_t new_init, new_min, new_max;
  6165. SCTP_CHECK_AND_CAST(srto, optval, struct sctp_rtoinfo, optsize);
  6166. SCTP_FIND_STCB(inp, stcb, srto->srto_assoc_id);
  6167. if (stcb) {
  6168. if (srto->srto_initial)
  6169. new_init = srto->srto_initial;
  6170. else
  6171. new_init = stcb->asoc.initial_rto;
  6172. if (srto->srto_max)
  6173. new_max = srto->srto_max;
  6174. else
  6175. new_max = stcb->asoc.maxrto;
  6176. if (srto->srto_min)
  6177. new_min = srto->srto_min;
  6178. else
  6179. new_min = stcb->asoc.minrto;
  6180. if ((new_min <= new_init) && (new_init <= new_max)) {
  6181. stcb->asoc.initial_rto = new_init;
  6182. stcb->asoc.maxrto = new_max;
  6183. stcb->asoc.minrto = new_min;
  6184. } else {
  6185. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6186. error = EINVAL;
  6187. }
  6188. SCTP_TCB_UNLOCK(stcb);
  6189. } else {
  6190. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6191. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6192. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6193. (srto->srto_assoc_id == SCTP_FUTURE_ASSOC))) {
  6194. SCTP_INP_WLOCK(inp);
  6195. if (srto->srto_initial)
  6196. new_init = srto->srto_initial;
  6197. else
  6198. new_init = inp->sctp_ep.initial_rto;
  6199. if (srto->srto_max)
  6200. new_max = srto->srto_max;
  6201. else
  6202. new_max = inp->sctp_ep.sctp_maxrto;
  6203. if (srto->srto_min)
  6204. new_min = srto->srto_min;
  6205. else
  6206. new_min = inp->sctp_ep.sctp_minrto;
  6207. if ((new_min <= new_init) && (new_init <= new_max)) {
  6208. inp->sctp_ep.initial_rto = new_init;
  6209. inp->sctp_ep.sctp_maxrto = new_max;
  6210. inp->sctp_ep.sctp_minrto = new_min;
  6211. } else {
  6212. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6213. error = EINVAL;
  6214. }
  6215. SCTP_INP_WUNLOCK(inp);
  6216. } else {
  6217. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6218. error = EINVAL;
  6219. }
  6220. }
  6221. break;
  6222. }
  6223. case SCTP_ASSOCINFO:
  6224. {
  6225. struct sctp_assocparams *sasoc;
  6226. SCTP_CHECK_AND_CAST(sasoc, optval, struct sctp_assocparams, optsize);
  6227. SCTP_FIND_STCB(inp, stcb, sasoc->sasoc_assoc_id);
  6228. if (sasoc->sasoc_cookie_life > 0) {
  6229. /* boundary check the cookie life */
  6230. if (sasoc->sasoc_cookie_life < SCTP_MIN_COOKIE_LIFE) {
  6231. sasoc->sasoc_cookie_life = SCTP_MIN_COOKIE_LIFE;
  6232. }
  6233. if (sasoc->sasoc_cookie_life > SCTP_MAX_COOKIE_LIFE) {
  6234. sasoc->sasoc_cookie_life = SCTP_MAX_COOKIE_LIFE;
  6235. }
  6236. }
  6237. if (stcb) {
  6238. if (sasoc->sasoc_asocmaxrxt > 0) {
  6239. stcb->asoc.max_send_times = sasoc->sasoc_asocmaxrxt;
  6240. }
  6241. if (sasoc->sasoc_cookie_life > 0) {
  6242. stcb->asoc.cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
  6243. }
  6244. SCTP_TCB_UNLOCK(stcb);
  6245. } else {
  6246. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6247. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6248. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6249. (sasoc->sasoc_assoc_id == SCTP_FUTURE_ASSOC))) {
  6250. SCTP_INP_WLOCK(inp);
  6251. if (sasoc->sasoc_asocmaxrxt > 0) {
  6252. inp->sctp_ep.max_send_times = sasoc->sasoc_asocmaxrxt;
  6253. }
  6254. if (sasoc->sasoc_cookie_life > 0) {
  6255. inp->sctp_ep.def_cookie_life = sctp_msecs_to_ticks(sasoc->sasoc_cookie_life);
  6256. }
  6257. SCTP_INP_WUNLOCK(inp);
  6258. } else {
  6259. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6260. error = EINVAL;
  6261. }
  6262. }
  6263. break;
  6264. }
  6265. case SCTP_INITMSG:
  6266. {
  6267. struct sctp_initmsg *sinit;
  6268. SCTP_CHECK_AND_CAST(sinit, optval, struct sctp_initmsg, optsize);
  6269. SCTP_INP_WLOCK(inp);
  6270. if (sinit->sinit_num_ostreams)
  6271. inp->sctp_ep.pre_open_stream_count = sinit->sinit_num_ostreams;
  6272. if (sinit->sinit_max_instreams)
  6273. inp->sctp_ep.max_open_streams_intome = sinit->sinit_max_instreams;
  6274. if (sinit->sinit_max_attempts)
  6275. inp->sctp_ep.max_init_times = sinit->sinit_max_attempts;
  6276. if (sinit->sinit_max_init_timeo)
  6277. inp->sctp_ep.initial_init_rto_max = sinit->sinit_max_init_timeo;
  6278. SCTP_INP_WUNLOCK(inp);
  6279. break;
  6280. }
  6281. case SCTP_PRIMARY_ADDR:
  6282. {
  6283. struct sctp_setprim *spa;
  6284. struct sctp_nets *net;
  6285. struct sockaddr *addr;
  6286. #if defined(INET) && defined(INET6)
  6287. struct sockaddr_in sin_store;
  6288. #endif
  6289. SCTP_CHECK_AND_CAST(spa, optval, struct sctp_setprim, optsize);
  6290. SCTP_FIND_STCB(inp, stcb, spa->ssp_assoc_id);
  6291. #if defined(INET) && defined(INET6)
  6292. if (spa->ssp_addr.ss_family == AF_INET6) {
  6293. struct sockaddr_in6 *sin6;
  6294. sin6 = (struct sockaddr_in6 *)&spa->ssp_addr;
  6295. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  6296. in6_sin6_2_sin(&sin_store, sin6);
  6297. addr = (struct sockaddr *)&sin_store;
  6298. } else {
  6299. addr = (struct sockaddr *)&spa->ssp_addr;
  6300. }
  6301. } else {
  6302. addr = (struct sockaddr *)&spa->ssp_addr;
  6303. }
  6304. #else
  6305. addr = (struct sockaddr *)&spa->ssp_addr;
  6306. #endif
  6307. if (stcb != NULL) {
  6308. net = sctp_findnet(stcb, addr);
  6309. } else {
  6310. /* We increment here since sctp_findassociation_ep_addr() wil
  6311. * do a decrement if it finds the stcb as long as the locked
  6312. * tcb (last argument) is NOT a TCB.. aka NULL.
  6313. */
  6314. net = NULL;
  6315. SCTP_INP_INCR_REF(inp);
  6316. stcb = sctp_findassociation_ep_addr(&inp, addr,
  6317. &net, NULL, NULL);
  6318. if (stcb == NULL) {
  6319. SCTP_INP_DECR_REF(inp);
  6320. }
  6321. }
  6322. if ((stcb != NULL) && (net != NULL)) {
  6323. if (net != stcb->asoc.primary_destination) {
  6324. if ((net->dest_state & SCTP_ADDR_UNCONFIRMED) == 0) {
  6325. /* Ok we need to set it */
  6326. if (sctp_set_primary_addr(stcb, (struct sockaddr *)NULL, net) == 0) {
  6327. if ((stcb->asoc.alternate) &&
  6328. ((net->dest_state & SCTP_ADDR_PF) == 0) &&
  6329. (net->dest_state & SCTP_ADDR_REACHABLE)) {
  6330. sctp_free_remote_addr(stcb->asoc.alternate);
  6331. stcb->asoc.alternate = NULL;
  6332. }
  6333. } else {
  6334. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6335. error = EINVAL;
  6336. }
  6337. } else {
  6338. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6339. error = EINVAL;
  6340. }
  6341. }
  6342. } else {
  6343. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6344. error = EINVAL;
  6345. }
  6346. if (stcb != NULL) {
  6347. SCTP_TCB_UNLOCK(stcb);
  6348. }
  6349. break;
  6350. }
  6351. case SCTP_SET_DYNAMIC_PRIMARY:
  6352. {
  6353. union sctp_sockstore *ss;
  6354. #ifdef SCTP_MVRF
  6355. int i, fnd = 0;
  6356. #endif
  6357. #if !defined(_WIN32) && !defined(__Userspace__)
  6358. #if defined(__APPLE__)
  6359. struct proc *proc;
  6360. #endif
  6361. #if defined(__FreeBSD__)
  6362. error = priv_check(curthread,
  6363. PRIV_NETINET_RESERVEDPORT);
  6364. #elif defined(__APPLE__)
  6365. proc = (struct proc *)p;
  6366. if (p) {
  6367. error = suser(proc->p_ucred, &proc->p_acflag);
  6368. } else {
  6369. break;
  6370. }
  6371. #else
  6372. error = suser(p, 0);
  6373. #endif
  6374. if (error)
  6375. break;
  6376. #endif
  6377. SCTP_CHECK_AND_CAST(ss, optval, union sctp_sockstore, optsize);
  6378. /* SUPER USER CHECK? */
  6379. #ifdef SCTP_MVRF
  6380. for (i = 0; i < inp->num_vrfs; i++) {
  6381. if (vrf_id == inp->m_vrf_ids[i]) {
  6382. fnd = 1;
  6383. break;
  6384. }
  6385. }
  6386. if (!fnd) {
  6387. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6388. error = EINVAL;
  6389. break;
  6390. }
  6391. #endif
  6392. error = sctp_dynamic_set_primary(&ss->sa, vrf_id);
  6393. break;
  6394. }
  6395. case SCTP_SET_PEER_PRIMARY_ADDR:
  6396. {
  6397. struct sctp_setpeerprim *sspp;
  6398. struct sockaddr *addr;
  6399. #if defined(INET) && defined(INET6)
  6400. struct sockaddr_in sin_store;
  6401. #endif
  6402. SCTP_CHECK_AND_CAST(sspp, optval, struct sctp_setpeerprim, optsize);
  6403. SCTP_FIND_STCB(inp, stcb, sspp->sspp_assoc_id);
  6404. if (stcb != NULL) {
  6405. struct sctp_ifa *ifa;
  6406. #if defined(INET) && defined(INET6)
  6407. if (sspp->sspp_addr.ss_family == AF_INET6) {
  6408. struct sockaddr_in6 *sin6;
  6409. sin6 = (struct sockaddr_in6 *)&sspp->sspp_addr;
  6410. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  6411. in6_sin6_2_sin(&sin_store, sin6);
  6412. addr = (struct sockaddr *)&sin_store;
  6413. } else {
  6414. addr = (struct sockaddr *)&sspp->sspp_addr;
  6415. }
  6416. } else {
  6417. addr = (struct sockaddr *)&sspp->sspp_addr;
  6418. }
  6419. #else
  6420. addr = (struct sockaddr *)&sspp->sspp_addr;
  6421. #endif
  6422. ifa = sctp_find_ifa_by_addr(addr, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
  6423. if (ifa == NULL) {
  6424. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6425. error = EINVAL;
  6426. goto out_of_it;
  6427. }
  6428. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
  6429. /* Must validate the ifa found is in our ep */
  6430. struct sctp_laddr *laddr;
  6431. int found = 0;
  6432. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  6433. if (laddr->ifa == NULL) {
  6434. SCTPDBG(SCTP_DEBUG_OUTPUT1, "%s: NULL ifa\n",
  6435. __func__);
  6436. continue;
  6437. }
  6438. if ((sctp_is_addr_restricted(stcb, laddr->ifa)) &&
  6439. (!sctp_is_addr_pending(stcb, laddr->ifa))) {
  6440. continue;
  6441. }
  6442. if (laddr->ifa == ifa) {
  6443. found = 1;
  6444. break;
  6445. }
  6446. }
  6447. if (!found) {
  6448. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6449. error = EINVAL;
  6450. goto out_of_it;
  6451. }
  6452. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6453. } else {
  6454. switch (addr->sa_family) {
  6455. #ifdef INET
  6456. case AF_INET:
  6457. {
  6458. struct sockaddr_in *sin;
  6459. sin = (struct sockaddr_in *)addr;
  6460. if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
  6461. &sin->sin_addr) != 0) {
  6462. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6463. error = EINVAL;
  6464. goto out_of_it;
  6465. }
  6466. break;
  6467. }
  6468. #endif
  6469. #ifdef INET6
  6470. case AF_INET6:
  6471. {
  6472. struct sockaddr_in6 *sin6;
  6473. sin6 = (struct sockaddr_in6 *)addr;
  6474. if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
  6475. &sin6->sin6_addr) != 0) {
  6476. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6477. error = EINVAL;
  6478. goto out_of_it;
  6479. }
  6480. break;
  6481. }
  6482. #endif
  6483. default:
  6484. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6485. error = EINVAL;
  6486. goto out_of_it;
  6487. }
  6488. #endif
  6489. }
  6490. if (sctp_set_primary_ip_address_sa(stcb, addr) != 0) {
  6491. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6492. error = EINVAL;
  6493. }
  6494. sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SOCKOPT, SCTP_SO_LOCKED);
  6495. out_of_it:
  6496. SCTP_TCB_UNLOCK(stcb);
  6497. } else {
  6498. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6499. error = EINVAL;
  6500. }
  6501. break;
  6502. }
  6503. case SCTP_BINDX_ADD_ADDR:
  6504. {
  6505. struct sockaddr *sa;
  6506. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6507. struct thread *td;
  6508. td = (struct thread *)p;
  6509. #endif
  6510. SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
  6511. #ifdef INET
  6512. if (sa->sa_family == AF_INET) {
  6513. if (optsize < sizeof(struct sockaddr_in)) {
  6514. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6515. error = EINVAL;
  6516. break;
  6517. }
  6518. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6519. if (td != NULL &&
  6520. (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
  6521. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6522. break;
  6523. }
  6524. #endif
  6525. } else
  6526. #endif
  6527. #ifdef INET6
  6528. if (sa->sa_family == AF_INET6) {
  6529. if (optsize < sizeof(struct sockaddr_in6)) {
  6530. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6531. error = EINVAL;
  6532. break;
  6533. }
  6534. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6535. if (td != NULL &&
  6536. (error = prison_local_ip6(td->td_ucred,
  6537. &(((struct sockaddr_in6 *)sa)->sin6_addr),
  6538. (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
  6539. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6540. break;
  6541. }
  6542. #endif
  6543. } else
  6544. #endif
  6545. {
  6546. error = EAFNOSUPPORT;
  6547. break;
  6548. }
  6549. sctp_bindx_add_address(so, inp, sa, vrf_id, &error, p);
  6550. break;
  6551. }
  6552. case SCTP_BINDX_REM_ADDR:
  6553. {
  6554. struct sockaddr *sa;
  6555. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6556. struct thread *td;
  6557. td = (struct thread *)p;
  6558. #endif
  6559. SCTP_CHECK_AND_CAST(sa, optval, struct sockaddr, optsize);
  6560. #ifdef INET
  6561. if (sa->sa_family == AF_INET) {
  6562. if (optsize < sizeof(struct sockaddr_in)) {
  6563. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6564. error = EINVAL;
  6565. break;
  6566. }
  6567. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6568. if (td != NULL &&
  6569. (error = prison_local_ip4(td->td_ucred, &(((struct sockaddr_in *)sa)->sin_addr)))) {
  6570. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6571. break;
  6572. }
  6573. #endif
  6574. } else
  6575. #endif
  6576. #ifdef INET6
  6577. if (sa->sa_family == AF_INET6) {
  6578. if (optsize < sizeof(struct sockaddr_in6)) {
  6579. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6580. error = EINVAL;
  6581. break;
  6582. }
  6583. #if defined(__FreeBSD__) && !defined(__Userspace__)
  6584. if (td != NULL &&
  6585. (error = prison_local_ip6(td->td_ucred,
  6586. &(((struct sockaddr_in6 *)sa)->sin6_addr),
  6587. (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
  6588. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6589. break;
  6590. }
  6591. #endif
  6592. } else
  6593. #endif
  6594. {
  6595. error = EAFNOSUPPORT;
  6596. break;
  6597. }
  6598. sctp_bindx_delete_address(inp, sa, vrf_id, &error);
  6599. break;
  6600. }
  6601. #if defined(__APPLE__) && !defined(__Userspace__)
  6602. case SCTP_LISTEN_FIX:
  6603. /* only applies to one-to-many sockets */
  6604. if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
  6605. /* make sure the ACCEPTCONN flag is OFF */
  6606. so->so_options &= ~SO_ACCEPTCONN;
  6607. } else {
  6608. /* otherwise, not allowed */
  6609. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6610. error = EINVAL;
  6611. }
  6612. break;
  6613. #endif
  6614. case SCTP_EVENT:
  6615. {
  6616. struct sctp_event *event;
  6617. uint32_t event_type;
  6618. SCTP_CHECK_AND_CAST(event, optval, struct sctp_event, optsize);
  6619. SCTP_FIND_STCB(inp, stcb, event->se_assoc_id);
  6620. switch (event->se_type) {
  6621. case SCTP_ASSOC_CHANGE:
  6622. event_type = SCTP_PCB_FLAGS_RECVASSOCEVNT;
  6623. break;
  6624. case SCTP_PEER_ADDR_CHANGE:
  6625. event_type = SCTP_PCB_FLAGS_RECVPADDREVNT;
  6626. break;
  6627. case SCTP_REMOTE_ERROR:
  6628. event_type = SCTP_PCB_FLAGS_RECVPEERERR;
  6629. break;
  6630. case SCTP_SEND_FAILED:
  6631. event_type = SCTP_PCB_FLAGS_RECVSENDFAILEVNT;
  6632. break;
  6633. case SCTP_SHUTDOWN_EVENT:
  6634. event_type = SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT;
  6635. break;
  6636. case SCTP_ADAPTATION_INDICATION:
  6637. event_type = SCTP_PCB_FLAGS_ADAPTATIONEVNT;
  6638. break;
  6639. case SCTP_PARTIAL_DELIVERY_EVENT:
  6640. event_type = SCTP_PCB_FLAGS_PDAPIEVNT;
  6641. break;
  6642. case SCTP_AUTHENTICATION_EVENT:
  6643. event_type = SCTP_PCB_FLAGS_AUTHEVNT;
  6644. break;
  6645. case SCTP_STREAM_RESET_EVENT:
  6646. event_type = SCTP_PCB_FLAGS_STREAM_RESETEVNT;
  6647. break;
  6648. case SCTP_SENDER_DRY_EVENT:
  6649. event_type = SCTP_PCB_FLAGS_DRYEVNT;
  6650. break;
  6651. case SCTP_NOTIFICATIONS_STOPPED_EVENT:
  6652. event_type = 0;
  6653. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
  6654. error = ENOTSUP;
  6655. break;
  6656. case SCTP_ASSOC_RESET_EVENT:
  6657. event_type = SCTP_PCB_FLAGS_ASSOC_RESETEVNT;
  6658. break;
  6659. case SCTP_STREAM_CHANGE_EVENT:
  6660. event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
  6661. break;
  6662. case SCTP_SEND_FAILED_EVENT:
  6663. event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
  6664. break;
  6665. default:
  6666. event_type = 0;
  6667. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6668. error = EINVAL;
  6669. break;
  6670. }
  6671. if (event_type > 0) {
  6672. if (stcb) {
  6673. if (event->se_on) {
  6674. sctp_stcb_feature_on(inp, stcb, event_type);
  6675. if (event_type == SCTP_PCB_FLAGS_DRYEVNT) {
  6676. if (TAILQ_EMPTY(&stcb->asoc.send_queue) &&
  6677. TAILQ_EMPTY(&stcb->asoc.sent_queue) &&
  6678. (stcb->asoc.stream_queue_cnt == 0)) {
  6679. sctp_ulp_notify(SCTP_NOTIFY_SENDER_DRY, stcb, 0, NULL, SCTP_SO_LOCKED);
  6680. }
  6681. }
  6682. } else {
  6683. sctp_stcb_feature_off(inp, stcb, event_type);
  6684. }
  6685. SCTP_TCB_UNLOCK(stcb);
  6686. } else {
  6687. /*
  6688. * We don't want to send up a storm of events,
  6689. * so return an error for sender dry events
  6690. */
  6691. if ((event_type == SCTP_PCB_FLAGS_DRYEVNT) &&
  6692. (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6693. ((event->se_assoc_id == SCTP_ALL_ASSOC) ||
  6694. (event->se_assoc_id == SCTP_CURRENT_ASSOC))) {
  6695. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTSUP);
  6696. error = ENOTSUP;
  6697. break;
  6698. }
  6699. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6700. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6701. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6702. ((event->se_assoc_id == SCTP_FUTURE_ASSOC) ||
  6703. (event->se_assoc_id == SCTP_ALL_ASSOC)))) {
  6704. SCTP_INP_WLOCK(inp);
  6705. if (event->se_on) {
  6706. sctp_feature_on(inp, event_type);
  6707. } else {
  6708. sctp_feature_off(inp, event_type);
  6709. }
  6710. SCTP_INP_WUNLOCK(inp);
  6711. }
  6712. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6713. ((event->se_assoc_id == SCTP_CURRENT_ASSOC) ||
  6714. (event->se_assoc_id == SCTP_ALL_ASSOC))) {
  6715. SCTP_INP_RLOCK(inp);
  6716. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  6717. SCTP_TCB_LOCK(stcb);
  6718. if (event->se_on) {
  6719. sctp_stcb_feature_on(inp, stcb, event_type);
  6720. } else {
  6721. sctp_stcb_feature_off(inp, stcb, event_type);
  6722. }
  6723. SCTP_TCB_UNLOCK(stcb);
  6724. }
  6725. SCTP_INP_RUNLOCK(inp);
  6726. }
  6727. }
  6728. } else {
  6729. if (stcb) {
  6730. SCTP_TCB_UNLOCK(stcb);
  6731. }
  6732. }
  6733. break;
  6734. }
  6735. case SCTP_RECVRCVINFO:
  6736. {
  6737. int *onoff;
  6738. SCTP_CHECK_AND_CAST(onoff, optval, int, optsize);
  6739. SCTP_INP_WLOCK(inp);
  6740. if (*onoff != 0) {
  6741. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
  6742. } else {
  6743. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVRCVINFO);
  6744. }
  6745. SCTP_INP_WUNLOCK(inp);
  6746. break;
  6747. }
  6748. case SCTP_RECVNXTINFO:
  6749. {
  6750. int *onoff;
  6751. SCTP_CHECK_AND_CAST(onoff, optval, int, optsize);
  6752. SCTP_INP_WLOCK(inp);
  6753. if (*onoff != 0) {
  6754. sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
  6755. } else {
  6756. sctp_feature_off(inp, SCTP_PCB_FLAGS_RECVNXTINFO);
  6757. }
  6758. SCTP_INP_WUNLOCK(inp);
  6759. break;
  6760. }
  6761. case SCTP_DEFAULT_SNDINFO:
  6762. {
  6763. struct sctp_sndinfo *info;
  6764. uint16_t policy;
  6765. SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize);
  6766. SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id);
  6767. if (stcb) {
  6768. if (info->snd_sid < stcb->asoc.streamoutcnt) {
  6769. stcb->asoc.def_send.sinfo_stream = info->snd_sid;
  6770. policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
  6771. stcb->asoc.def_send.sinfo_flags = info->snd_flags;
  6772. stcb->asoc.def_send.sinfo_flags |= policy;
  6773. stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
  6774. stcb->asoc.def_send.sinfo_context = info->snd_context;
  6775. } else {
  6776. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6777. error = EINVAL;
  6778. }
  6779. SCTP_TCB_UNLOCK(stcb);
  6780. } else {
  6781. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6782. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6783. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6784. ((info->snd_assoc_id == SCTP_FUTURE_ASSOC) ||
  6785. (info->snd_assoc_id == SCTP_ALL_ASSOC)))) {
  6786. SCTP_INP_WLOCK(inp);
  6787. inp->def_send.sinfo_stream = info->snd_sid;
  6788. policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
  6789. inp->def_send.sinfo_flags = info->snd_flags;
  6790. inp->def_send.sinfo_flags |= policy;
  6791. inp->def_send.sinfo_ppid = info->snd_ppid;
  6792. inp->def_send.sinfo_context = info->snd_context;
  6793. SCTP_INP_WUNLOCK(inp);
  6794. }
  6795. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6796. ((info->snd_assoc_id == SCTP_CURRENT_ASSOC) ||
  6797. (info->snd_assoc_id == SCTP_ALL_ASSOC))) {
  6798. SCTP_INP_RLOCK(inp);
  6799. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  6800. SCTP_TCB_LOCK(stcb);
  6801. if (info->snd_sid < stcb->asoc.streamoutcnt) {
  6802. stcb->asoc.def_send.sinfo_stream = info->snd_sid;
  6803. policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
  6804. stcb->asoc.def_send.sinfo_flags = info->snd_flags;
  6805. stcb->asoc.def_send.sinfo_flags |= policy;
  6806. stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
  6807. stcb->asoc.def_send.sinfo_context = info->snd_context;
  6808. }
  6809. SCTP_TCB_UNLOCK(stcb);
  6810. }
  6811. SCTP_INP_RUNLOCK(inp);
  6812. }
  6813. }
  6814. break;
  6815. }
  6816. case SCTP_DEFAULT_PRINFO:
  6817. {
  6818. struct sctp_default_prinfo *info;
  6819. SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize);
  6820. SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
  6821. if (info->pr_policy > SCTP_PR_SCTP_MAX) {
  6822. if (stcb) {
  6823. SCTP_TCB_UNLOCK(stcb);
  6824. }
  6825. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6826. error = EINVAL;
  6827. break;
  6828. }
  6829. if (stcb) {
  6830. stcb->asoc.def_send.sinfo_flags &= 0xfff0;
  6831. stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
  6832. stcb->asoc.def_send.sinfo_timetolive = info->pr_value;
  6833. SCTP_TCB_UNLOCK(stcb);
  6834. } else {
  6835. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  6836. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  6837. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6838. ((info->pr_assoc_id == SCTP_FUTURE_ASSOC) ||
  6839. (info->pr_assoc_id == SCTP_ALL_ASSOC)))) {
  6840. SCTP_INP_WLOCK(inp);
  6841. inp->def_send.sinfo_flags &= 0xfff0;
  6842. inp->def_send.sinfo_flags |= info->pr_policy;
  6843. inp->def_send.sinfo_timetolive = info->pr_value;
  6844. SCTP_INP_WUNLOCK(inp);
  6845. }
  6846. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  6847. ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) ||
  6848. (info->pr_assoc_id == SCTP_ALL_ASSOC))) {
  6849. SCTP_INP_RLOCK(inp);
  6850. LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
  6851. SCTP_TCB_LOCK(stcb);
  6852. stcb->asoc.def_send.sinfo_flags &= 0xfff0;
  6853. stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
  6854. stcb->asoc.def_send.sinfo_timetolive = info->pr_value;
  6855. SCTP_TCB_UNLOCK(stcb);
  6856. }
  6857. SCTP_INP_RUNLOCK(inp);
  6858. }
  6859. }
  6860. break;
  6861. }
  6862. case SCTP_PEER_ADDR_THLDS:
  6863. /* Applies to the specific association */
  6864. {
  6865. struct sctp_paddrthlds *thlds;
  6866. struct sctp_nets *net;
  6867. struct sockaddr *addr;
  6868. #if defined(INET) && defined(INET6)
  6869. struct sockaddr_in sin_store;
  6870. #endif
  6871. SCTP_CHECK_AND_CAST(thlds, optval, struct sctp_paddrthlds, optsize);
  6872. SCTP_FIND_STCB(inp, stcb, thlds->spt_assoc_id);
  6873. #if defined(INET) && defined(INET6)
  6874. if (thlds->spt_address.ss_family == AF_INET6) {
  6875. struct sockaddr_in6 *sin6;
  6876. sin6 = (struct sockaddr_in6 *)&thlds->spt_address;
  6877. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  6878. in6_sin6_2_sin(&sin_store, sin6);
  6879. addr = (struct sockaddr *)&sin_store;
  6880. } else {
  6881. addr = (struct sockaddr *)&thlds->spt_address;
  6882. }
  6883. } else {
  6884. addr = (struct sockaddr *)&thlds->spt_address;
  6885. }
  6886. #else
  6887. addr = (struct sockaddr *)&thlds->spt_address;
  6888. #endif
  6889. if (stcb != NULL) {
  6890. net = sctp_findnet(stcb, addr);
  6891. } else {
  6892. /* We increment here since sctp_findassociation_ep_addr() wil
  6893. * do a decrement if it finds the stcb as long as the locked
  6894. * tcb (last argument) is NOT a TCB.. aka NULL.
  6895. */
  6896. net = NULL;
  6897. SCTP_INP_INCR_REF(inp);
  6898. stcb = sctp_findassociation_ep_addr(&inp, addr,
  6899. &net, NULL, NULL);
  6900. if (stcb == NULL) {
  6901. SCTP_INP_DECR_REF(inp);
  6902. }
  6903. }
  6904. if ((stcb != NULL) && (net == NULL)) {
  6905. #ifdef INET
  6906. if (addr->sa_family == AF_INET) {
  6907. struct sockaddr_in *sin;
  6908. sin = (struct sockaddr_in *)addr;
  6909. if (sin->sin_addr.s_addr != INADDR_ANY) {
  6910. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6911. SCTP_TCB_UNLOCK(stcb);
  6912. error = EINVAL;
  6913. break;
  6914. }
  6915. } else
  6916. #endif
  6917. #ifdef INET6
  6918. if (addr->sa_family == AF_INET6) {
  6919. struct sockaddr_in6 *sin6;
  6920. sin6 = (struct sockaddr_in6 *)addr;
  6921. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  6922. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6923. SCTP_TCB_UNLOCK(stcb);
  6924. error = EINVAL;
  6925. break;
  6926. }
  6927. } else
  6928. #endif
  6929. #if defined(__Userspace__)
  6930. if (addr->sa_family == AF_CONN) {
  6931. struct sockaddr_conn *sconn;
  6932. sconn = (struct sockaddr_conn *)addr;
  6933. if (sconn->sconn_addr != NULL) {
  6934. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  6935. SCTP_TCB_UNLOCK(stcb);
  6936. error = EINVAL;
  6937. break;
  6938. }
  6939. } else
  6940. #endif
  6941. {
  6942. error = EAFNOSUPPORT;
  6943. SCTP_TCB_UNLOCK(stcb);
  6944. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6945. break;
  6946. }
  6947. }
  6948. if (thlds->spt_pathcpthld != 0xffff) {
  6949. if (stcb != NULL) {
  6950. SCTP_TCB_UNLOCK(stcb);
  6951. }
  6952. error = EINVAL;
  6953. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  6954. break;
  6955. }
  6956. if (stcb != NULL) {
  6957. if (net != NULL) {
  6958. net->failure_threshold = thlds->spt_pathmaxrxt;
  6959. net->pf_threshold = thlds->spt_pathpfthld;
  6960. if (net->dest_state & SCTP_ADDR_PF) {
  6961. if ((net->error_count > net->failure_threshold) ||
  6962. (net->error_count <= net->pf_threshold)) {
  6963. net->dest_state &= ~SCTP_ADDR_PF;
  6964. }
  6965. } else {
  6966. if ((net->error_count > net->pf_threshold) &&
  6967. (net->error_count <= net->failure_threshold)) {
  6968. net->dest_state |= SCTP_ADDR_PF;
  6969. sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
  6970. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
  6971. stcb->sctp_ep, stcb, net,
  6972. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_17);
  6973. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
  6974. }
  6975. }
  6976. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  6977. if (net->error_count > net->failure_threshold) {
  6978. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  6979. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
  6980. }
  6981. } else {
  6982. if (net->error_count <= net->failure_threshold) {
  6983. net->dest_state |= SCTP_ADDR_REACHABLE;
  6984. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
  6985. }
  6986. }
  6987. } else {
  6988. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  6989. net->failure_threshold = thlds->spt_pathmaxrxt;
  6990. net->pf_threshold = thlds->spt_pathpfthld;
  6991. if (net->dest_state & SCTP_ADDR_PF) {
  6992. if ((net->error_count > net->failure_threshold) ||
  6993. (net->error_count <= net->pf_threshold)) {
  6994. net->dest_state &= ~SCTP_ADDR_PF;
  6995. }
  6996. } else {
  6997. if ((net->error_count > net->pf_threshold) &&
  6998. (net->error_count <= net->failure_threshold)) {
  6999. net->dest_state |= SCTP_ADDR_PF;
  7000. sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
  7001. sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
  7002. stcb->sctp_ep, stcb, net,
  7003. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_18);
  7004. sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
  7005. }
  7006. }
  7007. if (net->dest_state & SCTP_ADDR_REACHABLE) {
  7008. if (net->error_count > net->failure_threshold) {
  7009. net->dest_state &= ~SCTP_ADDR_REACHABLE;
  7010. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
  7011. }
  7012. } else {
  7013. if (net->error_count <= net->failure_threshold) {
  7014. net->dest_state |= SCTP_ADDR_REACHABLE;
  7015. sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_UP, stcb, 0, net, SCTP_SO_LOCKED);
  7016. }
  7017. }
  7018. }
  7019. stcb->asoc.def_net_failure = thlds->spt_pathmaxrxt;
  7020. stcb->asoc.def_net_pf_threshold = thlds->spt_pathpfthld;
  7021. }
  7022. SCTP_TCB_UNLOCK(stcb);
  7023. } else {
  7024. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7025. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7026. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7027. (thlds->spt_assoc_id == SCTP_FUTURE_ASSOC))) {
  7028. SCTP_INP_WLOCK(inp);
  7029. inp->sctp_ep.def_net_failure = thlds->spt_pathmaxrxt;
  7030. inp->sctp_ep.def_net_pf_threshold = thlds->spt_pathpfthld;
  7031. SCTP_INP_WUNLOCK(inp);
  7032. } else {
  7033. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7034. error = EINVAL;
  7035. }
  7036. }
  7037. break;
  7038. }
  7039. case SCTP_REMOTE_UDP_ENCAPS_PORT:
  7040. {
  7041. struct sctp_udpencaps *encaps;
  7042. struct sctp_nets *net;
  7043. struct sockaddr *addr;
  7044. #if defined(INET) && defined(INET6)
  7045. struct sockaddr_in sin_store;
  7046. #endif
  7047. SCTP_CHECK_AND_CAST(encaps, optval, struct sctp_udpencaps, optsize);
  7048. SCTP_FIND_STCB(inp, stcb, encaps->sue_assoc_id);
  7049. #if defined(INET) && defined(INET6)
  7050. if (encaps->sue_address.ss_family == AF_INET6) {
  7051. struct sockaddr_in6 *sin6;
  7052. sin6 = (struct sockaddr_in6 *)&encaps->sue_address;
  7053. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
  7054. in6_sin6_2_sin(&sin_store, sin6);
  7055. addr = (struct sockaddr *)&sin_store;
  7056. } else {
  7057. addr = (struct sockaddr *)&encaps->sue_address;
  7058. }
  7059. } else {
  7060. addr = (struct sockaddr *)&encaps->sue_address;
  7061. }
  7062. #else
  7063. addr = (struct sockaddr *)&encaps->sue_address;
  7064. #endif
  7065. if (stcb != NULL) {
  7066. net = sctp_findnet(stcb, addr);
  7067. } else {
  7068. /* We increment here since sctp_findassociation_ep_addr() wil
  7069. * do a decrement if it finds the stcb as long as the locked
  7070. * tcb (last argument) is NOT a TCB.. aka NULL.
  7071. */
  7072. net = NULL;
  7073. SCTP_INP_INCR_REF(inp);
  7074. stcb = sctp_findassociation_ep_addr(&inp, addr, &net, NULL, NULL);
  7075. if (stcb == NULL) {
  7076. SCTP_INP_DECR_REF(inp);
  7077. }
  7078. }
  7079. if ((stcb != NULL) && (net == NULL)) {
  7080. #ifdef INET
  7081. if (addr->sa_family == AF_INET) {
  7082. struct sockaddr_in *sin;
  7083. sin = (struct sockaddr_in *)addr;
  7084. if (sin->sin_addr.s_addr != INADDR_ANY) {
  7085. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7086. SCTP_TCB_UNLOCK(stcb);
  7087. error = EINVAL;
  7088. break;
  7089. }
  7090. } else
  7091. #endif
  7092. #ifdef INET6
  7093. if (addr->sa_family == AF_INET6) {
  7094. struct sockaddr_in6 *sin6;
  7095. sin6 = (struct sockaddr_in6 *)addr;
  7096. if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
  7097. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7098. SCTP_TCB_UNLOCK(stcb);
  7099. error = EINVAL;
  7100. break;
  7101. }
  7102. } else
  7103. #endif
  7104. #if defined(__Userspace__)
  7105. if (addr->sa_family == AF_CONN) {
  7106. struct sockaddr_conn *sconn;
  7107. sconn = (struct sockaddr_conn *)addr;
  7108. if (sconn->sconn_addr != NULL) {
  7109. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7110. SCTP_TCB_UNLOCK(stcb);
  7111. error = EINVAL;
  7112. break;
  7113. }
  7114. } else
  7115. #endif
  7116. {
  7117. error = EAFNOSUPPORT;
  7118. SCTP_TCB_UNLOCK(stcb);
  7119. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  7120. break;
  7121. }
  7122. }
  7123. if (stcb != NULL) {
  7124. if (net != NULL) {
  7125. net->port = encaps->sue_port;
  7126. } else {
  7127. stcb->asoc.port = encaps->sue_port;
  7128. }
  7129. SCTP_TCB_UNLOCK(stcb);
  7130. } else {
  7131. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7132. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7133. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7134. (encaps->sue_assoc_id == SCTP_FUTURE_ASSOC))) {
  7135. SCTP_INP_WLOCK(inp);
  7136. inp->sctp_ep.port = encaps->sue_port;
  7137. SCTP_INP_WUNLOCK(inp);
  7138. } else {
  7139. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7140. error = EINVAL;
  7141. }
  7142. }
  7143. break;
  7144. }
  7145. case SCTP_ECN_SUPPORTED:
  7146. {
  7147. struct sctp_assoc_value *av;
  7148. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7149. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7150. if (stcb) {
  7151. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7152. error = EINVAL;
  7153. SCTP_TCB_UNLOCK(stcb);
  7154. } else {
  7155. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7156. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7157. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7158. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7159. SCTP_INP_WLOCK(inp);
  7160. if (av->assoc_value == 0) {
  7161. inp->ecn_supported = 0;
  7162. } else {
  7163. inp->ecn_supported = 1;
  7164. }
  7165. SCTP_INP_WUNLOCK(inp);
  7166. } else {
  7167. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7168. error = EINVAL;
  7169. }
  7170. }
  7171. break;
  7172. }
  7173. case SCTP_PR_SUPPORTED:
  7174. {
  7175. struct sctp_assoc_value *av;
  7176. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7177. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7178. if (stcb) {
  7179. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7180. error = EINVAL;
  7181. SCTP_TCB_UNLOCK(stcb);
  7182. } else {
  7183. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7184. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7185. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7186. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7187. SCTP_INP_WLOCK(inp);
  7188. if (av->assoc_value == 0) {
  7189. inp->prsctp_supported = 0;
  7190. } else {
  7191. inp->prsctp_supported = 1;
  7192. }
  7193. SCTP_INP_WUNLOCK(inp);
  7194. } else {
  7195. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7196. error = EINVAL;
  7197. }
  7198. }
  7199. break;
  7200. }
  7201. case SCTP_AUTH_SUPPORTED:
  7202. {
  7203. struct sctp_assoc_value *av;
  7204. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7205. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7206. if (stcb) {
  7207. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7208. error = EINVAL;
  7209. SCTP_TCB_UNLOCK(stcb);
  7210. } else {
  7211. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7212. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7213. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7214. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7215. if ((av->assoc_value == 0) &&
  7216. (inp->asconf_supported == 1)) {
  7217. /* AUTH is required for ASCONF */
  7218. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7219. error = EINVAL;
  7220. } else {
  7221. SCTP_INP_WLOCK(inp);
  7222. if (av->assoc_value == 0) {
  7223. inp->auth_supported = 0;
  7224. } else {
  7225. inp->auth_supported = 1;
  7226. }
  7227. SCTP_INP_WUNLOCK(inp);
  7228. }
  7229. } else {
  7230. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7231. error = EINVAL;
  7232. }
  7233. }
  7234. break;
  7235. }
  7236. case SCTP_ASCONF_SUPPORTED:
  7237. {
  7238. struct sctp_assoc_value *av;
  7239. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7240. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7241. if (stcb) {
  7242. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7243. error = EINVAL;
  7244. SCTP_TCB_UNLOCK(stcb);
  7245. } else {
  7246. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7247. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7248. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7249. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7250. if ((av->assoc_value != 0) &&
  7251. (inp->auth_supported == 0)) {
  7252. /* AUTH is required for ASCONF */
  7253. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7254. error = EINVAL;
  7255. } else {
  7256. SCTP_INP_WLOCK(inp);
  7257. if (av->assoc_value == 0) {
  7258. inp->asconf_supported = 0;
  7259. sctp_auth_delete_chunk(SCTP_ASCONF,
  7260. inp->sctp_ep.local_auth_chunks);
  7261. sctp_auth_delete_chunk(SCTP_ASCONF_ACK,
  7262. inp->sctp_ep.local_auth_chunks);
  7263. } else {
  7264. inp->asconf_supported = 1;
  7265. sctp_auth_add_chunk(SCTP_ASCONF,
  7266. inp->sctp_ep.local_auth_chunks);
  7267. sctp_auth_add_chunk(SCTP_ASCONF_ACK,
  7268. inp->sctp_ep.local_auth_chunks);
  7269. }
  7270. SCTP_INP_WUNLOCK(inp);
  7271. }
  7272. } else {
  7273. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7274. error = EINVAL;
  7275. }
  7276. }
  7277. break;
  7278. }
  7279. case SCTP_RECONFIG_SUPPORTED:
  7280. {
  7281. struct sctp_assoc_value *av;
  7282. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7283. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7284. if (stcb) {
  7285. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7286. error = EINVAL;
  7287. SCTP_TCB_UNLOCK(stcb);
  7288. } else {
  7289. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7290. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7291. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7292. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7293. SCTP_INP_WLOCK(inp);
  7294. if (av->assoc_value == 0) {
  7295. inp->reconfig_supported = 0;
  7296. } else {
  7297. inp->reconfig_supported = 1;
  7298. }
  7299. SCTP_INP_WUNLOCK(inp);
  7300. } else {
  7301. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7302. error = EINVAL;
  7303. }
  7304. }
  7305. break;
  7306. }
  7307. case SCTP_NRSACK_SUPPORTED:
  7308. {
  7309. struct sctp_assoc_value *av;
  7310. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7311. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7312. if (stcb) {
  7313. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7314. error = EINVAL;
  7315. SCTP_TCB_UNLOCK(stcb);
  7316. } else {
  7317. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7318. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7319. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7320. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7321. SCTP_INP_WLOCK(inp);
  7322. if (av->assoc_value == 0) {
  7323. inp->nrsack_supported = 0;
  7324. } else {
  7325. inp->nrsack_supported = 1;
  7326. }
  7327. SCTP_INP_WUNLOCK(inp);
  7328. } else {
  7329. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7330. error = EINVAL;
  7331. }
  7332. }
  7333. break;
  7334. }
  7335. case SCTP_PKTDROP_SUPPORTED:
  7336. {
  7337. struct sctp_assoc_value *av;
  7338. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7339. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7340. if (stcb) {
  7341. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7342. error = EINVAL;
  7343. SCTP_TCB_UNLOCK(stcb);
  7344. } else {
  7345. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7346. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7347. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7348. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7349. SCTP_INP_WLOCK(inp);
  7350. if (av->assoc_value == 0) {
  7351. inp->pktdrop_supported = 0;
  7352. } else {
  7353. inp->pktdrop_supported = 1;
  7354. }
  7355. SCTP_INP_WUNLOCK(inp);
  7356. } else {
  7357. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7358. error = EINVAL;
  7359. }
  7360. }
  7361. break;
  7362. }
  7363. case SCTP_MAX_CWND:
  7364. {
  7365. struct sctp_assoc_value *av;
  7366. struct sctp_nets *net;
  7367. SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
  7368. SCTP_FIND_STCB(inp, stcb, av->assoc_id);
  7369. if (stcb) {
  7370. stcb->asoc.max_cwnd = av->assoc_value;
  7371. if (stcb->asoc.max_cwnd > 0) {
  7372. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  7373. if ((net->cwnd > stcb->asoc.max_cwnd) &&
  7374. (net->cwnd > (net->mtu - sizeof(struct sctphdr)))) {
  7375. net->cwnd = stcb->asoc.max_cwnd;
  7376. if (net->cwnd < (net->mtu - sizeof(struct sctphdr))) {
  7377. net->cwnd = net->mtu - sizeof(struct sctphdr);
  7378. }
  7379. }
  7380. }
  7381. }
  7382. SCTP_TCB_UNLOCK(stcb);
  7383. } else {
  7384. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
  7385. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
  7386. ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) &&
  7387. (av->assoc_id == SCTP_FUTURE_ASSOC))) {
  7388. SCTP_INP_WLOCK(inp);
  7389. inp->max_cwnd = av->assoc_value;
  7390. SCTP_INP_WUNLOCK(inp);
  7391. } else {
  7392. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7393. error = EINVAL;
  7394. }
  7395. }
  7396. break;
  7397. }
  7398. default:
  7399. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
  7400. error = ENOPROTOOPT;
  7401. break;
  7402. } /* end switch (opt) */
  7403. return (error);
  7404. }
  7405. #if !defined(__Userspace__)
  7406. int
  7407. sctp_ctloutput(struct socket *so, struct sockopt *sopt)
  7408. {
  7409. #if defined(__FreeBSD__)
  7410. struct epoch_tracker et;
  7411. struct sctp_inpcb *inp;
  7412. #endif
  7413. void *optval = NULL;
  7414. void *p;
  7415. size_t optsize = 0;
  7416. int error = 0;
  7417. #if defined(__FreeBSD__)
  7418. if ((sopt->sopt_level == SOL_SOCKET) &&
  7419. (sopt->sopt_name == SO_SETFIB)) {
  7420. inp = (struct sctp_inpcb *)so->so_pcb;
  7421. if (inp == NULL) {
  7422. SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
  7423. return (EINVAL);
  7424. }
  7425. SCTP_INP_WLOCK(inp);
  7426. inp->fibnum = so->so_fibnum;
  7427. SCTP_INP_WUNLOCK(inp);
  7428. return (0);
  7429. }
  7430. #endif
  7431. if (sopt->sopt_level != IPPROTO_SCTP) {
  7432. /* wrong proto level... send back up to IP */
  7433. #ifdef INET6
  7434. if (INP_CHECK_SOCKAF(so, AF_INET6))
  7435. error = ip6_ctloutput(so, sopt);
  7436. #endif /* INET6 */
  7437. #if defined(INET) && defined(INET6)
  7438. else
  7439. #endif
  7440. #ifdef INET
  7441. error = ip_ctloutput(so, sopt);
  7442. #endif
  7443. return (error);
  7444. }
  7445. optsize = sopt->sopt_valsize;
  7446. if (optsize > SCTP_SOCKET_OPTION_LIMIT) {
  7447. SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
  7448. return (ENOBUFS);
  7449. }
  7450. if (optsize) {
  7451. SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT);
  7452. if (optval == NULL) {
  7453. SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOBUFS);
  7454. return (ENOBUFS);
  7455. }
  7456. error = sooptcopyin(sopt, optval, optsize, optsize);
  7457. if (error) {
  7458. SCTP_FREE(optval, SCTP_M_SOCKOPT);
  7459. goto out;
  7460. }
  7461. }
  7462. #if defined(__FreeBSD__) || defined(_WIN32)
  7463. p = (void *)sopt->sopt_td;
  7464. #else
  7465. p = (void *)sopt->sopt_p;
  7466. #endif
  7467. if (sopt->sopt_dir == SOPT_SET) {
  7468. #if defined(__FreeBSD__)
  7469. NET_EPOCH_ENTER(et);
  7470. #endif
  7471. error = sctp_setopt(so, sopt->sopt_name, optval, optsize, p);
  7472. #if defined(__FreeBSD__)
  7473. NET_EPOCH_EXIT(et);
  7474. #endif
  7475. } else if (sopt->sopt_dir == SOPT_GET) {
  7476. error = sctp_getopt(so, sopt->sopt_name, optval, &optsize, p);
  7477. } else {
  7478. SCTP_LTRACE_ERR_RET(so->so_pcb, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7479. error = EINVAL;
  7480. }
  7481. if ((error == 0) && (optval != NULL)) {
  7482. error = sooptcopyout(sopt, optval, optsize);
  7483. SCTP_FREE(optval, SCTP_M_SOCKOPT);
  7484. } else if (optval != NULL) {
  7485. SCTP_FREE(optval, SCTP_M_SOCKOPT);
  7486. }
  7487. out:
  7488. return (error);
  7489. }
  7490. #endif
  7491. #ifdef INET
  7492. #if defined(__Userspace__)
  7493. int
  7494. sctp_connect(struct socket *so, struct sockaddr *addr)
  7495. {
  7496. void *p = NULL;
  7497. #elif defined(__FreeBSD__)
  7498. static int
  7499. sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
  7500. {
  7501. #elif defined(__APPLE__)
  7502. static int
  7503. sctp_connect(struct socket *so, struct sockaddr *addr, struct proc *p)
  7504. {
  7505. #elif defined(_WIN32)
  7506. static int
  7507. sctp_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p)
  7508. {
  7509. #else
  7510. static int
  7511. sctp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
  7512. {
  7513. struct sockaddr *addr = mtod(nam, struct sockaddr *);
  7514. #endif
  7515. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7516. struct epoch_tracker et;
  7517. #endif
  7518. #ifdef SCTP_MVRF
  7519. int i, fnd = 0;
  7520. #endif
  7521. int error = 0;
  7522. int create_lock_on = 0;
  7523. uint32_t vrf_id;
  7524. struct sctp_inpcb *inp;
  7525. struct sctp_tcb *stcb = NULL;
  7526. inp = (struct sctp_inpcb *)so->so_pcb;
  7527. if (inp == NULL) {
  7528. /* I made the same as TCP since we are not setup? */
  7529. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7530. return (ECONNRESET);
  7531. }
  7532. if (addr == NULL) {
  7533. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7534. return EINVAL;
  7535. }
  7536. #if defined(__Userspace__)
  7537. /* TODO __Userspace__ falls into this code for IPv6 stuff at the moment... */
  7538. #endif
  7539. #if !defined(_WIN32) && !defined(__linux__) && !defined(__EMSCRIPTEN__)
  7540. switch (addr->sa_family) {
  7541. #ifdef INET6
  7542. case AF_INET6:
  7543. {
  7544. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7545. struct sockaddr_in6 *sin6;
  7546. #endif
  7547. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  7548. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7549. return (EINVAL);
  7550. }
  7551. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7552. sin6 = (struct sockaddr_in6 *)addr;
  7553. if (p != NULL && (error = prison_remote_ip6(p->td_ucred, &sin6->sin6_addr)) != 0) {
  7554. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  7555. return (error);
  7556. }
  7557. #endif
  7558. break;
  7559. }
  7560. #endif
  7561. #ifdef INET
  7562. case AF_INET:
  7563. {
  7564. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7565. struct sockaddr_in *sin;
  7566. #endif
  7567. #if !defined(_WIN32)
  7568. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  7569. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7570. return (EINVAL);
  7571. }
  7572. #endif
  7573. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7574. sin = (struct sockaddr_in *)addr;
  7575. if (p != NULL && (error = prison_remote_ip4(p->td_ucred, &sin->sin_addr)) != 0) {
  7576. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  7577. return (error);
  7578. }
  7579. #endif
  7580. break;
  7581. }
  7582. #endif
  7583. default:
  7584. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  7585. return (EAFNOSUPPORT);
  7586. }
  7587. #endif
  7588. SCTP_INP_INCR_REF(inp);
  7589. SCTP_ASOC_CREATE_LOCK(inp);
  7590. create_lock_on = 1;
  7591. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7592. NET_EPOCH_ENTER(et);
  7593. #endif
  7594. if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
  7595. (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
  7596. /* Should I really unlock ? */
  7597. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
  7598. error = EFAULT;
  7599. goto out_now;
  7600. }
  7601. #ifdef INET6
  7602. if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
  7603. (addr->sa_family == AF_INET6)) {
  7604. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7605. error = EINVAL;
  7606. goto out_now;
  7607. }
  7608. #endif
  7609. #if defined(__Userspace__)
  7610. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) &&
  7611. (addr->sa_family != AF_CONN)) {
  7612. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7613. error = EINVAL;
  7614. goto out_now;
  7615. }
  7616. #endif
  7617. if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
  7618. /* Bind a ephemeral port */
  7619. error = sctp_inpcb_bind(so, NULL, NULL, p);
  7620. if (error) {
  7621. goto out_now;
  7622. }
  7623. }
  7624. /* Now do we connect? */
  7625. if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
  7626. (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
  7627. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7628. error = EINVAL;
  7629. goto out_now;
  7630. }
  7631. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  7632. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  7633. /* We are already connected AND the TCP model */
  7634. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
  7635. error = EADDRINUSE;
  7636. goto out_now;
  7637. }
  7638. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  7639. SCTP_INP_RLOCK(inp);
  7640. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  7641. SCTP_INP_RUNLOCK(inp);
  7642. } else {
  7643. /* We increment here since sctp_findassociation_ep_addr() will
  7644. * do a decrement if it finds the stcb as long as the locked
  7645. * tcb (last argument) is NOT a TCB.. aka NULL.
  7646. */
  7647. SCTP_INP_INCR_REF(inp);
  7648. stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
  7649. if (stcb == NULL) {
  7650. SCTP_INP_DECR_REF(inp);
  7651. } else {
  7652. SCTP_TCB_UNLOCK(stcb);
  7653. }
  7654. }
  7655. if (stcb != NULL) {
  7656. /* Already have or am bring up an association */
  7657. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  7658. error = EALREADY;
  7659. goto out_now;
  7660. }
  7661. vrf_id = inp->def_vrf_id;
  7662. #ifdef SCTP_MVRF
  7663. for (i = 0; i < inp->num_vrfs; i++) {
  7664. if (vrf_id == inp->m_vrf_ids[i]) {
  7665. fnd = 1;
  7666. break;
  7667. }
  7668. }
  7669. if (!fnd) {
  7670. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7671. error = EINVAL;
  7672. goto out_now;
  7673. }
  7674. #endif
  7675. /* We are GOOD to go */
  7676. stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
  7677. inp->sctp_ep.pre_open_stream_count,
  7678. inp->sctp_ep.port, p,
  7679. SCTP_INITIALIZE_AUTH_PARAMS);
  7680. if (stcb == NULL) {
  7681. /* Gak! no memory */
  7682. goto out_now;
  7683. }
  7684. SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
  7685. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  7686. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  7687. SCTP_TCB_UNLOCK(stcb);
  7688. out_now:
  7689. #if defined(__FreeBSD__) && !defined(__Userspace__)
  7690. NET_EPOCH_EXIT(et);
  7691. #endif
  7692. if (create_lock_on) {
  7693. SCTP_ASOC_CREATE_UNLOCK(inp);
  7694. }
  7695. SCTP_INP_DECR_REF(inp);
  7696. return (error);
  7697. }
  7698. #endif
  7699. #if defined(__Userspace__)
  7700. int
  7701. sctpconn_connect(struct socket *so, struct sockaddr *addr)
  7702. {
  7703. #ifdef SCTP_MVRF
  7704. int i, fnd = 0;
  7705. #endif
  7706. void *p = NULL;
  7707. int error = 0;
  7708. int create_lock_on = 0;
  7709. uint32_t vrf_id;
  7710. struct sctp_inpcb *inp;
  7711. struct sctp_tcb *stcb = NULL;
  7712. inp = (struct sctp_inpcb *)so->so_pcb;
  7713. if (inp == NULL) {
  7714. /* I made the same as TCP since we are not setup? */
  7715. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7716. return (ECONNRESET);
  7717. }
  7718. if (addr == NULL) {
  7719. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7720. return EINVAL;
  7721. }
  7722. switch (addr->sa_family) {
  7723. #ifdef INET
  7724. case AF_INET:
  7725. #ifdef HAVE_SA_LEN
  7726. if (addr->sa_len != sizeof(struct sockaddr_in)) {
  7727. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7728. return (EINVAL);
  7729. }
  7730. #endif
  7731. break;
  7732. #endif
  7733. #ifdef INET6
  7734. case AF_INET6:
  7735. #ifdef HAVE_SA_LEN
  7736. if (addr->sa_len != sizeof(struct sockaddr_in6)) {
  7737. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7738. return (EINVAL);
  7739. }
  7740. #endif
  7741. break;
  7742. #endif
  7743. case AF_CONN:
  7744. #ifdef HAVE_SA_LEN
  7745. if (addr->sa_len != sizeof(struct sockaddr_conn)) {
  7746. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7747. return (EINVAL);
  7748. }
  7749. #endif
  7750. break;
  7751. default:
  7752. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  7753. return (EAFNOSUPPORT);
  7754. }
  7755. SCTP_INP_INCR_REF(inp);
  7756. SCTP_ASOC_CREATE_LOCK(inp);
  7757. create_lock_on = 1;
  7758. if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
  7759. (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
  7760. /* Should I really unlock ? */
  7761. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EFAULT);
  7762. error = EFAULT;
  7763. goto out_now;
  7764. }
  7765. #ifdef INET6
  7766. if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
  7767. (addr->sa_family == AF_INET6)) {
  7768. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7769. error = EINVAL;
  7770. goto out_now;
  7771. }
  7772. #endif
  7773. if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
  7774. /* Bind a ephemeral port */
  7775. error = sctp_inpcb_bind(so, NULL, NULL, p);
  7776. if (error) {
  7777. goto out_now;
  7778. }
  7779. }
  7780. /* Now do we connect? */
  7781. if ((inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) &&
  7782. (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_PORTREUSE))) {
  7783. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7784. error = EINVAL;
  7785. goto out_now;
  7786. }
  7787. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  7788. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  7789. /* We are already connected AND the TCP model */
  7790. SCTP_LTRACE_ERR_RET(inp, stcb, NULL, SCTP_FROM_SCTP_USRREQ, EADDRINUSE);
  7791. error = EADDRINUSE;
  7792. goto out_now;
  7793. }
  7794. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  7795. SCTP_INP_RLOCK(inp);
  7796. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  7797. SCTP_INP_RUNLOCK(inp);
  7798. } else {
  7799. /* We increment here since sctp_findassociation_ep_addr() will
  7800. * do a decrement if it finds the stcb as long as the locked
  7801. * tcb (last argument) is NOT a TCB.. aka NULL.
  7802. */
  7803. SCTP_INP_INCR_REF(inp);
  7804. stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL);
  7805. if (stcb == NULL) {
  7806. SCTP_INP_DECR_REF(inp);
  7807. } else {
  7808. SCTP_TCB_UNLOCK(stcb);
  7809. }
  7810. }
  7811. if (stcb != NULL) {
  7812. /* Already have or am bring up an association */
  7813. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EALREADY);
  7814. error = EALREADY;
  7815. goto out_now;
  7816. }
  7817. vrf_id = inp->def_vrf_id;
  7818. #ifdef SCTP_MVRF
  7819. for (i = 0; i < inp->num_vrfs; i++) {
  7820. if (vrf_id == inp->m_vrf_ids[i]) {
  7821. fnd = 1;
  7822. break;
  7823. }
  7824. }
  7825. if (!fnd) {
  7826. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7827. error = EINVAL;
  7828. goto out_now;
  7829. }
  7830. #endif
  7831. /* We are GOOD to go */
  7832. stcb = sctp_aloc_assoc_connected(inp, addr, &error, 0, 0, vrf_id,
  7833. inp->sctp_ep.pre_open_stream_count,
  7834. inp->sctp_ep.port, p,
  7835. SCTP_INITIALIZE_AUTH_PARAMS);
  7836. if (stcb == NULL) {
  7837. /* Gak! no memory */
  7838. goto out_now;
  7839. }
  7840. SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
  7841. (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
  7842. sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
  7843. SCTP_TCB_UNLOCK(stcb);
  7844. out_now:
  7845. if (create_lock_on) {
  7846. SCTP_ASOC_CREATE_UNLOCK(inp);
  7847. }
  7848. SCTP_INP_DECR_REF(inp);
  7849. return (error);
  7850. }
  7851. #endif
  7852. int
  7853. #if defined(__Userspace__)
  7854. sctp_listen(struct socket *so, int backlog, struct proc *p)
  7855. #elif defined(__FreeBSD__)
  7856. sctp_listen(struct socket *so, int backlog, struct thread *p)
  7857. #elif defined(_WIN32)
  7858. sctp_listen(struct socket *so, int backlog, PKTHREAD p)
  7859. #else
  7860. sctp_listen(struct socket *so, struct proc *p)
  7861. #endif
  7862. {
  7863. /*
  7864. * Note this module depends on the protocol processing being called
  7865. * AFTER any socket level flags and backlog are applied to the
  7866. * socket. The traditional way that the socket flags are applied is
  7867. * AFTER protocol processing. We have made a change to the
  7868. * sys/kern/uipc_socket.c module to reverse this but this MUST be in
  7869. * place if the socket API for SCTP is to work properly.
  7870. */
  7871. int error = 0;
  7872. struct sctp_inpcb *inp;
  7873. inp = (struct sctp_inpcb *)so->so_pcb;
  7874. if (inp == NULL) {
  7875. /* I made the same as TCP since we are not setup? */
  7876. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  7877. return (ECONNRESET);
  7878. }
  7879. if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) {
  7880. /* See if we have a listener */
  7881. struct sctp_inpcb *tinp;
  7882. union sctp_sockstore store;
  7883. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
  7884. /* not bound all */
  7885. struct sctp_laddr *laddr;
  7886. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  7887. memcpy(&store, &laddr->ifa->address, sizeof(store));
  7888. switch (store.sa.sa_family) {
  7889. #ifdef INET
  7890. case AF_INET:
  7891. store.sin.sin_port = inp->sctp_lport;
  7892. break;
  7893. #endif
  7894. #ifdef INET6
  7895. case AF_INET6:
  7896. store.sin6.sin6_port = inp->sctp_lport;
  7897. break;
  7898. #endif
  7899. #if defined(__Userspace__)
  7900. case AF_CONN:
  7901. store.sconn.sconn_port = inp->sctp_lport;
  7902. break;
  7903. #endif
  7904. default:
  7905. break;
  7906. }
  7907. tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
  7908. if (tinp && (tinp != inp) &&
  7909. ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
  7910. ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  7911. (SCTP_IS_LISTENING(tinp))) {
  7912. /* we have a listener already and its not this inp. */
  7913. SCTP_INP_DECR_REF(tinp);
  7914. return (EADDRINUSE);
  7915. } else if (tinp) {
  7916. SCTP_INP_DECR_REF(tinp);
  7917. }
  7918. }
  7919. } else {
  7920. /* Setup a local addr bound all */
  7921. memset(&store, 0, sizeof(store));
  7922. #ifdef INET6
  7923. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
  7924. store.sa.sa_family = AF_INET6;
  7925. #ifdef HAVE_SA_LEN
  7926. store.sa.sa_len = sizeof(struct sockaddr_in6);
  7927. #endif
  7928. }
  7929. #endif
  7930. #if defined(__Userspace__)
  7931. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) {
  7932. store.sa.sa_family = AF_CONN;
  7933. #ifdef HAVE_SA_LEN
  7934. store.sa.sa_len = sizeof(struct sockaddr_conn);
  7935. #endif
  7936. }
  7937. #endif
  7938. #ifdef INET
  7939. #if defined(__Userspace__)
  7940. if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) &&
  7941. ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) {
  7942. #else
  7943. if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
  7944. #endif
  7945. store.sa.sa_family = AF_INET;
  7946. #ifdef HAVE_SA_LEN
  7947. store.sa.sa_len = sizeof(struct sockaddr_in);
  7948. #endif
  7949. }
  7950. #endif
  7951. switch (store.sa.sa_family) {
  7952. #ifdef INET
  7953. case AF_INET:
  7954. store.sin.sin_port = inp->sctp_lport;
  7955. break;
  7956. #endif
  7957. #ifdef INET6
  7958. case AF_INET6:
  7959. store.sin6.sin6_port = inp->sctp_lport;
  7960. break;
  7961. #endif
  7962. #if defined(__Userspace__)
  7963. case AF_CONN:
  7964. store.sconn.sconn_port = inp->sctp_lport;
  7965. break;
  7966. #endif
  7967. default:
  7968. break;
  7969. }
  7970. tinp = sctp_pcb_findep(&store.sa, 0, 0, inp->def_vrf_id);
  7971. if (tinp && (tinp != inp) &&
  7972. ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) == 0) &&
  7973. ((tinp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
  7974. (SCTP_IS_LISTENING(tinp))) {
  7975. /* we have a listener already and its not this inp. */
  7976. SCTP_INP_DECR_REF(tinp);
  7977. return (EADDRINUSE);
  7978. } else if (tinp) {
  7979. SCTP_INP_DECR_REF(tinp);
  7980. }
  7981. }
  7982. }
  7983. SCTP_INP_INFO_WLOCK();
  7984. SCTP_INP_WLOCK(inp);
  7985. #ifdef SCTP_LOCK_LOGGING
  7986. if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOCK_LOGGING_ENABLE) {
  7987. sctp_log_lock(inp, (struct sctp_tcb *)NULL, SCTP_LOG_LOCK_SOCK);
  7988. }
  7989. #endif
  7990. if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) &&
  7991. (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
  7992. /* The unlucky case
  7993. * - We are in the tcp pool with this guy.
  7994. * - Someone else is in the main inp slot.
  7995. * - We must move this guy (the listener) to the main slot
  7996. * - We must then move the guy that was listener to the TCP Pool.
  7997. */
  7998. if (sctp_swap_inpcb_for_listen(inp)) {
  7999. error = EADDRINUSE;
  8000. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  8001. goto out;
  8002. }
  8003. }
  8004. #if defined(__FreeBSD__) || defined(__Userspace__)
  8005. SOCK_LOCK(so);
  8006. error = solisten_proto_check(so);
  8007. if (error) {
  8008. SOCK_UNLOCK(so);
  8009. goto out;
  8010. }
  8011. #endif
  8012. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  8013. (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) {
  8014. SOCK_UNLOCK(so);
  8015. #if defined(__FreeBSD__) && !defined(__Userspace__)
  8016. solisten_proto_abort(so);
  8017. #endif
  8018. error = EADDRINUSE;
  8019. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  8020. goto out;
  8021. }
  8022. if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
  8023. ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) ||
  8024. (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED))) {
  8025. SOCK_UNLOCK(so);
  8026. #if defined(__FreeBSD__) && !defined(__Userspace__)
  8027. solisten_proto_abort(so);
  8028. #endif
  8029. error = EINVAL;
  8030. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, error);
  8031. goto out;
  8032. }
  8033. if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
  8034. if ((error = sctp_inpcb_bind_locked(inp, NULL, NULL, p))) {
  8035. SOCK_UNLOCK(so);
  8036. #if defined(__FreeBSD__) && !defined(__Userspace__)
  8037. solisten_proto_abort(so);
  8038. #endif
  8039. /* bind error, probably perm */
  8040. goto out;
  8041. }
  8042. }
  8043. #if defined(__FreeBSD__) && !defined(__Userspace__)
  8044. if ((inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) == 0) {
  8045. solisten_proto(so, backlog);
  8046. SOCK_UNLOCK(so);
  8047. inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
  8048. } else {
  8049. solisten_proto_abort(so);
  8050. SOCK_UNLOCK(so);
  8051. if (backlog > 0) {
  8052. inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
  8053. } else {
  8054. inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
  8055. }
  8056. }
  8057. #elif defined(_WIN32) || defined(__Userspace__)
  8058. solisten_proto(so, backlog);
  8059. #endif
  8060. #if !(defined(__FreeBSD__) && !defined(__Userspace__))
  8061. if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
  8062. /* remove the ACCEPTCONN flag for one-to-many sockets */
  8063. #if defined(__Userspace__)
  8064. so->so_options &= ~SCTP_SO_ACCEPTCONN;
  8065. #else
  8066. so->so_options &= ~SO_ACCEPTCONN;
  8067. #endif
  8068. }
  8069. SOCK_UNLOCK(so);
  8070. if (backlog > 0) {
  8071. inp->sctp_flags |= SCTP_PCB_FLAGS_ACCEPTING;
  8072. } else {
  8073. inp->sctp_flags &= ~SCTP_PCB_FLAGS_ACCEPTING;
  8074. }
  8075. #endif
  8076. out:
  8077. SCTP_INP_WUNLOCK(inp);
  8078. SCTP_INP_INFO_WUNLOCK();
  8079. return (error);
  8080. }
  8081. static int sctp_defered_wakeup_cnt = 0;
  8082. int
  8083. sctp_accept(struct socket *so, struct sockaddr **addr)
  8084. {
  8085. struct sctp_tcb *stcb;
  8086. struct sctp_inpcb *inp;
  8087. union sctp_sockstore store;
  8088. #ifdef INET6
  8089. #if defined(SCTP_KAME) && defined(SCTP_EMBEDDED_V6_SCOPE)
  8090. int error;
  8091. #endif
  8092. #endif
  8093. inp = (struct sctp_inpcb *)so->so_pcb;
  8094. if (inp == NULL) {
  8095. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8096. return (ECONNRESET);
  8097. }
  8098. SCTP_INP_WLOCK(inp);
  8099. if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
  8100. SCTP_INP_WUNLOCK(inp);
  8101. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
  8102. return (EOPNOTSUPP);
  8103. }
  8104. if (so->so_state & SS_ISDISCONNECTED) {
  8105. SCTP_INP_WUNLOCK(inp);
  8106. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED);
  8107. return (ECONNABORTED);
  8108. }
  8109. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  8110. if (stcb == NULL) {
  8111. SCTP_INP_WUNLOCK(inp);
  8112. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8113. return (ECONNRESET);
  8114. }
  8115. SCTP_TCB_LOCK(stcb);
  8116. store = stcb->asoc.primary_destination->ro._l_addr;
  8117. SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
  8118. /* Wake any delayed sleep action */
  8119. if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
  8120. inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
  8121. if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
  8122. inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
  8123. SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
  8124. if (sowriteable(inp->sctp_socket)) {
  8125. #if defined(__Userspace__)
  8126. /*__Userspace__ calling sowwakup_locked because of SOCKBUF_LOCK above. */
  8127. #endif
  8128. #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
  8129. sowwakeup_locked(inp->sctp_socket);
  8130. #else
  8131. #if defined(__APPLE__)
  8132. /* socket is locked */
  8133. #endif
  8134. sowwakeup(inp->sctp_socket);
  8135. #endif
  8136. } else {
  8137. SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
  8138. }
  8139. }
  8140. if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
  8141. inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
  8142. SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
  8143. if (soreadable(inp->sctp_socket)) {
  8144. sctp_defered_wakeup_cnt++;
  8145. #if defined(__Userspace__)
  8146. /*__Userspace__ calling sorwakup_locked because of SOCKBUF_LOCK above */
  8147. #endif
  8148. #if defined(__FreeBSD__) || defined(_WIN32) || defined(__Userspace__)
  8149. sorwakeup_locked(inp->sctp_socket);
  8150. #else
  8151. #if defined(__APPLE__)
  8152. /* socket is locked */
  8153. #endif
  8154. sorwakeup(inp->sctp_socket);
  8155. #endif
  8156. } else {
  8157. SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
  8158. }
  8159. }
  8160. }
  8161. SCTP_INP_WUNLOCK(inp);
  8162. if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
  8163. sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
  8164. SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19);
  8165. } else {
  8166. SCTP_TCB_UNLOCK(stcb);
  8167. }
  8168. switch (store.sa.sa_family) {
  8169. #ifdef INET
  8170. case AF_INET:
  8171. {
  8172. struct sockaddr_in *sin;
  8173. SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
  8174. if (sin == NULL)
  8175. return (ENOMEM);
  8176. sin->sin_family = AF_INET;
  8177. #ifdef HAVE_SIN_LEN
  8178. sin->sin_len = sizeof(*sin);
  8179. #endif
  8180. sin->sin_port = store.sin.sin_port;
  8181. sin->sin_addr = store.sin.sin_addr;
  8182. *addr = (struct sockaddr *)sin;
  8183. break;
  8184. }
  8185. #endif
  8186. #ifdef INET6
  8187. case AF_INET6:
  8188. {
  8189. struct sockaddr_in6 *sin6;
  8190. SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
  8191. if (sin6 == NULL)
  8192. return (ENOMEM);
  8193. sin6->sin6_family = AF_INET6;
  8194. #ifdef HAVE_SIN6_LEN
  8195. sin6->sin6_len = sizeof(*sin6);
  8196. #endif
  8197. sin6->sin6_port = store.sin6.sin6_port;
  8198. sin6->sin6_addr = store.sin6.sin6_addr;
  8199. #if defined(SCTP_EMBEDDED_V6_SCOPE)
  8200. #ifdef SCTP_KAME
  8201. if ((error = sa6_recoverscope(sin6)) != 0) {
  8202. SCTP_FREE_SONAME(sin6);
  8203. return (error);
  8204. }
  8205. #else
  8206. if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
  8207. /*
  8208. * sin6->sin6_scope_id =
  8209. * ntohs(sin6->sin6_addr.s6_addr16[1]);
  8210. */
  8211. in6_recoverscope(sin6, &sin6->sin6_addr, NULL); /* skip ifp check */
  8212. else
  8213. sin6->sin6_scope_id = 0; /* XXX */
  8214. #endif /* SCTP_KAME */
  8215. #endif /* SCTP_EMBEDDED_V6_SCOPE */
  8216. *addr = (struct sockaddr *)sin6;
  8217. break;
  8218. }
  8219. #endif
  8220. #if defined(__Userspace__)
  8221. case AF_CONN:
  8222. {
  8223. struct sockaddr_conn *sconn;
  8224. SCTP_MALLOC_SONAME(sconn, struct sockaddr_conn *, sizeof(struct sockaddr_conn));
  8225. if (sconn == NULL) {
  8226. return (ENOMEM);
  8227. }
  8228. sconn->sconn_family = AF_CONN;
  8229. #ifdef HAVE_SCONN_LEN
  8230. sconn->sconn_len = sizeof(struct sockaddr_conn);
  8231. #endif
  8232. sconn->sconn_port = store.sconn.sconn_port;
  8233. sconn->sconn_addr = store.sconn.sconn_addr;
  8234. *addr = (struct sockaddr *)sconn;
  8235. break;
  8236. }
  8237. #endif
  8238. default:
  8239. /* TSNH */
  8240. break;
  8241. }
  8242. return (0);
  8243. }
  8244. #ifdef INET
  8245. int
  8246. #if !defined(__Userspace__)
  8247. sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
  8248. {
  8249. struct sockaddr_in *sin;
  8250. #else
  8251. sctp_ingetaddr(struct socket *so, struct mbuf *nam)
  8252. {
  8253. struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
  8254. #endif
  8255. uint32_t vrf_id;
  8256. struct sctp_inpcb *inp;
  8257. struct sctp_ifa *sctp_ifa;
  8258. /*
  8259. * Do the malloc first in case it blocks.
  8260. */
  8261. #if !defined(__Userspace__)
  8262. SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
  8263. if (sin == NULL)
  8264. return (ENOMEM);
  8265. #else
  8266. SCTP_BUF_LEN(nam) = sizeof(*sin);
  8267. memset(sin, 0, sizeof(*sin));
  8268. #endif
  8269. sin->sin_family = AF_INET;
  8270. #ifdef HAVE_SIN_LEN
  8271. sin->sin_len = sizeof(*sin);
  8272. #endif
  8273. inp = (struct sctp_inpcb *)so->so_pcb;
  8274. if (!inp) {
  8275. #if !defined(__Userspace__)
  8276. SCTP_FREE_SONAME(sin);
  8277. #endif
  8278. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8279. return (ECONNRESET);
  8280. }
  8281. SCTP_INP_RLOCK(inp);
  8282. sin->sin_port = inp->sctp_lport;
  8283. if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
  8284. if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
  8285. struct sctp_tcb *stcb;
  8286. struct sockaddr_in *sin_a;
  8287. struct sctp_nets *net;
  8288. int fnd;
  8289. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  8290. if (stcb == NULL) {
  8291. goto notConn;
  8292. }
  8293. fnd = 0;
  8294. sin_a = NULL;
  8295. SCTP_TCB_LOCK(stcb);
  8296. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  8297. sin_a = (struct sockaddr_in *)&net->ro._l_addr;
  8298. if (sin_a == NULL)
  8299. /* this will make coverity happy */
  8300. continue;
  8301. if (sin_a->sin_family == AF_INET) {
  8302. fnd = 1;
  8303. break;
  8304. }
  8305. }
  8306. if ((!fnd) || (sin_a == NULL)) {
  8307. /* punt */
  8308. SCTP_TCB_UNLOCK(stcb);
  8309. goto notConn;
  8310. }
  8311. vrf_id = inp->def_vrf_id;
  8312. sctp_ifa = sctp_source_address_selection(inp,
  8313. stcb,
  8314. (sctp_route_t *)&net->ro,
  8315. net, 0, vrf_id);
  8316. if (sctp_ifa) {
  8317. sin->sin_addr = sctp_ifa->address.sin.sin_addr;
  8318. sctp_free_ifa(sctp_ifa);
  8319. }
  8320. SCTP_TCB_UNLOCK(stcb);
  8321. } else {
  8322. /* For the bound all case you get back 0 */
  8323. notConn:
  8324. sin->sin_addr.s_addr = 0;
  8325. }
  8326. } else {
  8327. /* Take the first IPv4 address in the list */
  8328. struct sctp_laddr *laddr;
  8329. int fnd = 0;
  8330. LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
  8331. if (laddr->ifa->address.sa.sa_family == AF_INET) {
  8332. struct sockaddr_in *sin_a;
  8333. sin_a = &laddr->ifa->address.sin;
  8334. sin->sin_addr = sin_a->sin_addr;
  8335. fnd = 1;
  8336. break;
  8337. }
  8338. }
  8339. if (!fnd) {
  8340. #if !defined(__Userspace__)
  8341. SCTP_FREE_SONAME(sin);
  8342. #endif
  8343. SCTP_INP_RUNLOCK(inp);
  8344. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  8345. return (ENOENT);
  8346. }
  8347. }
  8348. SCTP_INP_RUNLOCK(inp);
  8349. #if !defined(__Userspace__)
  8350. (*addr) = (struct sockaddr *)sin;
  8351. #endif
  8352. return (0);
  8353. }
  8354. int
  8355. #if !defined(__Userspace__)
  8356. sctp_peeraddr(struct socket *so, struct sockaddr **addr)
  8357. {
  8358. struct sockaddr_in *sin;
  8359. #else
  8360. sctp_peeraddr(struct socket *so, struct mbuf *nam)
  8361. {
  8362. struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
  8363. #endif
  8364. int fnd;
  8365. struct sockaddr_in *sin_a;
  8366. struct sctp_inpcb *inp;
  8367. struct sctp_tcb *stcb;
  8368. struct sctp_nets *net;
  8369. /* Do the malloc first in case it blocks. */
  8370. #if !defined(__Userspace__)
  8371. SCTP_MALLOC_SONAME(sin, struct sockaddr_in *, sizeof *sin);
  8372. if (sin == NULL)
  8373. return (ENOMEM);
  8374. #else
  8375. SCTP_BUF_LEN(nam) = sizeof(*sin);
  8376. memset(sin, 0, sizeof(*sin));
  8377. #endif
  8378. sin->sin_family = AF_INET;
  8379. #ifdef HAVE_SIN_LEN
  8380. sin->sin_len = sizeof(*sin);
  8381. #endif
  8382. inp = (struct sctp_inpcb *)so->so_pcb;
  8383. if ((inp == NULL) ||
  8384. ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
  8385. /* UDP type and listeners will drop out here */
  8386. #if !defined(__Userspace__)
  8387. SCTP_FREE_SONAME(sin);
  8388. #endif
  8389. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
  8390. return (ENOTCONN);
  8391. }
  8392. SCTP_INP_RLOCK(inp);
  8393. stcb = LIST_FIRST(&inp->sctp_asoc_list);
  8394. if (stcb) {
  8395. SCTP_TCB_LOCK(stcb);
  8396. }
  8397. SCTP_INP_RUNLOCK(inp);
  8398. if (stcb == NULL) {
  8399. #if !defined(__Userspace__)
  8400. SCTP_FREE_SONAME(sin);
  8401. #endif
  8402. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8403. return (ECONNRESET);
  8404. }
  8405. fnd = 0;
  8406. TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  8407. sin_a = (struct sockaddr_in *)&net->ro._l_addr;
  8408. if (sin_a->sin_family == AF_INET) {
  8409. fnd = 1;
  8410. sin->sin_port = stcb->rport;
  8411. sin->sin_addr = sin_a->sin_addr;
  8412. break;
  8413. }
  8414. }
  8415. SCTP_TCB_UNLOCK(stcb);
  8416. if (!fnd) {
  8417. /* No IPv4 address */
  8418. #if !defined(__Userspace__)
  8419. SCTP_FREE_SONAME(sin);
  8420. #endif
  8421. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOENT);
  8422. return (ENOENT);
  8423. }
  8424. #if !defined(__Userspace__)
  8425. (*addr) = (struct sockaddr *)sin;
  8426. #endif
  8427. return (0);
  8428. }
  8429. #if !defined(__Userspace__)
  8430. struct pr_usrreqs sctp_usrreqs = {
  8431. #if defined(__FreeBSD__)
  8432. .pru_abort = sctp_abort,
  8433. .pru_accept = sctp_accept,
  8434. .pru_attach = sctp_attach,
  8435. .pru_bind = sctp_bind,
  8436. .pru_connect = sctp_connect,
  8437. .pru_control = in_control,
  8438. .pru_close = sctp_close,
  8439. .pru_detach = sctp_close,
  8440. .pru_sopoll = sopoll_generic,
  8441. .pru_flush = sctp_flush,
  8442. .pru_disconnect = sctp_disconnect,
  8443. .pru_listen = sctp_listen,
  8444. .pru_peeraddr = sctp_peeraddr,
  8445. .pru_send = sctp_sendm,
  8446. .pru_shutdown = sctp_shutdown,
  8447. .pru_sockaddr = sctp_ingetaddr,
  8448. .pru_sosend = sctp_sosend,
  8449. .pru_soreceive = sctp_soreceive
  8450. #elif defined(__APPLE__)
  8451. .pru_abort = sctp_abort,
  8452. .pru_accept = sctp_accept,
  8453. .pru_attach = sctp_attach,
  8454. .pru_bind = sctp_bind,
  8455. .pru_connect = sctp_connect,
  8456. .pru_connect2 = pru_connect2_notsupp,
  8457. .pru_control = in_control,
  8458. .pru_detach = sctp_detach,
  8459. .pru_disconnect = sctp_disconnect,
  8460. .pru_listen = sctp_listen,
  8461. .pru_peeraddr = sctp_peeraddr,
  8462. .pru_rcvd = NULL,
  8463. .pru_rcvoob = pru_rcvoob_notsupp,
  8464. .pru_send = sctp_sendm,
  8465. .pru_sense = pru_sense_null,
  8466. .pru_shutdown = sctp_shutdown,
  8467. .pru_sockaddr = sctp_ingetaddr,
  8468. .pru_sosend = sctp_sosend,
  8469. .pru_soreceive = sctp_soreceive,
  8470. .pru_sopoll = sopoll
  8471. #elif defined(_WIN32) && !defined(__Userspace__)
  8472. sctp_abort,
  8473. sctp_accept,
  8474. sctp_attach,
  8475. sctp_bind,
  8476. sctp_connect,
  8477. pru_connect2_notsupp,
  8478. NULL,
  8479. NULL,
  8480. sctp_disconnect,
  8481. sctp_listen,
  8482. sctp_peeraddr,
  8483. NULL,
  8484. pru_rcvoob_notsupp,
  8485. NULL,
  8486. pru_sense_null,
  8487. sctp_shutdown,
  8488. sctp_flush,
  8489. sctp_ingetaddr,
  8490. sctp_sosend,
  8491. sctp_soreceive,
  8492. sopoll_generic,
  8493. NULL,
  8494. sctp_close
  8495. #endif
  8496. };
  8497. #elif !defined(__Userspace__)
  8498. int
  8499. sctp_usrreq(so, req, m, nam, control)
  8500. struct socket *so;
  8501. int req;
  8502. struct mbuf *m, *nam, *control;
  8503. {
  8504. struct proc *p = curproc;
  8505. int error;
  8506. int family;
  8507. struct sctp_inpcb *inp = (struct sctp_inpcb *)so->so_pcb;
  8508. error = 0;
  8509. family = so->so_proto->pr_domain->dom_family;
  8510. if (req == PRU_CONTROL) {
  8511. switch (family) {
  8512. case PF_INET:
  8513. error = in_control(so, (long)m, (caddr_t)nam,
  8514. (struct ifnet *)control);
  8515. break;
  8516. #ifdef INET6
  8517. case PF_INET6:
  8518. error = in6_control(so, (long)m, (caddr_t)nam,
  8519. (struct ifnet *)control, p);
  8520. break;
  8521. #endif
  8522. default:
  8523. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  8524. error = EAFNOSUPPORT;
  8525. }
  8526. return (error);
  8527. }
  8528. switch (req) {
  8529. case PRU_ATTACH:
  8530. error = sctp_attach(so, family, p);
  8531. break;
  8532. case PRU_DETACH:
  8533. error = sctp_detach(so);
  8534. break;
  8535. case PRU_BIND:
  8536. if (nam == NULL) {
  8537. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8538. return (EINVAL);
  8539. }
  8540. error = sctp_bind(so, nam, p);
  8541. break;
  8542. case PRU_LISTEN:
  8543. error = sctp_listen(so, p);
  8544. break;
  8545. case PRU_CONNECT:
  8546. if (nam == NULL) {
  8547. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8548. return (EINVAL);
  8549. }
  8550. error = sctp_connect(so, nam, p);
  8551. break;
  8552. case PRU_DISCONNECT:
  8553. error = sctp_disconnect(so);
  8554. break;
  8555. case PRU_ACCEPT:
  8556. if (nam == NULL) {
  8557. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
  8558. return (EINVAL);
  8559. }
  8560. error = sctp_accept(so, nam);
  8561. break;
  8562. case PRU_SHUTDOWN:
  8563. error = sctp_shutdown(so);
  8564. break;
  8565. case PRU_RCVD:
  8566. /*
  8567. * For Open and Net BSD, this is real ugly. The mbuf *nam
  8568. * that is passed (by soreceive()) is the int flags c ast as
  8569. * a (mbuf *) yuck!
  8570. */
  8571. break;
  8572. case PRU_SEND:
  8573. /* Flags are ignored */
  8574. {
  8575. struct sockaddr *addr;
  8576. if (nam == NULL)
  8577. addr = NULL;
  8578. else
  8579. addr = mtod(nam, struct sockaddr *);
  8580. error = sctp_sendm(so, 0, m, addr, control, p);
  8581. }
  8582. break;
  8583. case PRU_ABORT:
  8584. error = sctp_abort(so);
  8585. break;
  8586. case PRU_SENSE:
  8587. error = 0;
  8588. break;
  8589. case PRU_RCVOOB:
  8590. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  8591. error = EAFNOSUPPORT;
  8592. break;
  8593. case PRU_SENDOOB:
  8594. SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
  8595. error = EAFNOSUPPORT;
  8596. break;
  8597. case PRU_PEERADDR:
  8598. error = sctp_peeraddr(so, nam);
  8599. break;
  8600. case PRU_SOCKADDR:
  8601. error = sctp_ingetaddr(so, nam);
  8602. break;
  8603. case PRU_SLOWTIMO:
  8604. error = 0;
  8605. break;
  8606. default:
  8607. break;
  8608. }
  8609. return (error);
  8610. }
  8611. #endif
  8612. #endif
  8613. #if defined(__Userspace__)
  8614. int
  8615. register_recv_cb(struct socket *so,
  8616. int (*receive_cb)(struct socket *sock, union sctp_sockstore addr, void *data,
  8617. size_t datalen, struct sctp_rcvinfo, int flags, void *ulp_info))
  8618. {
  8619. struct sctp_inpcb *inp;
  8620. inp = (struct sctp_inpcb *) so->so_pcb;
  8621. if (inp == NULL) {
  8622. return (0);
  8623. }
  8624. SCTP_INP_WLOCK(inp);
  8625. inp->recv_callback = receive_cb;
  8626. SCTP_INP_WUNLOCK(inp);
  8627. return (1);
  8628. }
  8629. int
  8630. register_send_cb(struct socket *so, uint32_t sb_threshold, int (*send_cb)(struct socket *sock, uint32_t sb_free, void *ulp_info))
  8631. {
  8632. struct sctp_inpcb *inp;
  8633. inp = (struct sctp_inpcb *) so->so_pcb;
  8634. if (inp == NULL) {
  8635. return (0);
  8636. }
  8637. SCTP_INP_WLOCK(inp);
  8638. inp->send_callback = send_cb;
  8639. inp->send_sb_threshold = sb_threshold;
  8640. SCTP_INP_WUNLOCK(inp);
  8641. /* FIXME change to current amount free. This will be the full buffer
  8642. * the first time this is registered but it could be only a portion
  8643. * of the send buffer if this is called a second time e.g. if the
  8644. * threshold changes.
  8645. */
  8646. return (1);
  8647. }
  8648. int
  8649. register_ulp_info (struct socket *so, void *ulp_info)
  8650. {
  8651. struct sctp_inpcb *inp;
  8652. inp = (struct sctp_inpcb *) so->so_pcb;
  8653. if (inp == NULL) {
  8654. return (0);
  8655. }
  8656. SCTP_INP_WLOCK(inp);
  8657. inp->ulp_info = ulp_info;
  8658. SCTP_INP_WUNLOCK(inp);
  8659. return (1);
  8660. }
  8661. int
  8662. retrieve_ulp_info (struct socket *so, void **pulp_info)
  8663. {
  8664. struct sctp_inpcb *inp;
  8665. if (pulp_info == NULL) {
  8666. return (0);
  8667. }
  8668. inp = (struct sctp_inpcb *) so->so_pcb;
  8669. if (inp == NULL) {
  8670. return (0);
  8671. }
  8672. SCTP_INP_RLOCK(inp);
  8673. *pulp_info = inp->ulp_info;
  8674. SCTP_INP_RUNLOCK(inp);
  8675. return (1);
  8676. }
  8677. #endif