dclib-network.c 147 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996
  1. /***************************************************************************
  2. * *
  3. * _____ ____ *
  4. * | __ \ / __ \ _ _ _____ *
  5. * | | \ \ / / \_\ | | | | _ \ *
  6. * | | \ \| | | | | | |_| | *
  7. * | | | || | | | | | ___/ *
  8. * | | / /| | __ | | | | _ \ *
  9. * | |__/ / \ \__/ / | |___| | |_| | *
  10. * |_____/ \____/ |_____|_|_____/ *
  11. * *
  12. * Wiimms source code library *
  13. * *
  14. ***************************************************************************
  15. * *
  16. * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
  17. * *
  18. ***************************************************************************
  19. * *
  20. * This library is free software; you can redistribute it and/or modify *
  21. * it under the terms of the GNU General Public License as published by *
  22. * the Free Software Foundation; either version 2 of the License, or *
  23. * (at your option) any later version. *
  24. * *
  25. * This library is distributed in the hope that it will be useful, *
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  28. * GNU General Public License for more details. *
  29. * *
  30. * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
  31. * *
  32. ***************************************************************************/
  33. #define _GNU_SOURCE 1
  34. #include <string.h>
  35. #include <netdb.h>
  36. #include <errno.h>
  37. #include <unistd.h>
  38. #include <errno.h>
  39. #include <poll.h>
  40. #include <signal.h>
  41. #include <unistd.h>
  42. #include <fcntl.h>
  43. #include <sys/types.h>
  44. #include <sys/socket.h>
  45. #include <sys/un.h>
  46. #include <netinet/in.h>
  47. #include <stddef.h>
  48. #include <ifaddrs.h>
  49. #include "dclib-network.h"
  50. #include "dclib-punycode.h"
  51. ///////////////////////////////////////////////////////////////////////////////
  52. #ifdef __APPLE__
  53. #ifndef SOCK_NONBLOCK
  54. #define SOCK_NONBLOCK 0
  55. #endif
  56. #endif
  57. #ifndef POLLRDHUP
  58. #define POLLRDHUP 0
  59. #endif
  60. //
  61. ///////////////////////////////////////////////////////////////////////////////
  62. /////////////// host name support ///////////////
  63. ///////////////////////////////////////////////////////////////////////////////
  64. bool ResolveHost
  65. (
  66. // returns TRUE, if a hostname is detected
  67. // if result is FALSE => check host->filename
  68. NetworkHost_t *host, // valid pointer to NetworkHost_t
  69. bool init_host, // true: initialize 'host'
  70. ccp name, // name to analyze
  71. int default_port, // use this as port, if no other is found
  72. bool check_filename, // true: check for unix filename
  73. bool store_name // true: setup 'host->name'
  74. )
  75. {
  76. return ResolveHostMem( host, init_host, MemByString(name),
  77. default_port, check_filename, store_name );
  78. }
  79. ///////////////////////////////////////////////////////////////////////////////
  80. bool ResolveHostMem
  81. (
  82. // returns TRUE, if a hostname is detected
  83. // if result is FALSE => check host->filename
  84. NetworkHost_t *host, // valid pointer to NetworkHost_t
  85. bool init_host, // true: initialize 'host'
  86. mem_t name, // name to analyze
  87. int default_port, // use this as port, if no other is found
  88. bool check_filename, // true: check for unix filename
  89. bool store_name // true: setup 'host->name'
  90. )
  91. {
  92. Setup_ConnectTCP_Hook(false);
  93. DASSERT(host);
  94. if (!init_host)
  95. FREE((char*)host->name);
  96. InitializeHost(host);
  97. host->port = default_port;
  98. if (check_filename)
  99. {
  100. mem_t res = CheckUnixSocketPathMem(name,0);
  101. host->filename = res.ptr;
  102. if (host->filename)
  103. return false;
  104. }
  105. char buf[1000];
  106. ccp ptr = name.ptr;
  107. ccp end = ptr + name.len;
  108. if ( ptr < end
  109. && ( *ptr >= 'a' && *ptr <= 'z' || *ptr >= 'A' && *ptr <= 'Z' ))
  110. {
  111. while ( ptr < end
  112. && ( *ptr >= 'a' && *ptr <= 'z'
  113. || *ptr >= 'A' && *ptr <= 'Z'
  114. || *ptr >= '0' && *ptr <= '9'
  115. || *ptr == '_' || *ptr == '-'
  116. ))
  117. {
  118. ptr++;
  119. }
  120. uint len = ptr - name.ptr;
  121. if ( len && len < sizeof(buf) && ptr+1 < end && *ptr == ':' && ptr[1] == '/' )
  122. {
  123. memcpy(buf,name.ptr,len);
  124. buf[len] = 0;
  125. struct servent *s = getservbyname(buf,0);
  126. if (s)
  127. {
  128. const int port = ntohs(s->s_port);
  129. if ( port > 0 )
  130. host->port = port;
  131. }
  132. ptr += 2;
  133. if ( *ptr == '/' )
  134. ptr++;
  135. name = BehindMem(name,ptr);
  136. check_filename = false;
  137. }
  138. else
  139. ptr = name.ptr;
  140. }
  141. while ( ptr < end
  142. && ( *ptr >= 'a' && *ptr <= 'z'
  143. || *ptr >= 'A' && *ptr <= 'Z'
  144. || *ptr >= '0' && *ptr <= '9'
  145. || *ptr == '_' || *ptr == '-' || *ptr == '.'
  146. ))
  147. {
  148. ptr++;
  149. }
  150. uint len = ptr - name.ptr;
  151. if ( len > 0 && len < sizeof(buf) )
  152. {
  153. memcpy(buf,name.ptr,len);
  154. buf[len] = 0;
  155. if (store_name)
  156. host->name = MEMDUP(buf,len);
  157. struct hostent *h = gethostbyname(buf);
  158. if ( h && h->h_addrtype == AF_INET && h->h_length == 4 )
  159. {
  160. host->ip4 = ntohl(*(u32*)h->h_addr_list[0]);
  161. host->ip4_valid = true;
  162. }
  163. if ( ptr < end && *ptr == ':' )
  164. {
  165. ccp pptr = ptr+1;
  166. if ( pptr < end && *pptr >= '0' && *pptr <= '9' )
  167. {
  168. char *end;
  169. const uint port = strtoul(pptr,&end,10);
  170. if ( port <= 0xffff && end > pptr )
  171. {
  172. host->port = port;
  173. ptr = end;
  174. }
  175. }
  176. else
  177. {
  178. ccp pstart = pptr;
  179. while ( pptr < end
  180. && ( *pptr >= 'a' && *pptr <= 'z'
  181. || *pptr >= 'A' && *pptr <= 'Z'
  182. || *pptr >= '0' && *pptr <= '9'
  183. || *pptr == '_' || *pptr == '-'
  184. ))
  185. {
  186. pptr++;
  187. }
  188. len = pptr - pstart;
  189. if ( len > 0 && len < sizeof(buf) )
  190. {
  191. memcpy(buf,pstart,len);
  192. buf[len] = 0;
  193. struct servent *s = getservbyname(buf,0);
  194. if (s)
  195. {
  196. const int port = ntohs(s->s_port);
  197. if ( port > 0 )
  198. host->port = port;
  199. ptr = pptr;
  200. }
  201. }
  202. }
  203. }
  204. host->sa.sin_family = AF_INET;
  205. host->sa.sin_addr.s_addr = htonl(host->ip4);
  206. host->sa.sin_port = htons(host->port);
  207. }
  208. if ( *ptr && check_filename )
  209. {
  210. host->filename = name.ptr;
  211. host->ip4_valid = false;
  212. }
  213. host->not_scanned = BehindMem(name,ptr);
  214. return host->ip4_valid;
  215. }
  216. //
  217. ///////////////////////////////////////////////////////////////////////////////
  218. /////////////// enum PrintModeIP_t ///////////////
  219. ///////////////////////////////////////////////////////////////////////////////
  220. PrintModeIP_t ScanPrintModeIP ( PrintModeIP_t base, ccp arg )
  221. {
  222. if (arg)
  223. {
  224. bool neg = false;
  225. while (*arg)
  226. {
  227. PrintModeIP_t val = 0;
  228. PrintModeIP_t mask = 0;
  229. switch(*arg++)
  230. {
  231. case '-': neg = !neg; break;
  232. case 'n': val = PMIP_NEVER; mask = PMIP_M_BITS; break;
  233. case 'r': val = PMIP_RELEVANT; mask = PMIP_M_BITS; break;
  234. case 'i': val = PMIP_IF_SET; mask = PMIP_M_BITS; break;
  235. case 'a': val = PMIP_ALWAYS; mask = PMIP_M_BITS; break;
  236. case 'p': val = PMIP_PORT; break;
  237. case 's': val = PMIP_SERVICE; break;
  238. case 'm': val = PMIP_MASK; break;
  239. case 'b': val = PMIP_BRACKETS; break;
  240. case 'f': val = PMIP_FULL_IPV6; break;
  241. case '0': val = PMIP_0DOTS; mask = PMIP_M_DOTS; break;
  242. case '1': val = PMIP_1DOT; mask = PMIP_M_DOTS; break;
  243. case '2': val = PMIP_2DOTS; mask = PMIP_M_DOTS; break;
  244. case '3': val = PMIP_3DOTS; mask = PMIP_M_DOTS; break;
  245. }
  246. if (mask) // ignore 'neg'
  247. {
  248. base = base & ~mask | val;
  249. neg = false;
  250. }
  251. else if (val)
  252. {
  253. if (neg)
  254. base &= ~val;
  255. else
  256. base |= val;
  257. neg = false;
  258. }
  259. }
  260. }
  261. return base;
  262. }
  263. ///////////////////////////////////////////////////////////////////////////////
  264. ccp PrintPrintModeIP ( PrintModeIP_t val, bool align )
  265. {
  266. char buf[20], *dest = buf;
  267. DASSERT( PMIP_M_BITS == 3 );
  268. *dest++ = "nria"[ val & PMIP_M_BITS ];
  269. if ( val & PMIP_PORT ) *dest++ = 'p'; else if (align) *dest++ = '-';
  270. if ( val & PMIP_SERVICE ) *dest++ = 's'; else if (align) *dest++ = '-';
  271. if ( val & PMIP_MASK ) *dest++ = 'm'; else if (align) *dest++ = '-';
  272. if ( val & PMIP_BRACKETS ) *dest++ = 'b'; else if (align) *dest++ = '-';
  273. if ( val & PMIP_FULL_IPV6 ) *dest++ = 'f'; else if (align) *dest++ = '-';
  274. if ( val & PMIP_0DOTS )
  275. *dest++ = '0';
  276. else if ( val & PMIP_1DOT )
  277. *dest++ = '1';
  278. else if ( val & PMIP_2DOTS )
  279. *dest++ = '2';
  280. else if (align)
  281. *dest++ = '3';
  282. DASSERT( dest < buf+sizeof(buf) );
  283. return CopyCircBuf0(buf,dest-buf);
  284. }
  285. //
  286. ///////////////////////////////////////////////////////////////////////////////
  287. /////////////// enum IPClass_t ///////////////
  288. ///////////////////////////////////////////////////////////////////////////////
  289. ccp GetIPClassColor ( const ColorSet_t *colset, IPClass_t ipc )
  290. {
  291. if ( !colset || !colset->colorize )
  292. return "";
  293. switch (ipc)
  294. {
  295. case IPCL_INVALID: return colset->b_red;
  296. case IPCL_LOOPBACK: return colset->b_cyan;
  297. case IPCL_LOCAL: return colset->b_green;
  298. case IPCL_STANDARD: return colset->reset;
  299. case IPCL_SPECIAL: return colset->b_yellow;
  300. default: return colset->b_magenta;
  301. }
  302. }
  303. //
  304. ///////////////////////////////////////////////////////////////////////////////
  305. /////////////// struct SplitIP_t ///////////////
  306. ///////////////////////////////////////////////////////////////////////////////
  307. bool SplitIP ( SplitIP_t *sip, ccp addr )
  308. {
  309. DASSERT(sip);
  310. memset(sip,0,sizeof(*sip));
  311. if (!addr)
  312. return false;
  313. while ( isblank((int)*addr) )
  314. addr++;
  315. int bits = -1;
  316. ccp slash = strchr(addr,'/');
  317. if (slash)
  318. {
  319. if (strchr(slash,'.'))
  320. {
  321. // is there a netmask?
  322. struct in_addr inp;
  323. if (inet_aton(slash+1,&inp))
  324. {
  325. const int bits2 = Count1Bits32(inp.s_addr);
  326. const ipv4_t mask = GetIP4Mask(bits2);
  327. if ( mask == inp.s_addr )
  328. bits = bits2;
  329. }
  330. }
  331. if ( bits < 0 )
  332. {
  333. const int val = strtol(slash+1,0,10);
  334. if ( val >= 0 && val <= 128 )
  335. bits = val;
  336. }
  337. }
  338. ccp have_port = 0;
  339. if ( *addr == '[' )
  340. {
  341. ccp close = strchr(++addr,']');
  342. if (!close)
  343. return false;
  344. StringCopySM(sip->name,sizeof(sip->name),addr,close-addr);
  345. if ( close[1] == ':' )
  346. have_port = close+2;
  347. }
  348. else
  349. {
  350. char *end_name = slash
  351. ? StringCopySM(sip->name,sizeof(sip->name),addr,slash-addr)
  352. : StringCopyS(sip->name,sizeof(sip->name),addr);
  353. if ( end_name > sip->name && end_name[-1] == '.' )
  354. {
  355. // remove trailing point if not a valid IPv4 (domains only)
  356. if ( CheckIP4(sip->name,end_name-sip->name) <= CIP4_INVALID )
  357. *--end_name = 0;
  358. }
  359. ccp point = strchr(sip->name,'.');
  360. if (point)
  361. {
  362. char *colon = strchr(point,':');
  363. if (colon)
  364. {
  365. *colon++ = 0;
  366. have_port = colon;
  367. }
  368. }
  369. }
  370. if (!*sip->name)
  371. return false;
  372. if (have_port)
  373. {
  374. if ( *have_port >= '0' && *have_port <= '9' )
  375. {
  376. const uint port = strtol(have_port,0,10);
  377. if ( port <= 0xffff )
  378. sip->port = port;
  379. }
  380. else
  381. {
  382. char serv[100];
  383. if (slash)
  384. {
  385. StringCopySM(serv,sizeof(serv),have_port,slash-have_port);
  386. have_port = serv;
  387. }
  388. struct servent result_buf;
  389. struct servent *result = 0;
  390. char buf[1000];
  391. if ( !getservbyname_r(have_port,0,&result_buf,buf,sizeof(buf),&result) && result )
  392. sip->port = ntohs(result->s_port);
  393. }
  394. }
  395. sip->bits = bits;
  396. return true;
  397. }
  398. //
  399. ///////////////////////////////////////////////////////////////////////////////
  400. /////////////// struct NamesIP_t ///////////////
  401. ///////////////////////////////////////////////////////////////////////////////
  402. struct ip_names_list_t
  403. {
  404. int offset;
  405. char name[8];
  406. };
  407. //-----------------------------------------------------------------------------
  408. #undef RECORD
  409. #define RECORD(v) { offsetof(NamesIP_t,v), #v },
  410. static const struct ip_names_list_t ip_names_list[] =
  411. {
  412. RECORD(binaddr)
  413. RECORD(ipvers)
  414. RECORD(addr1)
  415. RECORD(addr2)
  416. RECORD(bits)
  417. RECORD(mask1)
  418. RECORD(mask2)
  419. {-1,""}
  420. };
  421. #undef RECORD
  422. #undef GET_NAME_IP_PTR
  423. #define GET_NAME_IP_PTR(nip,offset) ((ccp*)( (char*)(nip)+offset ))
  424. ///////////////////////////////////////////////////////////////////////////////
  425. void SetupNamesIP ( NamesIP_t *dest, const NamesIP_t *src )
  426. {
  427. if (!dest)
  428. return;
  429. if (src)
  430. {
  431. for ( const struct ip_names_list_t *in = ip_names_list; in->offset >= 0; in++ )
  432. {
  433. ccp *s = GET_NAME_IP_PTR(src,in->offset);
  434. ccp *d = GET_NAME_IP_PTR(dest,in->offset);
  435. *d = *s && **s ? *s : in->name;
  436. }
  437. }
  438. else
  439. {
  440. for ( const struct ip_names_list_t *in = ip_names_list; in->offset >= 0; in++ )
  441. {
  442. ccp *d = GET_NAME_IP_PTR(dest,in->offset);
  443. *d = in->name;
  444. }
  445. }
  446. }
  447. ///////////////////////////////////////////////////////////////////////////////
  448. void SetupNamesByListIP ( NamesIP_t *dest, const exmem_list_t *src )
  449. {
  450. if (!dest)
  451. return;
  452. // [[2do]] ??? qqq
  453. }
  454. ///////////////////////////////////////////////////////////////////////////////
  455. ccp PrintNamesIP ( const NamesIP_t *nip )
  456. {
  457. return nip
  458. ? PrintCircBuf("ba=%s, iv=%s, a1=%s, a2=%s, b=%s, m1=%s, m2=%s\n",
  459. nip->binaddr, nip->ipvers, nip->addr1, nip->addr2,
  460. nip->bits, nip->mask1, nip->mask2 )
  461. : 0;
  462. }
  463. //
  464. ///////////////////////////////////////////////////////////////////////////////
  465. /////////////// struct BinIP_t ///////////////
  466. ///////////////////////////////////////////////////////////////////////////////
  467. BinIP_t GetIPMask ( const BinIP_t *src )
  468. {
  469. BinIP_t res = {0};
  470. if (src)
  471. {
  472. if ( src->ipvers == 4 )
  473. res.ip4 = GetIP4Mask(src->bits);
  474. else if ( src->ipvers == 6 )
  475. res.ip6 = GetIP6Mask(src->bits);
  476. else
  477. goto abort;
  478. res.ipvers = src->ipvers;
  479. res.bits = src->bits;
  480. }
  481. abort:
  482. return res;
  483. }
  484. ///////////////////////////////////////////////////////////////////////////////
  485. void ApplyIPMask ( BinIP_t *bip )
  486. {
  487. if (bip)
  488. {
  489. BinIP_t mask = GetIPMask(bip);
  490. bip->ip6_64[0] &= mask.ip6_64[0];
  491. bip->ip6_64[1] &= mask.ip6_64[1];
  492. }
  493. }
  494. ///////////////////////////////////////////////////////////////////////////////
  495. IPClass_t GetIPClassBIP ( const BinIP_t * bip )
  496. {
  497. struct ip4_tab
  498. {
  499. ipv4_t addr;
  500. ipv4_t mask;
  501. IPClass_t ipc;
  502. };
  503. static const struct ip4_tab ip4_tab[] =
  504. {
  505. { 0x00000000, 0xffffffff, IPCL_INVALID }, // 0.0.0.0
  506. { 0x7f000000, 0xff000000, IPCL_LOOPBACK }, // 127.0.0.0/8
  507. { 0x0a000000, 0xff000000, IPCL_LOCAL }, // 10.0.0.0/8
  508. { 0xac100000, 0xfff00000, IPCL_LOCAL }, // 172.16.0.0/12
  509. { 0xc0a80000, 0xffff0000, IPCL_LOCAL }, // 192.168.0.0/16
  510. { 0xa9fe0000, 0xffff0000, IPCL_LOCAL }, // 169.254.0.0/16
  511. { 0xe0000000, 0xe0000000, IPCL_SPECIAL }, // 224.0.0.0/3
  512. { 0,0,IPCL__N },
  513. };
  514. struct ip6_tab
  515. {
  516. IPClass_t ipc;
  517. ccp name;
  518. ipv6_t addr;
  519. ipv6_t mask;
  520. };
  521. static struct ip6_tab ip6_tab[] =
  522. {
  523. { IPCL_INVALID, "::" },
  524. { IPCL_LOOPBACK, "::1" },
  525. { IPCL_LOCAL, "fe80::/10" },
  526. { IPCL_SPECIAL, "f00::/8" },
  527. { 0,0 },
  528. };
  529. if (bip)
  530. {
  531. if ( bip->ipvers == 4 )
  532. {
  533. const ipv4_t addr = ntohl(bip->ip4);
  534. for ( const struct ip4_tab *ptr = ip4_tab; ptr->ipc < IPCL__N; ptr++ )
  535. if ( ( addr & ptr->mask ) == ptr->addr )
  536. return ptr->ipc;
  537. return IPCL_STANDARD;
  538. }
  539. else if ( bip->ipvers == 6 )
  540. {
  541. ipv6_t addr;
  542. memcpy(&addr,bip->ip6_64,sizeof(addr));
  543. PRINT0("> %016llx.%016llx\n",ntoh64(addr.v64[0]),ntoh64(addr.v64[1]));
  544. static bool init_done = false;
  545. if (!init_done)
  546. {
  547. init_done = true;
  548. ManageIP_t mip = {{0}};
  549. for ( struct ip6_tab *ptr = ip6_tab; ptr->name; ptr++ )
  550. {
  551. ScanMIP(&mip,ptr->name);
  552. memcpy(&ptr->addr,mip.bin.ip6_64,sizeof(ptr->addr));
  553. ptr->mask = GetIP6Mask(mip.bin.bits);
  554. }
  555. ResetMIP(&mip);
  556. }
  557. for ( struct ip6_tab *ptr = ip6_tab; ptr->name; ptr++ )
  558. {
  559. PRINT0(" %016llx.%016llx / %016llx.%016llx : %s\n",
  560. ntoh64(ptr->addr.v64[0]), ntoh64(ptr->addr.v64[1]),
  561. ntoh64(ptr->mask.v64[0]), ntoh64(ptr->mask.v64[1]),
  562. ptr->name );
  563. if ( ( addr.v64[0] & ptr->mask.v64[0] ) == ptr->addr.v64[0]
  564. && ( addr.v64[1] & ptr->mask.v64[1] ) == ptr->addr.v64[1] )
  565. {
  566. return ptr->ipc;
  567. }
  568. }
  569. return IPCL_STANDARD;
  570. }
  571. }
  572. return IPCL_INVALID;
  573. }
  574. ///////////////////////////////////////////////////////////////////////////////
  575. ccp PrintBIP ( const BinIP_t * bip )
  576. {
  577. ccp res;
  578. int bitlen = 32;
  579. char buf[INET6_ADDRSTRLEN+1];
  580. switch ( bip ? bip->ipvers : 0 )
  581. {
  582. case 4:
  583. res = inet_ntop(AF_INET,&bip->ip4,buf,sizeof(buf));
  584. break;
  585. case 6:
  586. res = inet_ntop(AF_INET6,bip->ip6_32,buf,sizeof(buf));
  587. bitlen = 128;
  588. break;
  589. default:
  590. res = 0;
  591. break;
  592. }
  593. if (!res)
  594. return 0;
  595. return bip->bits < bitlen
  596. ? PrintCircBuf("%s/%u",res,bip->bits)
  597. : CopyCircBuf(res,strlen(res)+1);
  598. }
  599. ///////////////////////////////////////////////////////////////////////////////
  600. bool IsSameBIP ( const BinIP_t *a1, const BinIP_t *a2, uint use_mask )
  601. {
  602. if ( a1 && a2 && a1->ipvers == a2->ipvers )
  603. {
  604. int bits;
  605. switch ( use_mask & 3 )
  606. {
  607. case 1: bits = a1->bits; break;
  608. case 2: bits = a2->bits; break;
  609. case 3: bits = a1->bits < a2->bits ? a1->bits : a2->bits; break;
  610. default: bits = 128; break;
  611. }
  612. if ( a1->ipvers == 4 )
  613. {
  614. ipv4_t mask = GetIP4Mask(bits);
  615. return ( a1->ip4 & mask ) == ( a2->ip4 & mask );
  616. }
  617. else if ( a1->ipvers == 6 )
  618. {
  619. ipv6_t mask = GetIP6Mask(bits);
  620. return !( ( a1->ip6.v64[0] ^ a2->ip6.v64[0] ) & mask.v64[0] )
  621. && !( ( a1->ip6.v64[1] ^ a2->ip6.v64[1] ) & mask.v64[1] );
  622. }
  623. }
  624. return false;
  625. }
  626. //
  627. ///////////////////////////////////////////////////////////////////////////////
  628. /////////////// struct BinIPList_t ///////////////
  629. ///////////////////////////////////////////////////////////////////////////////
  630. void ResetBIL ( BinIPList_t *bil )
  631. {
  632. if (bil)
  633. {
  634. ClearBIL(bil);
  635. FREE(bil->list);
  636. InitializeBIL(bil);
  637. }
  638. }
  639. ///////////////////////////////////////////////////////////////////////////////
  640. void ClearBIL ( BinIPList_t *bil )
  641. {
  642. if (bil)
  643. {
  644. BinIPItem_t *it = bil->list;
  645. for ( int i = 0; i < bil->used; i++, it++ )
  646. {
  647. FreeString(it->name);
  648. it->name = 0;
  649. }
  650. bil->used = 0;
  651. }
  652. }
  653. ///////////////////////////////////////////////////////////////////////////////
  654. ///////////////////////////////////////////////////////////////////////////////
  655. void SetSizeBIL ( BinIPList_t *bil, int size )
  656. {
  657. DASSERT(bil);
  658. if ( size < 0 )
  659. size = 0;
  660. if ( bil->used > size )
  661. {
  662. for ( int i = size; i < bil->used; i++ )
  663. {
  664. BinIPItem_t *it = bil->list + i;
  665. FreeString(it->name);
  666. }
  667. bil->used = size;
  668. }
  669. if ( bil->size != size )
  670. {
  671. bil->size = size;
  672. bil->list = REALLOC( bil->list, size * sizeof(*bil->list) );
  673. }
  674. DASSERT( !bil->size || bil->list );
  675. DASSERT( bil->used <= bil->size );
  676. }
  677. ///////////////////////////////////////////////////////////////////////////////
  678. void SetMinSizeBIL ( BinIPList_t *bil, int min_size )
  679. {
  680. DASSERT(bil);
  681. if ( min_size > bil->size )
  682. {
  683. const int good_size = bil->size / 8 + 10;
  684. if ( min_size < good_size )
  685. min_size = good_size;
  686. SetSizeBIL(bil,min_size);
  687. }
  688. }
  689. ///////////////////////////////////////////////////////////////////////////////
  690. BinIPItem_t * CreateItemBIL ( BinIPList_t *bil, int n_item )
  691. {
  692. DASSERT(bil);
  693. if ( n_item < 0 )
  694. n_item = 0;
  695. SetMinSizeBIL(bil,bil->used+n_item);
  696. BinIPItem_t *res = bil->list + bil->used;
  697. if ( n_item > 0 )
  698. memset( res, 0, n_item * sizeof(*res) );
  699. bil->used += n_item;
  700. DASSERT( !bil->size || bil->list );
  701. DASSERT( bil->used <= bil->size );
  702. return res;
  703. }
  704. ///////////////////////////////////////////////////////////////////////////////
  705. ///////////////////////////////////////////////////////////////////////////////
  706. #if 0
  707. BinIPItem_t * InsertBIL ( BinIPList_t *bil, int index, ccp key, CopyMode_t copy_mode )
  708. {
  709. DASSERT(bil);
  710. // ???
  711. return 0;
  712. }
  713. #endif
  714. ///////////////////////////////////////////////////////////////////////////////
  715. #if 0
  716. BinIPItem_t * InsertByKeyBIL ( BinIPList_t *bil, ccp key, CopyMode_t copy_mode )
  717. {
  718. DASSERT(bil);
  719. // ???
  720. return 0;
  721. }
  722. #endif
  723. ///////////////////////////////////////////////////////////////////////////////
  724. #if 0
  725. int FindIndexBIL ( const BinIPList_t *bil, ccp key )
  726. {
  727. DASSERT(bil);
  728. // ???
  729. return 0;
  730. }
  731. #endif
  732. ///////////////////////////////////////////////////////////////////////////////
  733. BinIPIterate_t FindAddressBIL ( const BinIPList_t *bil, BinIP_t *addr, uint use_mask )
  734. {
  735. BinIPIterate_t iter;
  736. if ( bil && bil->used && addr && addr->ipvers )
  737. {
  738. iter.valid = true;
  739. iter.bil = bil;
  740. iter.cur = bil->list - 1;
  741. iter.addr = *addr;
  742. iter.use_mask = use_mask;
  743. FindNextAddressBIL(&iter);
  744. }
  745. else
  746. memset(&iter,0,sizeof(iter));
  747. return iter;
  748. }
  749. //-----------------------------------------------------------------------------
  750. void FindNextAddressBIL ( BinIPIterate_t *iter )
  751. {
  752. if ( iter && iter->valid && iter->bil && iter->cur )
  753. {
  754. for ( uint idx = iter->cur + 1 - iter->bil->list; idx < iter->bil->used; idx++ )
  755. {
  756. BinIPItem_t *it = iter->bil->list + idx;
  757. if (IsSameBIP(&it->bip,&iter->addr,iter->use_mask))
  758. {
  759. iter->cur = it;
  760. return;
  761. }
  762. }
  763. }
  764. iter->valid = false;
  765. }
  766. ///////////////////////////////////////////////////////////////////////////////
  767. ///////////////////////////////////////////////////////////////////////////////
  768. BinIP_t GetBIPBySA ( sockaddr_t *addr, sockaddr_t *mask )
  769. {
  770. BinIP_t res = {0};
  771. if (addr)
  772. {
  773. if ( addr->sa_family == AF_INET )
  774. {
  775. res.ipvers = 4;
  776. res.bits = GetBitsBySA(mask,32);
  777. res.ip4 = ((sockaddr_in4_t*)addr)->sin_addr.s_addr;
  778. }
  779. else if ( addr->sa_family == AF_INET6 )
  780. {
  781. res.ipvers = 6;
  782. res.bits = GetBitsBySA(mask,128);
  783. memcpy(&res.ip6,&((sockaddr_in6_t*)addr)->sin6_addr,sizeof(res.ip6));
  784. }
  785. }
  786. return res;
  787. }
  788. ///////////////////////////////////////////////////////////////////////////////
  789. ///////////////////////////////////////////////////////////////////////////////
  790. uint ScanInterfaceAddresses ( BinIPList_t *bil, bool init_bil )
  791. {
  792. DASSERT(bil);
  793. if (init_bil)
  794. InitializeBIL(bil);
  795. else
  796. ClearBIL(bil);
  797. struct ifaddrs *ifaddr;
  798. if (getifaddrs(&ifaddr))
  799. return -1;
  800. for ( const struct ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next )
  801. {
  802. BinIP_t temp = GetBIPBySA(ifa->ifa_addr,ifa->ifa_netmask);
  803. if (temp.ipvers)
  804. {
  805. BinIPItem_t *it = CreateItemBIL(bil,1);
  806. it->name = STRDUP(ifa->ifa_name);
  807. it->bip = temp;
  808. }
  809. }
  810. freeifaddrs(ifaddr);
  811. return bil->used;
  812. }
  813. ///////////////////////////////////////////////////////////////////////////////
  814. const BinIPList_t * GetInterfaceAddressList ( bool update )
  815. {
  816. static BinIPList_t *list = 0;
  817. if ( !list || update )
  818. {
  819. bool init = !list;
  820. if (init)
  821. list = MALLOC(sizeof(*list));
  822. ScanInterfaceAddresses(list,init);
  823. }
  824. return list;
  825. }
  826. ///////////////////////////////////////////////////////////////////////////////
  827. bool IsLocalBIL ( BinIP_t *addr, uint use_mask )
  828. {
  829. const BinIPList_t *ial = GetInterfaceAddressList(false);
  830. BinIPIterate_t iter = FindAddressBIL(ial,addr,use_mask);
  831. return iter.valid;
  832. }
  833. //
  834. ///////////////////////////////////////////////////////////////////////////////
  835. /////////////// struct ManageIP_t ///////////////
  836. ///////////////////////////////////////////////////////////////////////////////
  837. void ResetMIP ( ManageIP_t *mip )
  838. {
  839. if (mip)
  840. {
  841. FreeString(mip->name);
  842. FreeString(mip->decoded_name);
  843. memset(mip,0,sizeof(*mip));
  844. }
  845. }
  846. ///////////////////////////////////////////////////////////////////////////////
  847. void ClearNameMIP ( ManageIP_t *mip )
  848. {
  849. if (mip)
  850. {
  851. FreeString(mip->name);
  852. FreeString(mip->decoded_name);
  853. mip->name = mip->decoded_name = 0;
  854. }
  855. }
  856. ///////////////////////////////////////////////////////////////////////////////
  857. ManageIP_t GetCopyMIP ( const ManageIP_t *mip )
  858. {
  859. ManageIP_t res;
  860. if (mip)
  861. {
  862. memcpy(&res,mip,sizeof(res));
  863. if (res.name)
  864. res.name = STRDUP(res.name);
  865. if (res.decoded_name)
  866. res.decoded_name = STRDUP(res.decoded_name);
  867. }
  868. else
  869. memset(&res,0,sizeof(res));
  870. return res;
  871. }
  872. ///////////////////////////////////////////////////////////////////////////////
  873. bool AssignMIP ( ManageIP_t *dest, const ManageIP_t *src )
  874. {
  875. if (dest)
  876. {
  877. ClearNameMIP(dest);
  878. *dest = GetCopyMIP(src);
  879. return dest->bin.ipvers != 0;
  880. }
  881. return false;
  882. }
  883. ///////////////////////////////////////////////////////////////////////////////
  884. bool AssignBinMIP ( ManageIP_t *mip, cvp bin, int bits )
  885. {
  886. DASSERT(mip);
  887. ResetMIP(mip);
  888. if (!bin)
  889. return false;
  890. const BinIP_t *bip = bin;
  891. if ( bip->ipvers == 4 )
  892. mip->relevant_bits = 32;
  893. else if ( bip->ipvers == 6 )
  894. mip->relevant_bits = 128;
  895. else
  896. return false;
  897. memcpy(&mip->bin,bin,sizeof(mip->bin));
  898. if ( bits >= 0 )
  899. {
  900. mip->have_bits = true;
  901. mip->bin.bits = bits < mip->relevant_bits ? bits : mip->relevant_bits;
  902. }
  903. if ( mip->bin.bits < mip->relevant_bits )
  904. mip->have_bits = true;
  905. else
  906. mip->bin.bits = mip->relevant_bits;
  907. return true;
  908. }
  909. ///////////////////////////////////////////////////////////////////////////////
  910. bool AssignSockaddrMIP ( ManageIP_t *mip, cvp sockaddr, u16 port, int bits )
  911. {
  912. DASSERT(mip);
  913. ResetMIP(mip);
  914. if (!sockaddr)
  915. return false;
  916. const sockaddr_in46_t *sa = sockaddr;
  917. if ( sa->family == AF_INET )
  918. {
  919. mip->bin.ipvers = 4;
  920. mip->bin.bits = 32;
  921. mip->bin.ip4 = sa->in4.sin_addr.s_addr;
  922. mip->port = ntohs(sa->in4.sin_port);
  923. }
  924. else if ( sa->family == AF_INET6 )
  925. {
  926. mip->bin.ipvers = 6;
  927. mip->bin.bits = 128;
  928. memcpy(mip->bin.ip6_8,sa->in6.sin6_addr.s6_addr,sizeof(mip->bin.ip6_8));
  929. mip->port = ntohs(sa->in6.sin6_port);
  930. }
  931. mip->relevant_bits = mip->bin.bits;
  932. if ( bits >= 0 )
  933. {
  934. mip->have_bits = true;
  935. if ( mip->bin.bits > bits )
  936. mip->bin.bits = bits;
  937. }
  938. if ( !mip->port )
  939. mip->port = port;
  940. return true;
  941. }
  942. ///////////////////////////////////////////////////////////////////////////////
  943. bool ScanMIP ( ManageIP_t *mip, ccp addr )
  944. {
  945. DASSERT(mip);
  946. ResetMIP(mip);
  947. SplitIP_t sip;
  948. if (!SplitIP(&sip,addr))
  949. return false;
  950. if (strchr(sip.name,':'))
  951. {
  952. if ( inet_pton(AF_INET6,sip.name,mip->bin.ip6_32) != 1 )
  953. return false;
  954. mip->bin.ipvers = 6;
  955. mip->relevant_bits = 128;
  956. }
  957. else
  958. {
  959. struct in_addr inp;
  960. if (!dclib_aton(sip.name,&inp))
  961. return false;
  962. mip->bin.ipvers = 4;
  963. mip->bin.ip4 = inp.s_addr;
  964. mip->relevant_bits = 32;
  965. }
  966. mip->bin.bits = mip->relevant_bits;
  967. if ( sip.bits >= 0 )
  968. {
  969. mip->have_bits = true;
  970. if ( sip.bits < mip->relevant_bits )
  971. mip->bin.bits = sip.bits;
  972. }
  973. mip->port = sip.port;
  974. return true;
  975. }
  976. ///////////////////////////////////////////////////////////////////////////////
  977. ManageIP_t GetSockNameMIP ( int sock )
  978. {
  979. ManageIP_t mip = {{0}};
  980. sockaddr_in46_t sa;
  981. socklen_t sa_len = sizeof(sa);
  982. if (!getsockname(sock,(sockaddr_t*)&sa,&sa_len))
  983. AssignSockaddrMIP(&mip,&sa,0,-1);
  984. return mip;
  985. }
  986. ///////////////////////////////////////////////////////////////////////////////
  987. ManageIP_t GetPeerNameMIP ( int sock )
  988. {
  989. ManageIP_t mip = {{0}};
  990. sockaddr_in46_t sa;
  991. socklen_t sa_len = sizeof(sa);
  992. if (!getpeername(sock,(sockaddr_t*)&sa,&sa_len))
  993. AssignSockaddrMIP(&mip,&sa,0,-1);
  994. return mip;
  995. }
  996. ///////////////////////////////////////////////////////////////////////////////
  997. ManageIP_t GetAddrInfoMIP ( ccp addr, int protocol, IpMode_t ipm )
  998. {
  999. ManageIP_t mip = {{0}};
  1000. SplitIP_t sip;
  1001. if (SplitIP(&sip,addr))
  1002. {
  1003. struct addrinfo hints
  1004. = { .ai_family = AF_UNSPEC,
  1005. .ai_protocol = protocol < 0 ? IPPROTO_TCP : protocol };
  1006. struct addrinfo *result;
  1007. if (!getaddrinfo(sip.name,0,&hints,&result))
  1008. {
  1009. struct addrinfo *ip4 = 0, *ip6 = 0;
  1010. for ( struct addrinfo *rp = result; rp; rp = rp->ai_next)
  1011. {
  1012. if ( !ip4 && rp->ai_family == AF_INET )
  1013. ip4 = rp;
  1014. else if ( !ip6 && rp->ai_family == AF_INET6 )
  1015. ip6 = rp;
  1016. }
  1017. switch (ipm)
  1018. {
  1019. case IPV4_ONLY: break; // nothing to do
  1020. case IPV6_ONLY: ip4 = ip6; break;
  1021. case IPV4_FIRST: if (!ip4) ip4 = ip6; break;
  1022. case IPV6_FIRST: if (ip6) ip4 = ip6; break;
  1023. }
  1024. if (ip4)
  1025. AssignSockaddrMIP(&mip,ip4->ai_addr,sip.port,sip.bits);
  1026. freeaddrinfo(result);
  1027. }
  1028. }
  1029. return mip;
  1030. }
  1031. ///////////////////////////////////////////////////////////////////////////////
  1032. sockaddr_in46_t GetSockaddrMIP ( const ManageIP_t *mip )
  1033. {
  1034. DASSERT(mip);
  1035. sockaddr_in46_t sa = { .family = 0 };
  1036. if ( mip->bin.ipvers == 4 )
  1037. {
  1038. sa.in4.sin_family = AF_INET;
  1039. sa.in4.sin_addr.s_addr = mip->bin.ip4;
  1040. sa.in4.sin_port = htons(mip->port);
  1041. }
  1042. else if ( mip->bin.ipvers == 6 )
  1043. {
  1044. sa.in6.sin6_family = AF_INET6;
  1045. sa.in6.sin6_port = htons(mip->port);
  1046. memcpy(sa.in6.sin6_addr.s6_addr,mip->bin.ip6_8,sizeof(sa.in6.sin6_addr));
  1047. }
  1048. return sa;
  1049. }
  1050. ///////////////////////////////////////////////////////////////////////////////
  1051. ccp GetNameInfoMIP ( ManageIP_t *mip )
  1052. {
  1053. DASSERT(mip);
  1054. if ( !mip->name && mip->bin.ipvers )
  1055. {
  1056. char host1[NI_MAXHOST+20], host2[NI_MAXHOST+20];
  1057. sockaddr_in46_t sa = GetSockaddrMIP(mip);
  1058. if (!getnameinfo( (sockaddr_t*)&sa,sizeof(sa), host1,sizeof(host1), 0,0, 0 ))
  1059. {
  1060. mip->name = STRDUP(host1);
  1061. FreeString(mip->decoded_name);
  1062. const uint stat = Domain2UTF8(host2,sizeof(host2),host1,-1);
  1063. mip->decoded_name = stat && *host2 && strcmp(host1,host2) ? STRDUP(host2) : 0;
  1064. }
  1065. }
  1066. return mip->name;
  1067. }
  1068. ///////////////////////////////////////////////////////////////////////////////
  1069. void ApplyMaskMIP ( ManageIP_t *mip, int bits )
  1070. {
  1071. DASSERT(mip);
  1072. if ( bits >= 0 && bits < mip->bin.bits )
  1073. mip->bin.bits = bits;
  1074. ApplyIPMask(&mip->bin);
  1075. }
  1076. ///////////////////////////////////////////////////////////////////////////////
  1077. void MaskPrefixMIP ( ManageIP_t *mip )
  1078. {
  1079. DASSERT(mip);
  1080. if ( mip->bin.ipvers == 4 || mip->bin.ip6_64[0] != 0ull )
  1081. ApplyMaskMIP(mip,64);
  1082. }
  1083. ///////////////////////////////////////////////////////////////////////////////
  1084. ccp PrintAddrMIP ( const ManageIP_t *mip, PrintModeIP_t pmode )
  1085. {
  1086. DASSERT(mip);
  1087. ccp res;
  1088. char buf[INET6_ADDRSTRLEN+1];
  1089. switch (mip->bin.ipvers)
  1090. {
  1091. case 4:
  1092. res = buf;
  1093. if ( pmode & PMIP_0DOTS )
  1094. snprintf(buf,sizeof(buf),"%u",ntohl(mip->bin.ip4));
  1095. else if ( pmode & PMIP_1DOT )
  1096. snprintf(buf,sizeof(buf), "%u.%u",
  1097. mip->bin.ip4x.v8[0], ntohl(mip->bin.ip4)&0xffffff );
  1098. else if ( pmode & PMIP_2DOTS )
  1099. snprintf(buf,sizeof(buf), "%u.%u.%u",
  1100. mip->bin.ip4x.v8[0], mip->bin.ip4x.v8[1], ntohs(mip->bin.ip4x.v16[1]) );
  1101. else
  1102. snprintf(buf,sizeof(buf), "%u.%u.%u.%u",
  1103. mip->bin.ip4x.v8[0], mip->bin.ip4x.v8[1],
  1104. mip->bin.ip4x.v8[2], mip->bin.ip4x.v8[3] );
  1105. break;
  1106. case 6:
  1107. if ( pmode & PMIP_FULL_IPV6 )
  1108. {
  1109. snprintf(buf,sizeof(buf), "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
  1110. ntohs(mip->bin.ip6.v16[0]),
  1111. ntohs(mip->bin.ip6.v16[1]),
  1112. ntohs(mip->bin.ip6.v16[2]),
  1113. ntohs(mip->bin.ip6.v16[3]),
  1114. ntohs(mip->bin.ip6.v16[4]),
  1115. ntohs(mip->bin.ip6.v16[5]),
  1116. ntohs(mip->bin.ip6.v16[6]),
  1117. ntohs(mip->bin.ip6.v16[7]) );
  1118. res = buf;
  1119. }
  1120. else
  1121. res = inet_ntop(AF_INET6,mip->bin.ip6_32,buf,sizeof(buf));
  1122. break;
  1123. default:
  1124. res = 0;
  1125. }
  1126. if (!res)
  1127. return 0;
  1128. char port[100];
  1129. *port = 0;
  1130. if ( mip->port && pmode & (PMIP_SERVICE|PMIP_PORT) )
  1131. {
  1132. if ( pmode & PMIP_SERVICE )
  1133. {
  1134. struct servent result_buf;
  1135. struct servent *result;
  1136. char buf[1000];
  1137. const int stat = getservbyport_r(htons(mip->port),0,&result_buf,buf,sizeof(buf),&result);
  1138. if ( !stat && result )
  1139. snprintf(port,sizeof(port),":%s",result_buf.s_name);
  1140. }
  1141. if (!*port)
  1142. snprintf(port,sizeof(port),":%u",mip->port);
  1143. pmode |= PMIP_BRACKETS;
  1144. }
  1145. char bits[20];
  1146. if (PrintBitsMIP(mip,pmode))
  1147. {
  1148. if ( mip->bin.ipvers == 4 && pmode & PMIP_MASK )
  1149. {
  1150. ipv4x_t mask;
  1151. mask.ip4 = GetIP4Mask(mip->bin.bits);
  1152. snprintf(bits,sizeof(bits),"/%d.%d.%d.%d",
  1153. mask.v8[0], mask.v8[1], mask.v8[2], mask.v8[3] );
  1154. }
  1155. else
  1156. snprintf(bits,sizeof(bits),"/%u",mip->bin.bits);
  1157. }
  1158. else
  1159. *bits = 0;
  1160. return pmode & PMIP_BRACKETS && mip->bin.ipvers == 6
  1161. ? PrintCircBuf("[%s]%s%s",res,port,bits)
  1162. : PrintCircBuf("%s%s%s",res,port,bits);
  1163. }
  1164. ///////////////////////////////////////////////////////////////////////////////
  1165. ccp PrintVersAddrMIP ( const ManageIP_t *mip, PrintModeIP_t pmode )
  1166. {
  1167. DASSERT(mip);
  1168. ccp res = PrintAddrMIP(mip,pmode);
  1169. return res ? PrintCircBuf("IPv%u %s",mip->bin.ipvers,res) : 0;
  1170. }
  1171. ///////////////////////////////////////////////////////////////////////////////
  1172. ///////////////////////////////////////////////////////////////////////////////
  1173. ccp GetSqlSetAddrMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1174. {
  1175. if (!mip)
  1176. return 0;
  1177. NamesIP_t nip;
  1178. SetupNamesIP(&nip,names);
  1179. if ( mip->bin.ipvers == 4 )
  1180. {
  1181. const ipv4_t mask = GetIP4Mask(mip->bin.bits);
  1182. return PrintCircBuf("%s=4,%s=0,%s=0x%08x",
  1183. nip.ipvers, nip.addr1,
  1184. nip.addr2, ntohl( mip->bin.ip4 & mask ));
  1185. }
  1186. else if ( mip->bin.ipvers == 6 )
  1187. {
  1188. const ipv6_t mask = GetIP6Mask(mip->bin.bits);
  1189. return PrintCircBuf("%s=6,%s=0x%llx,%s=0x%llx",
  1190. nip.ipvers,
  1191. nip.addr1, ntoh64( mip->bin.ip6_64[0] & mask.v64[0] ),
  1192. nip.addr2, ntoh64( mip->bin.ip6_64[1] & mask.v64[1] ));
  1193. }
  1194. return 0;
  1195. }
  1196. ///////////////////////////////////////////////////////////////////////////////
  1197. ccp GetSqlSetMaskMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1198. {
  1199. if (!mip)
  1200. return 0;
  1201. NamesIP_t nip;
  1202. SetupNamesIP(&nip,names);
  1203. if ( mip->bin.ipvers == 4 )
  1204. {
  1205. const ipv4_t mask = GetIP4Mask(mip->bin.bits);
  1206. return PrintCircBuf("%s=4,%s=0,%s=0x%08x,%s=0,%s=0x%08x",
  1207. nip.ipvers, nip.addr1,
  1208. nip.addr2, ntohl( mip->bin.ip4 & mask ),
  1209. nip.mask1, nip.mask2, ntohl(mask));
  1210. }
  1211. else if ( mip->bin.ipvers == 6 )
  1212. {
  1213. const ipv6_t mask = GetIP6Mask(mip->bin.bits);
  1214. return PrintCircBuf("%s=6,%s=0x%llx,%s=0x%llx,%s=0x%llx,%s=0x%llx",
  1215. nip.ipvers,
  1216. nip.addr1, ntoh64( mip->bin.ip6_64[0] & mask.v64[0] ),
  1217. nip.addr2, ntoh64( mip->bin.ip6_64[1] & mask.v64[1] ),
  1218. nip.mask1, ntoh64(mask.v64[0]),
  1219. nip.mask2, ntoh64(mask.v64[1]) );
  1220. }
  1221. return 0;
  1222. }
  1223. ///////////////////////////////////////////////////////////////////////////////
  1224. ccp GetSqlSetBinMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1225. {
  1226. if (!mip)
  1227. return 0;
  1228. NamesIP_t nip;
  1229. SetupNamesIP(&nip,names);
  1230. return PrintCircBuf("%s=unhex('%02x%02x%016llx%016llx')",
  1231. nip.binaddr, mip->bin.ipvers, mip->bin.bits,
  1232. ntoh64(mip->bin.ip6_64[0]), ntoh64(mip->bin.ip6_64[0]) );
  1233. }
  1234. ///////////////////////////////////////////////////////////////////////////////
  1235. ccp GetSqlCondAddrMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1236. {
  1237. if (!mip)
  1238. return 0;
  1239. NamesIP_t nip;
  1240. SetupNamesIP(&nip,names);
  1241. if ( mip->bin.ipvers == 4 )
  1242. return PrintCircBuf("%s=4 && %s=0x%08x",
  1243. nip.ipvers, nip.addr2, ntohl(mip->bin.ip4) );
  1244. else if ( mip->bin.ipvers == 6 )
  1245. return PrintCircBuf("%s=6 && %s=0x%llx && %s=0x%llx",
  1246. nip.ipvers,
  1247. nip.addr1, ntoh64(mip->bin.ip6_64[0]),
  1248. nip.addr2, ntoh64(mip->bin.ip6_64[1]) );
  1249. return 0;
  1250. }
  1251. ///////////////////////////////////////////////////////////////////////////////
  1252. ccp GetSqlCondMaskMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1253. {
  1254. if (!mip)
  1255. return 0;
  1256. NamesIP_t nip;
  1257. SetupNamesIP(&nip,names);
  1258. if ( mip->bin.ipvers == 4 )
  1259. return PrintCircBuf("%s=4 && %s=(%s&0x%08x)",
  1260. nip.ipvers,
  1261. nip.addr2, nip.mask2, ntohl(mip->bin.ip4) );
  1262. else if ( mip->bin.ipvers == 6 )
  1263. return PrintCircBuf("%s=6 && %s=(%s&0x%llx) && %s=(%s&0x%llx)",
  1264. nip.ipvers,
  1265. nip.addr1, nip.mask1, ntoh64(mip->bin.ip6_64[0]),
  1266. nip.addr2, nip.mask2, ntoh64(mip->bin.ip6_64[1]) );
  1267. return 0;
  1268. }
  1269. ///////////////////////////////////////////////////////////////////////////////
  1270. ccp GetSqlCondBinMaskMIP ( const ManageIP_t *mip, const NamesIP_t *names )
  1271. {
  1272. if (!mip)
  1273. return 0;
  1274. NamesIP_t nip;
  1275. SetupNamesIP(&nip,names);
  1276. if ( mip->bin.ipvers == 4 )
  1277. return PrintCircBuf("compare_binaddr(%s,4,0,0x%08x,%s,%s)",
  1278. nip.binaddr, ntohl(mip->bin.ip4),
  1279. nip.mask1, nip.mask2 );
  1280. else if ( mip->bin.ipvers == 6 )
  1281. return PrintCircBuf("compare_binaddr(%s,6,0x%llx,0x%llx,%s,%s)",
  1282. nip.binaddr,
  1283. ntoh64(mip->bin.ip6_64[0]), ntoh64(mip->bin.ip6_64[1]),
  1284. nip.mask1, nip.mask2 );
  1285. return 0;
  1286. }
  1287. //
  1288. ///////////////////////////////////////////////////////////////////////////////
  1289. /////////////// struct ResolveIP_t ///////////////
  1290. ///////////////////////////////////////////////////////////////////////////////
  1291. void ResetRIP ( ResolveIP_t *rip )
  1292. {
  1293. if (rip)
  1294. {
  1295. ResetMIP(&rip->mip4);
  1296. ResetMIP(&rip->mip6);
  1297. memset(rip,0,sizeof(*rip));
  1298. }
  1299. }
  1300. ///////////////////////////////////////////////////////////////////////////////
  1301. void ClearNamesRIP ( ResolveIP_t *rip )
  1302. {
  1303. if (rip)
  1304. {
  1305. ClearNameMIP(&rip->mip4);
  1306. ClearNameMIP(&rip->mip6);
  1307. }
  1308. }
  1309. ///////////////////////////////////////////////////////////////////////////////
  1310. int SetupListRIP ( ResolveIP_t *rip )
  1311. {
  1312. DASSERT(rip);
  1313. memset(rip->mip_list,0,sizeof(rip->mip_list));
  1314. ManageIP_t **mp = rip->mip_list;
  1315. switch (rip->ip_mode)
  1316. {
  1317. case IPV6_FIRST:
  1318. if (rip->mip6.bin.ipvers)
  1319. *mp++ = &rip->mip6;
  1320. // fall though
  1321. case IPV4_ONLY:
  1322. if (rip->mip4.bin.ipvers)
  1323. *mp++ = &rip->mip4;
  1324. break;
  1325. case IPV4_FIRST:
  1326. if (rip->mip4.bin.ipvers)
  1327. *mp++ = &rip->mip4;
  1328. // fall though
  1329. case IPV6_ONLY:
  1330. if (rip->mip6.bin.ipvers)
  1331. *mp++ = &rip->mip6;
  1332. break;
  1333. }
  1334. return mp - rip->mip_list;
  1335. }
  1336. ///////////////////////////////////////////////////////////////////////////////
  1337. ResolveIP_t GetCopyRIP ( const ResolveIP_t *rip )
  1338. {
  1339. ResolveIP_t res;
  1340. if (rip)
  1341. {
  1342. res.ip_mode = rip->ip_mode;
  1343. res.mip4 = GetCopyMIP(&rip->mip4);
  1344. res.mip6 = GetCopyMIP(&rip->mip6);
  1345. SetupListRIP(&res);
  1346. }
  1347. else
  1348. memset(&res,0,sizeof(res));
  1349. return res;
  1350. }
  1351. ///////////////////////////////////////////////////////////////////////////////
  1352. void AssignRIP ( ResolveIP_t *dest, const ResolveIP_t *src )
  1353. {
  1354. if (dest)
  1355. {
  1356. ClearNamesRIP(dest);
  1357. *dest = GetCopyRIP(src);
  1358. }
  1359. }
  1360. ///////////////////////////////////////////////////////////////////////////////
  1361. int ScanRIP
  1362. (
  1363. // return 0..2 = number of records
  1364. ResolveIP_t *rip, // valid data, ResetRIP()
  1365. ccp addr, // address to scan
  1366. int protocol, // protocol to use: 0=all, -1=default (IPPROTO_TCP at the moment)
  1367. IpMode_t ip_mode, // IPv4 and/or IPV6, order of 'mip_list'
  1368. bool get_names // true: call GetNameInfoMIP()
  1369. )
  1370. {
  1371. DASSERT(rip);
  1372. ResetRIP(rip);
  1373. SplitIP_t sip;
  1374. if (!SplitIP(&sip,addr))
  1375. return 0;
  1376. NormalizeNameSIP(&sip);
  1377. rip->ip_mode = ip_mode;
  1378. struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };
  1379. struct addrinfo *result;
  1380. char aname[300];
  1381. Domain2ASCII(aname,sizeof(aname),sip.name,-1);
  1382. if (!getaddrinfo(aname,0,&hints,&result))
  1383. {
  1384. struct addrinfo *ip4 = 0, *ip6 = 0;
  1385. for ( struct addrinfo *rp = result; rp; rp = rp->ai_next)
  1386. {
  1387. if ( !ip4 && rp->ai_family == AF_INET )
  1388. ip4 = rp;
  1389. else if ( !ip6 && rp->ai_family == AF_INET6 )
  1390. ip6 = rp;
  1391. }
  1392. if (ip4)
  1393. AssignSockaddrMIP(&rip->mip4,ip4->ai_addr,sip.port,sip.bits);
  1394. if (ip6)
  1395. AssignSockaddrMIP(&rip->mip6,ip6->ai_addr,sip.port,sip.bits);
  1396. if (get_names)
  1397. {
  1398. GetNameInfoMIP(&rip->mip4);
  1399. GetNameInfoMIP(&rip->mip6);
  1400. }
  1401. freeaddrinfo(result);
  1402. }
  1403. return SetupListRIP(rip);
  1404. }
  1405. ///////////////////////////////////////////////////////////////////////////////
  1406. ///////////////////////////////////////////////////////////////////////////////
  1407. #if 0
  1408. void DumpRIP ( FILE *f, int indent, const ResolveIP_t *rip )
  1409. {
  1410. if ( !f || !rip )
  1411. return;
  1412. indent = NormalizeIndent(indent);
  1413. }
  1414. #endif
  1415. //
  1416. ///////////////////////////////////////////////////////////////////////////////
  1417. /////////////// struct AllowIP4_t ///////////////
  1418. ///////////////////////////////////////////////////////////////////////////////
  1419. const KeywordTab_t AllowIP4KeyTable[] =
  1420. {
  1421. { 0, "0", 0, 1 },
  1422. { ALLOW_MODE_DENY, "DENY", 0, 1 },
  1423. { ALLOW_MODE_ALLOW, "ALLOW", 0, 0 },
  1424. { ALLOW_MODE_AKEY, "AKEY", "JACC", 0 },
  1425. { ALLOW_MODE_LOCAL, "LOCAL", 0, 0 },
  1426. { ALLOW_MODE_LAN, "LAN", 0, 0 },
  1427. { ALLOW_MODE_EXTERN, "EXTERN", 0, 0 },
  1428. { ALLOW_MODE_PUBLIC, "PUBLIC", 0, 0 },
  1429. { ALLOW_MODE_USER, "USER", 0, 0 },
  1430. { ALLOW_MODE_MOD, "MOD", "MODERATOR", 0 },
  1431. { ALLOW_MODE_ADMIN, "ADMIN", "ADMINISTRATOR",0 },
  1432. { ALLOW_MODE_DEVELOP, "DEVELOP", "DEVELOPER", 0 },
  1433. { ALLOW_MODE_LOG, "LOG", 0, 0 },
  1434. { ALLOW_MODE_VERBOSE, "VERBOSE", 0, 0 },
  1435. { ALLOW_RELEASE, "RELEASE", 0, 0 },
  1436. { ALLOW_DEBUG, "DEBUG", 0, 0 },
  1437. { ALLOW_MODE_NOT, "NOT", 0, 0 },
  1438. { ALLOW_MODE_SET, "SET", 0, ALLOW_MODE__OP },
  1439. { ALLOW_MODE_AND, "AND", 0, ALLOW_MODE__OP },
  1440. { 0, "OR", 0, ALLOW_MODE__OP },
  1441. { ALLOW_MODE_CONTINUE, "CONTINUE", 0, 0 },
  1442. {0,0,0,0}
  1443. };
  1444. ///////////////////////////////////////////////////////////////////////////////
  1445. void InitializeAllowIP4 ( AllowIP4_t *ai )
  1446. {
  1447. DASSERT(ai);
  1448. memset(ai,0,sizeof(*ai));
  1449. ai->ref_counter = 1;
  1450. ai->fallback_mode = ALLOW_MODE_DENY;
  1451. ai->allow_mode = ALLOW_MODE_ALLOW|ALLOW_MODE_AKEY;
  1452. }
  1453. ///////////////////////////////////////////////////////////////////////////////
  1454. void ResetAllowIP4 ( AllowIP4_t *ai )
  1455. {
  1456. if (ai)
  1457. {
  1458. FREE(ai->list);
  1459. ai->list = 0;
  1460. ai->used = ai->size = 0;
  1461. }
  1462. }
  1463. ///////////////////////////////////////////////////////////////////////////////
  1464. void ClearAllowIP4 ( AllowIP4_t *ai )
  1465. {
  1466. if (ai)
  1467. {
  1468. FREE(ai->list);
  1469. InitializeAllowIP4(ai);
  1470. }
  1471. }
  1472. ///////////////////////////////////////////////////////////////////////////////
  1473. AllowIP4_t * NewReferenceAllowIP4 ( AllowIP4_t *ai )
  1474. {
  1475. if (ai)
  1476. ai->ref_counter++;
  1477. else
  1478. {
  1479. ai = MALLOC(sizeof(*ai));
  1480. DASSERT(ai);
  1481. InitializeAllowIP4(ai);
  1482. }
  1483. return ai;
  1484. }
  1485. ///////////////////////////////////////////////////////////////////////////////
  1486. AllowIP4_t * DeleteReferenceAllowIP4 ( AllowIP4_t *ai )
  1487. {
  1488. if ( ai && !--ai->ref_counter )
  1489. {
  1490. ResetAllowIP4(ai);
  1491. FREE(ai);
  1492. }
  1493. return 0;
  1494. }
  1495. ///////////////////////////////////////////////////////////////////////////////
  1496. ///////////////////////////////////////////////////////////////////////////////
  1497. enumError ScanLineAllowIP4
  1498. (
  1499. AllowIP4_t *ai, // valid structure; new elements are appended
  1500. mem_t line, // single line to analyse
  1501. const KeywordTab_t *tab // NULL or keyword table.
  1502. // If NULL, a local table with keywords 0 DENY
  1503. // ALLOW SET REMOVE AND OR and CONTINUE is used.
  1504. )
  1505. {
  1506. if ( !line.ptr || !line.len )
  1507. return ERR_OK;
  1508. ccp ptr = line.ptr;
  1509. ccp end = ptr + line.len;
  1510. //--- find first character
  1511. while ( ptr < end && *(uchar*)ptr <= ' ' )
  1512. ptr++;
  1513. if ( ptr == end || *ptr == '#' )
  1514. return ERR_OK;
  1515. NetworkHost_t host;
  1516. ResolveHostMem(&host,true,BehindMem(line,ptr),0,false,false);
  1517. if (!host.ip4_valid)
  1518. return ERR_ERROR;
  1519. line = host.not_scanned;
  1520. u32 mask = M1(mask);
  1521. if ( line.len && *line.ptr == '/' )
  1522. line = ScanNetworkMaskMem(&mask,line);
  1523. //--- scan options
  1524. if (!tab)
  1525. tab = AllowIP4KeyTable;
  1526. char arg[1000];
  1527. StringCopySMem(arg,sizeof(arg),line); // to be NULL terminated
  1528. s64 res = ScanKeywordList(arg,tab,0,true,0,0,"AllowIP4",ERR_SYNTAX);
  1529. if ( res == M1(res) )
  1530. return ERR_SYNTAX;
  1531. if ( res & ALLOW_MODE_NOT )
  1532. res = res ^ ALLOW_MODE__MASK;
  1533. #if defined(DEBUG) && DEBUG > 0 || defined(IS_DEVELOP) && IS_DEVELOP > 0
  1534. if ( res & ALLOW_RELEASE )
  1535. return ERR_OK;
  1536. #else
  1537. if ( res & ALLOW_DEBUG )
  1538. return ERR_OK;
  1539. #endif
  1540. //--- add item
  1541. if ( ai->used == ai->size )
  1542. {
  1543. ai->size = 11*ai->size/10 + 10;
  1544. ai->list = REALLOC(ai->list,ai->size*sizeof(*ai->list));
  1545. }
  1546. DASSERT( ai->used < ai->size );
  1547. DASSERT( ai->list );
  1548. AllowIP4Item_t *it = ai->list + ai->used++;
  1549. //memset(it,0,sizeof(*it));
  1550. it->addr = host.ip4 & mask;
  1551. it->mask = mask;
  1552. it->mode = res;
  1553. it->count = 0;
  1554. return ERR_OK;
  1555. }
  1556. ///////////////////////////////////////////////////////////////////////////////
  1557. enumError ScanFileAllowIP4
  1558. (
  1559. AllowIP4_t *ai, // valid structure; new elements are appended
  1560. ccp fname, // ffilename of the source
  1561. FileMode_t fmode, // flags for OpenFile()
  1562. const KeywordTab_t *tab // NULL or keyword table -> see ScanLineAllowIP4()
  1563. )
  1564. {
  1565. File_t F;
  1566. enumError err = OpenFile(&F,true,fname,fmode,0,0);
  1567. if (err)
  1568. return err;
  1569. char iobuf[10000];
  1570. while (fgets(iobuf,sizeof(iobuf)-1,F.f))
  1571. {
  1572. err = ScanLineAllowIP4(ai,MemByString(iobuf),tab);
  1573. if (err)
  1574. break;
  1575. }
  1576. CloseFile(&F,0);
  1577. return err;
  1578. }
  1579. ///////////////////////////////////////////////////////////////////////////////
  1580. void ResetCountersAllowIP4
  1581. (
  1582. AllowIP4_t *ai // NULL or dest for addition
  1583. )
  1584. {
  1585. if (ai)
  1586. {
  1587. uint i;
  1588. AllowIP4Item_t *p = ai->list;
  1589. for ( i = 0; i < ai->used; i++, p++ )
  1590. p->count = 0;
  1591. }
  1592. }
  1593. ///////////////////////////////////////////////////////////////////////////////
  1594. void AddCountersAllowIP4
  1595. (
  1596. AllowIP4_t *dest, // NULL or dest for addition
  1597. const AllowIP4_t *src // NULL or source for addition
  1598. )
  1599. {
  1600. if ( dest && dest->used && src && src->used )
  1601. {
  1602. uint is;
  1603. const AllowIP4Item_t *ps = src->list;
  1604. for ( is = 0; is < src->used; is++, ps++ )
  1605. {
  1606. uint id;
  1607. AllowIP4Item_t *pd = dest->list;
  1608. for ( id = 0; id < dest->used; id++, pd++ )
  1609. if ( pd->addr == ps->addr
  1610. && pd->mask == ps->mask
  1611. && pd->mode == ps->mode
  1612. )
  1613. {
  1614. pd->count += ps->count;
  1615. break;
  1616. }
  1617. }
  1618. }
  1619. }
  1620. ///////////////////////////////////////////////////////////////////////////////
  1621. ///////////////////////////////////////////////////////////////////////////////
  1622. static uint print_mode_helper
  1623. ( char *buf, uint bufsize, const KeywordTab_t *keytab, u64 mode )
  1624. {
  1625. ASSERT(buf);
  1626. ASSERT(bufsize>1);
  1627. char *dest = buf, *end = buf + bufsize-1;
  1628. if (keytab)
  1629. {
  1630. mode &= ~(ALLOW_MODE_SET|ALLOW_MODE_AND);
  1631. for ( ; mode && keytab->name1; keytab++ )
  1632. {
  1633. if ( keytab->id & mode )
  1634. {
  1635. dest = StringCat2E(dest,end,keytab->name1," ");
  1636. mode &= ~keytab->id;
  1637. }
  1638. }
  1639. }
  1640. *dest = 0;
  1641. return dest-buf;
  1642. }
  1643. //-----------------------------------------------------------------------------
  1644. void DumpAllowIP4
  1645. (
  1646. FILE *f, // NULL or output file
  1647. int indent, // indention
  1648. const AllowIP4_t *ai, // NULL or source
  1649. const KeywordTab_t *keytab, // NULL or key table for output
  1650. ccp title, // not NULL: Add title
  1651. bool print_tab_head // true: add table headings and separators
  1652. )
  1653. {
  1654. if ( !f || !ai )
  1655. return;
  1656. char buf[200];
  1657. uint i, fw_mode = 5, fw_settings = 8;
  1658. for ( i = 0; i < ai->used; i++ )
  1659. {
  1660. const AllowIP4Item_t *it = ai->list + i;
  1661. uint len = snprintf(buf,sizeof(buf),"%llx",it->mode);
  1662. if ( fw_mode < len )
  1663. fw_mode = len;
  1664. len = print_mode_helper(buf,sizeof(buf),keytab,it->mode);
  1665. if ( fw_settings < len )
  1666. fw_settings = len;
  1667. }
  1668. indent = NormalizeIndent(indent);
  1669. fprintf(f, "%*sAllowIP4[%s]: %u reference%s, %u/%u elements,"
  1670. " fallback:%llx, allow:%llx\n",
  1671. indent,"", title ? title : "",
  1672. ai->ref_counter, ai->ref_counter == 1 ? "" : "s",
  1673. ai->used, ai->size,
  1674. ai->fallback_mode, ai->allow_mode );
  1675. const uint seplen = 52 + fw_mode + fw_settings;
  1676. if (print_tab_head)
  1677. fprintf(f,"\n"
  1678. "%*s counter ipv4 address ipv4/netmask > %-*s"
  1679. " settings\n%*s%.*s\n",
  1680. indent,"", fw_mode+4, "operation",
  1681. indent,"", seplen, Minus300 );
  1682. for ( i = 0; i < ai->used; i++ )
  1683. {
  1684. const AllowIP4Item_t *it = ai->list + i;
  1685. print_mode_helper(buf,sizeof(buf),keytab,it->mode);
  1686. fprintf(f, "%*s%8s %-15s %08x/%08x > %s %*llx %s\n",
  1687. indent, "",
  1688. PrintNumberU7(0,0,it->count,DC_SFORM_ALIGN|DC_SFORM_DASH),
  1689. PrintIP4(0,0,it->addr,-1),
  1690. it->addr, it->mask,
  1691. it->mode & ALLOW_MODE_SET ? "SET"
  1692. : it->mode & ALLOW_MODE_AND ? "AND" : "OR ",
  1693. fw_mode, it->mode, *buf ? buf : "-" );
  1694. }
  1695. if (print_tab_head)
  1696. fprintf(f,"%*s%.*s\n", indent,"", seplen, Minus300 );
  1697. }
  1698. ///////////////////////////////////////////////////////////////////////////////
  1699. ///////////////////////////////////////////////////////////////////////////////
  1700. u64 GetAllowIP4ByAddr ( const AllowIP4_t *ai, u32 addr, u64 if_not_found )
  1701. {
  1702. DASSERT(ai);
  1703. bool found = false;
  1704. uint i;
  1705. u64 res = 0;
  1706. AllowIP4Item_t *it = (AllowIP4Item_t*)ai->list;
  1707. for ( i = 0; i < ai->used; i++, it++ )
  1708. {
  1709. if ( ( addr & it->mask ) == it->addr )
  1710. {
  1711. it->count++;
  1712. found = true;
  1713. if ( it->mode & ALLOW_MODE_SET )
  1714. res = it->mode;
  1715. else if ( it->mode & ALLOW_MODE_AND )
  1716. res &= it->mode;
  1717. else
  1718. res |= it->mode;
  1719. if ( !(it->mode & ALLOW_MODE_CONTINUE) )
  1720. break;
  1721. }
  1722. }
  1723. return found ? res & ALLOW_MODE__MASK : if_not_found;
  1724. }
  1725. ///////////////////////////////////////////////////////////////////////////////
  1726. u64 GetAllowIP4ByName ( const AllowIP4_t *ai, mem_t name, u64 if_not_found )
  1727. {
  1728. DASSERT(ai);
  1729. NetworkHost_t host;
  1730. ResolveHostMem(&host,true,name,0,false,false);
  1731. return host.ip4_valid
  1732. ? GetAllowIP4ByAddr(ai,host.ip4,if_not_found)
  1733. : if_not_found;
  1734. }
  1735. ///////////////////////////////////////////////////////////////////////////////
  1736. u64 GetAutoAllowIP4ByAddr ( const AllowIP4_t *ai, u32 addr )
  1737. {
  1738. if (!ai)
  1739. return ALLOW_MODE_ALLOW;
  1740. const u64 res = GetAllowIP4ByAddr(ai,addr,M1(res));
  1741. return IS_M1(res) ? ai->fallback_mode : res & ALLOW_MODE__MASK;
  1742. }
  1743. ///////////////////////////////////////////////////////////////////////////////
  1744. u64 GetAutoAllowIP4ByName ( const AllowIP4_t *ai, mem_t name )
  1745. {
  1746. if (!ai)
  1747. return ALLOW_MODE_ALLOW;
  1748. NetworkHost_t host;
  1749. ResolveHostMem(&host,true,name,0,false,false);
  1750. return host.ip4_valid
  1751. ? GetAllowIP4ByAddr(ai,host.ip4,ai->fallback_mode)
  1752. : ai->fallback_mode;
  1753. }
  1754. ///////////////////////////////////////////////////////////////////////////////
  1755. u64 GetAutoAllowIP4BySock ( const AllowIP4_t *ai, int sock )
  1756. {
  1757. if (!ai)
  1758. return ALLOW_MODE_ALLOW;
  1759. struct sockaddr_in sa;
  1760. socklen_t sa_len = sizeof(sa);
  1761. if ( getpeername(sock,(struct sockaddr*)&sa,&sa_len) || sa.sin_family != AF_INET )
  1762. return ai->fallback_mode;
  1763. return GetAutoAllowIP4ByAddr(ai,ntohl(sa.sin_addr.s_addr));
  1764. }
  1765. ///////////////////////////////////////////////////////////////////////////////
  1766. ///////////////////////////////////////////////////////////////////////////////
  1767. void SaveCurrentStateAllowIP4
  1768. (
  1769. FILE *f, // output file
  1770. ccp section, // not NULL and not empty: create own section
  1771. ccp name_prefix, // NULL or prefix of name
  1772. uint tab_pos, // tab pos of '='
  1773. const AllowIP4_t *ai // valid struct
  1774. )
  1775. {
  1776. DASSERT(f);
  1777. DASSERT(ai);
  1778. if ( section && *section )
  1779. fprintf(f,"\n#%.50s\n[%s]\n\n",Minus300,section);
  1780. if (!name_prefix)
  1781. name_prefix = EmptyString;
  1782. const int base = 8*tab_pos + 7 - strlen(name_prefix);
  1783. fprintf(f,
  1784. "%s" "fallback%.*s= %#llx\n"
  1785. "%s" "allow%.*s= %#llx\n"
  1786. "%s" "n-rules%.*s= %u\n"
  1787. ,name_prefix, (base-8)/8, Tabs20, ai->fallback_mode
  1788. ,name_prefix, (base-5)/8, Tabs20, ai->allow_mode
  1789. ,name_prefix, (base-7)/8, Tabs20, ai->used
  1790. );
  1791. uint i;
  1792. char name[30];
  1793. for ( i = 0; i < ai->used; i++ )
  1794. {
  1795. const AllowIP4Item_t *it = ai->list + i;
  1796. const uint len = snprintf(name,sizeof(name),"rule-%u",i);
  1797. fprintf(f, "%s%s%.*s= 0x%08x,0x%08x,%#llx,%llu\n",
  1798. name_prefix, name, (base-len)/8, Tabs20,
  1799. it->addr, it->mask, it->mode, it->count );
  1800. }
  1801. }
  1802. ///////////////////////////////////////////////////////////////////////////////
  1803. ///////////////////////////////////////////////////////////////////////////////
  1804. bool ScanAllowIP4Item
  1805. (
  1806. // return true on success; counter is optional
  1807. AllowIP4Item_t *it, // store data here, cleared first
  1808. ccp line // NULL or line to scan
  1809. )
  1810. {
  1811. DASSERT(it);
  1812. memset(it,0,sizeof(*it));
  1813. if (line)
  1814. {
  1815. char *end;
  1816. it->addr = str2ul(line,&end,10);
  1817. if ( end > line )
  1818. {
  1819. line = SkipControls1(end,',');
  1820. it->mask = str2ul(line,&end,10);
  1821. if ( end > line )
  1822. {
  1823. line = SkipControls1(end,',');
  1824. it->mode = str2ull(line,&end,10);
  1825. if ( end > line )
  1826. {
  1827. line = SkipControls1(end,',');
  1828. it->count = str2ull(line,0,10); // optional -> no error check
  1829. return true;
  1830. }
  1831. }
  1832. }
  1833. }
  1834. return false;
  1835. }
  1836. ///////////////////////////////////////////////////////////////////////////////
  1837. ///////////////////////////////////////////////////////////////////////////////
  1838. void RestoreStateAllowIP4
  1839. (
  1840. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  1841. cvp user_table // pointer provided by RestoreStateTab_t[]
  1842. )
  1843. {
  1844. DASSERT(rs);
  1845. if (user_table)
  1846. RestoreStateAllowIP4Ex(rs,(AllowIP4_t*)user_table,0);
  1847. }
  1848. ///////////////////////////////////////////////////////////////////////////////
  1849. void RestoreStateAllowIP4Ex
  1850. (
  1851. RestoreState_t *rs, // info data, modified
  1852. AllowIP4_t *ai, // valid struct
  1853. ccp name_prefix // NULL or prefix of name
  1854. )
  1855. {
  1856. DASSERT(ai);
  1857. DASSERT(rs);
  1858. ClearAllowIP4(ai);
  1859. if (!name_prefix)
  1860. name_prefix = EmptyString;
  1861. char name[200]; // name buf
  1862. snprintf(name,sizeof(name),"%sfallback",name_prefix);
  1863. ai->fallback_mode = GetParamFieldU64(rs,name,ai->fallback_mode);
  1864. snprintf(name,sizeof(name),"%sallow",name_prefix);
  1865. ai->allow_mode = GetParamFieldU64(rs,name,ai->allow_mode);
  1866. snprintf(name,sizeof(name),"%sn-rules",name_prefix);
  1867. const uint n_rules = GetParamFieldUINT(rs,name,0);
  1868. uint i;
  1869. for ( i = 0; i < n_rules; i++ )
  1870. {
  1871. snprintf(name,sizeof(name),"%srule-%u",name_prefix,i);
  1872. ParamFieldItem_t *pfi = GetParamField(rs,name);
  1873. AllowIP4Item_t ait;
  1874. if ( pfi && ScanAllowIP4Item(&ait,(ccp)pfi->data) )
  1875. {
  1876. if ( ai->used == ai->size )
  1877. {
  1878. ai->size = 11*ai->size/10 + 10;
  1879. ai->list = REALLOC(ai->list,ai->size*sizeof(*ai->list));
  1880. }
  1881. DASSERT( ai->used < ai->size );
  1882. DASSERT( ai->list );
  1883. ai->list[ai->used++] = ait;
  1884. }
  1885. }
  1886. }
  1887. //
  1888. ///////////////////////////////////////////////////////////////////////////////
  1889. /////////////// TCP + UDP connections ///////////////
  1890. ///////////////////////////////////////////////////////////////////////////////
  1891. int ConnectByHost
  1892. (
  1893. NetworkHost_t *host, // valid pointer to NetworkHost_t
  1894. int type, // AF_INET type, e.g. SOCK_STREAM, SOCK_DGRAM
  1895. int protocol, // AF_INET protocol, e.g. IPPROTO_TCP, IPPROTO_UDP
  1896. bool silent // true: suppress error messages
  1897. )
  1898. {
  1899. DASSERT(host);
  1900. int sock = socket(AF_INET,type,protocol);
  1901. if ( sock == -1 )
  1902. {
  1903. if (!silent)
  1904. ERROR1(ERR_CANT_CONNECT,
  1905. "Can't create socket: %s\n",
  1906. GetHostName(host));
  1907. return -1;
  1908. }
  1909. if (connect(sock,(struct sockaddr *)&host->sa,sizeof(host->sa)))
  1910. {
  1911. if (!silent)
  1912. ERROR1(ERR_CANT_CONNECT,
  1913. "Can't connect to %s:%d\n",
  1914. GetHostName(host), host->port );
  1915. close(sock);
  1916. return -1;
  1917. }
  1918. return sock;
  1919. }
  1920. ///////////////////////////////////////////////////////////////////////////////
  1921. int ConnectByHostTCP
  1922. (
  1923. NetworkHost_t *host, // valid pointer to NetworkHost_t
  1924. bool silent // true: suppress error messages
  1925. )
  1926. {
  1927. DASSERT(host);
  1928. return ConnectByHost(host,SOCK_STREAM,IPPROTO_TCP,silent);
  1929. }
  1930. ///////////////////////////////////////////////////////////////////////////////
  1931. int ConnectTCP
  1932. (
  1933. ccp addr, // optional service + server + optional host
  1934. // e.g.: "service://host:port/....."
  1935. int default_port, // default port
  1936. bool silent // true: suppress error messages
  1937. )
  1938. {
  1939. Setup_ConnectTCP_Hook(false);
  1940. ccp unix_path = CheckUnixSocketPath(addr,0);
  1941. if (unix_path)
  1942. return ConnectUnixTCP(unix_path,silent);
  1943. if (!strncasecmp(addr,"tcp:",4))
  1944. addr += 4;
  1945. NetworkHost_t host;
  1946. int sock = -1;
  1947. if (ResolveHost(&host,true,addr,default_port,false,true))
  1948. sock = ConnectByHost(&host,SOCK_STREAM,IPPROTO_TCP,silent);
  1949. ResetHost(&host);
  1950. return sock;
  1951. }
  1952. ///////////////////////////////////////////////////////////////////////////////
  1953. void Setup_ConnectTCP_Hook ( bool force )
  1954. {
  1955. if ( force || !ConnectTCP_Hook )
  1956. ConnectTCP_Hook = ConnectTCP;
  1957. }
  1958. ///////////////////////////////////////////////////////////////////////////////
  1959. ///////////////////////////////////////////////////////////////////////////////
  1960. int ConnectByHostUDP
  1961. (
  1962. NetworkHost_t *host, // valid pointer to NetworkHost_t
  1963. bool silent // true: suppress error messages
  1964. )
  1965. {
  1966. DASSERT(host);
  1967. return ConnectByHost(host,SOCK_DGRAM,IPPROTO_UDP,silent);
  1968. }
  1969. ///////////////////////////////////////////////////////////////////////////////
  1970. int ConnectUDP
  1971. (
  1972. ccp name, // optional service + server + optional host
  1973. // e.g.: "service://host:port/....."
  1974. int default_host, // default host
  1975. bool silent // true: suppress error messages
  1976. )
  1977. {
  1978. NetworkHost_t host;
  1979. int sock = -1;
  1980. if (ResolveHost(&host,true,name,default_host,false,true))
  1981. sock = ConnectByHost(&host,SOCK_DGRAM,IPPROTO_UDP,silent);
  1982. ResetHost(&host);
  1983. return sock;
  1984. }
  1985. ///////////////////////////////////////////////////////////////////////////////
  1986. ///////////////////////////////////////////////////////////////////////////////
  1987. int WillReceiveNotBlock
  1988. (
  1989. // returns: -1:error, 0:may block, 1:will not block
  1990. int fd, // file handle of source
  1991. uint msec // timeout: 0:no timeout, >0: milliseconds
  1992. )
  1993. {
  1994. fd_set read_set;
  1995. FD_ZERO(&read_set);
  1996. FD_SET(fd,&read_set);
  1997. struct timeval timeout;
  1998. timeout.tv_sec = msec/1000;
  1999. timeout.tv_usec = (msec%1000) * 1000;
  2000. errno = 0;
  2001. const int stat = select(fd+1,&read_set,0,0,&timeout);
  2002. return stat < 0 ? stat : stat > 0 && FD_ISSET(fd,&read_set);
  2003. }
  2004. ///////////////////////////////////////////////////////////////////////////////
  2005. ssize_t ReceiveTimeout
  2006. (
  2007. // returns: <0: on error, 0:timeout, >0: bytes read
  2008. int fd, // file handle of source
  2009. void *buf, // valid pointer to buffer
  2010. uint size, // size to receive
  2011. int flags, // flags for recv()
  2012. int msec // timeout: -1:unlimited, 0:no timeout, >0: milliseconds
  2013. )
  2014. {
  2015. if ( fd == -1 )
  2016. return -1;
  2017. if ( !buf || !size )
  2018. return 0;
  2019. if ( msec >= 0 )
  2020. {
  2021. fd_set read_set;
  2022. FD_ZERO(&read_set);
  2023. FD_SET(fd,&read_set);
  2024. struct timeval timeout;
  2025. timeout.tv_sec = msec/1000;
  2026. timeout.tv_usec = (msec%1000) * 1000;
  2027. errno = 0;
  2028. const int stat = select(fd+1,&read_set,0,0,&timeout);
  2029. if ( stat <= 0 )
  2030. return stat;
  2031. }
  2032. return recv(fd,buf,size,flags);
  2033. }
  2034. ///////////////////////////////////////////////////////////////////////////////
  2035. ///////////////////////////////////////////////////////////////////////////////
  2036. int WillSendNotBlock
  2037. (
  2038. // returns: -1:error, 0:may block, 1:will not block
  2039. int fd, // file handle of source
  2040. uint msec // timeout: 0:no timeout, >0: milliseconds
  2041. )
  2042. {
  2043. fd_set write_set;
  2044. FD_ZERO(&write_set);
  2045. FD_SET(fd,&write_set);
  2046. struct timeval timeout; // kein Warten
  2047. timeout.tv_sec = msec/1000;
  2048. timeout.tv_usec = (msec%1000) * 1000;
  2049. errno = 0;
  2050. const int stat = select(fd+1,0,&write_set,0,&timeout);
  2051. return stat < 0 ? stat : stat > 0 && FD_ISSET(fd,&write_set);
  2052. }
  2053. ///////////////////////////////////////////////////////////////////////////////
  2054. ssize_t SendTimeout
  2055. (
  2056. // returns: <0: on error, 0:timeout, >0: bytes written
  2057. int fd, // file hande of destination
  2058. const void *data, // valid pointer to data
  2059. uint size, // size to receive
  2060. int flags, // flags for send()
  2061. int msec, // total timeout: -1:unlimited, 0:no timeout, >0: milliseconds
  2062. bool all // true: send all data until done, total timeout or error
  2063. )
  2064. {
  2065. if ( fd == -1 )
  2066. return -1;
  2067. if ( !data || !size )
  2068. return 0;
  2069. //--- send loop for complete sending
  2070. if (all)
  2071. {
  2072. uint max_time = msec < 0 ? 0 : GetTimerMSec() + msec;
  2073. ssize_t total = 0;
  2074. while (size)
  2075. {
  2076. ssize_t stat = SendTimeout(fd,data,size,flags,msec,false);
  2077. if ( stat < 0 )
  2078. return stat;
  2079. data = (u8*)data + stat;
  2080. size -= stat;
  2081. total += stat;
  2082. if ( msec >= 0 )
  2083. {
  2084. msec = max_time - GetTimerMSec();
  2085. if ( msec < 0 )
  2086. break;
  2087. }
  2088. }
  2089. return total;
  2090. }
  2091. //--- send, single try
  2092. if ( msec >= 0 )
  2093. {
  2094. fd_set write_set;
  2095. FD_ZERO(&write_set);
  2096. FD_SET(fd,&write_set);
  2097. struct timeval timeout;
  2098. timeout.tv_sec = msec/1000;
  2099. timeout.tv_usec = (msec%1000) * 1000;
  2100. errno = 0;
  2101. const int stat = select(fd+1,0,&write_set,0,&timeout);
  2102. if ( stat <= 0 )
  2103. return stat;
  2104. }
  2105. return send(fd,data,size,flags);
  2106. }
  2107. //
  2108. ///////////////////////////////////////////////////////////////////////////////
  2109. /////////////// IP interface: check sums ///////////////
  2110. ///////////////////////////////////////////////////////////////////////////////
  2111. u16 CalcChecksumIP4
  2112. (
  2113. const void *data, // ip4 header
  2114. // make sure, that the checksum member is NULL
  2115. uint size // size of ip4 header
  2116. )
  2117. {
  2118. // http://en.wikipedia.org/wiki/IPv4_header_checksum
  2119. DASSERT(data);
  2120. const u16 *ptr = (u16*)data;
  2121. u32 csum = 0;
  2122. while ( size > 1 )
  2123. {
  2124. csum += ntohs(*ptr++);
  2125. size -= 2;
  2126. }
  2127. if (size)
  2128. csum += *(u8*)ptr << 8;
  2129. return ~( ( csum >> 16 ) + ( csum & 0xffff ));
  2130. }
  2131. ///////////////////////////////////////////////////////////////////////////////
  2132. u16 CalcChecksumUDP
  2133. (
  2134. const ip4_head_t *ip4, // IP4 header
  2135. const udp_head_t *udp, // UDP header
  2136. const void *data // UDP data, size is 'udp->data_len'
  2137. )
  2138. {
  2139. DASSERT(ip4);
  2140. DASSERT(udp);
  2141. DASSERT( data || !udp->data_len );
  2142. int dlen = ntohs(udp->data_len);
  2143. u32 csum = ntohs(((u16*)&ip4->ip_src)[0])
  2144. + ntohs(((u16*)&ip4->ip_src)[1])
  2145. + ntohs(((u16*)&ip4->ip_dest)[0])
  2146. + ntohs(((u16*)&ip4->ip_dest)[1])
  2147. + ip4->protocol
  2148. + ntohs(udp->port_src)
  2149. + ntohs(udp->port_dest)
  2150. + 2*dlen;
  2151. dlen -= 8;
  2152. const u16 *ptr = (u16*)data;
  2153. while ( dlen > 1 )
  2154. {
  2155. csum += ntohs(*ptr++);
  2156. dlen -= 2;
  2157. }
  2158. if ( dlen > 0 )
  2159. csum += *(u8*)ptr << 8;
  2160. while ( csum >= 0x10000 )
  2161. csum = (u32)((u16*)&csum)[0] + (u32)((u16*)&csum)[1];
  2162. return csum == 0xffff ? 0xffff : htons(~csum);
  2163. }
  2164. //
  2165. ///////////////////////////////////////////////////////////////////////////////
  2166. /////////////// UNIX sockets ///////////////
  2167. ///////////////////////////////////////////////////////////////////////////////
  2168. enumError SendUnixUDP
  2169. (
  2170. ccp path1, // NULL or part #1 of path
  2171. ccp path2, // NULL or part #2 of path
  2172. bool silent, // suppress all error messages
  2173. cvp data, // data to send
  2174. uint size // size of 'data'
  2175. )
  2176. {
  2177. if ( !data || !size )
  2178. return ERR_NOTHING_TO_DO;
  2179. char pathbuf[PATH_MAX];
  2180. ccp path = PathCatPP(pathbuf,sizeof(pathbuf),path1,path2);
  2181. PRINT("SendUnixUDP(%s)\n",path);
  2182. static int sock = -1;
  2183. if ( sock == -1 )
  2184. {
  2185. sock = socket(AF_UNIX,SOCK_STREAM|SOCK_CLOEXEC,0);
  2186. if ( sock == -1 )
  2187. {
  2188. if (!silent)
  2189. ERROR1(ERR_CANT_CREATE,
  2190. "Can't create UNIX stream socket: %s\n",path);
  2191. return ERR_CANT_CREATE;
  2192. }
  2193. }
  2194. struct sockaddr_un sa;
  2195. memset(&sa,0,sizeof(sa));
  2196. sa.sun_family = AF_UNIX;
  2197. StringCopyS(sa.sun_path,sizeof(sa.sun_path),path);
  2198. if ( sendto(sock,data,size,0,(struct sockaddr*)&sa,sizeof(sa)) < 0 )
  2199. {
  2200. if (!silent)
  2201. ERROR1(ERR_WRITE_FAILED,
  2202. "Can't send %u bytes to UNIX stream socket: %s\n",
  2203. size, path );
  2204. return ERR_WRITE_FAILED;
  2205. }
  2206. return ERR_OK;
  2207. }
  2208. //
  2209. ///////////////////////////////////////////////////////////////////////////////
  2210. /////////////// Transfer Statistics ///////////////
  2211. ///////////////////////////////////////////////////////////////////////////////
  2212. TransferStats_t * Add2TransferStats
  2213. (
  2214. // return dest
  2215. // calculate: dest += src
  2216. TransferStats_t *dest, // NULL or destination and first source
  2217. const TransferStats_t *src // NULL or second source
  2218. )
  2219. {
  2220. if ( dest && src )
  2221. {
  2222. dest->conn_count += src->conn_count;
  2223. dest->recv_count += src->recv_count;
  2224. dest->recv_size += src->recv_size;
  2225. dest->send_count += src->send_count;
  2226. dest->send_size += src->send_size;
  2227. }
  2228. return dest;
  2229. }
  2230. ///////////////////////////////////////////////////////////////////////////////
  2231. TransferStats_t * Sub2TransferStats
  2232. (
  2233. // return dest
  2234. // calculate: dest -= src
  2235. TransferStats_t *dest, // NULL or destination and first source
  2236. const TransferStats_t *src // NULL or second source
  2237. )
  2238. {
  2239. if ( dest && src )
  2240. {
  2241. dest->conn_count -= src->conn_count;
  2242. dest->recv_count -= src->recv_count;
  2243. dest->recv_size -= src->recv_size;
  2244. dest->send_count -= src->send_count;
  2245. dest->send_size -= src->send_size;
  2246. }
  2247. return dest;
  2248. }
  2249. ///////////////////////////////////////////////////////////////////////////////
  2250. TransferStats_t * Add3TransferStats
  2251. (
  2252. // return dest
  2253. // calculate: dest = src1 + src2
  2254. TransferStats_t *dest, // NULL or destination (maybe same as source)
  2255. const TransferStats_t *src1, // NULL or first source
  2256. const TransferStats_t *src2 // NULL or second source
  2257. )
  2258. {
  2259. if (dest)
  2260. {
  2261. if (!src1)
  2262. {
  2263. if (src2)
  2264. memcpy(dest,src2,sizeof(*dest));
  2265. else
  2266. memset(dest,0,sizeof(*dest));
  2267. }
  2268. else if (!src2)
  2269. {
  2270. DASSERT(src1);
  2271. memcpy(dest,src1,sizeof(*dest));
  2272. }
  2273. else
  2274. {
  2275. DASSERT(src1);
  2276. DASSERT(src2);
  2277. dest->conn_count = src1->conn_count + src2->conn_count;
  2278. dest->recv_count = src1->recv_count + src2->recv_count;
  2279. dest->recv_size = src1->recv_size + src2->recv_size;
  2280. dest->send_count = src1->send_count + src2->send_count;
  2281. dest->send_size = src1->send_size + src2->send_size;
  2282. }
  2283. }
  2284. return dest;
  2285. }
  2286. ///////////////////////////////////////////////////////////////////////////////
  2287. TransferStats_t * Sub3TransferStats
  2288. (
  2289. // return dest
  2290. // calculate: dest = src1 - src2
  2291. TransferStats_t *dest, // NULL or destination (maybe same as source)
  2292. const TransferStats_t *src1, // NULL or first source
  2293. const TransferStats_t *src2 // NULL or second source
  2294. )
  2295. {
  2296. if (dest)
  2297. {
  2298. if (!src1)
  2299. {
  2300. if (src2)
  2301. {
  2302. TransferStats_t temp;
  2303. memset(&temp,0,sizeof(temp));
  2304. Sub3TransferStats(dest,&temp,src2);
  2305. }
  2306. else
  2307. memset(dest,0,sizeof(*dest));
  2308. }
  2309. else if (!src2)
  2310. {
  2311. DASSERT(src1);
  2312. memcpy(dest,src1,sizeof(*dest));
  2313. }
  2314. else
  2315. {
  2316. DASSERT(src1);
  2317. DASSERT(src2);
  2318. dest->conn_count = src1->conn_count - src2->conn_count;
  2319. dest->recv_count = src1->recv_count - src2->recv_count;
  2320. dest->recv_size = src1->recv_size - src2->recv_size;
  2321. dest->send_count = src1->send_count - src2->send_count;
  2322. dest->send_size = src1->send_size - src2->send_size;
  2323. }
  2324. }
  2325. return dest;
  2326. }
  2327. ///////////////////////////////////////////////////////////////////////////////
  2328. TransferStats_t * SumTransferStats
  2329. (
  2330. // return dest
  2331. // calculate: dest = sum(all_sources)
  2332. TransferStats_t *dest, // NULL or destination (maybe same as source)
  2333. const TransferStats_t * const *src, // NULL or source list, elements may be NULL
  2334. int n_src // number of element; if -1: term at first NULL
  2335. )
  2336. {
  2337. if (dest)
  2338. {
  2339. TransferStats_t temp;
  2340. memset(&temp,0,sizeof(temp));
  2341. if (src)
  2342. {
  2343. if ( n_src < 0 )
  2344. while ( *src )
  2345. Add2TransferStats(&temp,*src++);
  2346. else
  2347. for ( ; *src; src++ )
  2348. if (*src)
  2349. Add2TransferStats(&temp,*src);
  2350. }
  2351. memcpy(dest,&temp,sizeof(*dest));
  2352. }
  2353. return dest;
  2354. }
  2355. ///////////////////////////////////////////////////////////////////////////////
  2356. ccp PrintTransferStatsSQL
  2357. (
  2358. // print statistic as SQL assigning list.
  2359. // arguments are speparated by a comma.
  2360. char *buf, // result buffer
  2361. // NULL: use a local circulary static buffer
  2362. size_t buf_size, // size of 'buf', ignored if buf==NULL
  2363. const TransferStats_t *ts, // valid source
  2364. ccp prefix // not NULL: prefix member names
  2365. )
  2366. {
  2367. DASSERT(ts);
  2368. const bool alloced = !buf;
  2369. if (alloced)
  2370. buf = GetCircBuf( buf_size = CIRC_BUF_MAX_ALLOC );
  2371. if (!prefix)
  2372. prefix = "";
  2373. const uint len
  2374. = snprintf( buf, buf_size,
  2375. "%sconn=%u, %srecv_n=%u, %srecv=%llu, %ssend_n=%u, %ssend=%llu",
  2376. prefix, ts->conn_count,
  2377. prefix, ts->recv_count,
  2378. prefix, ts->recv_size,
  2379. prefix, ts->send_count,
  2380. prefix, ts->send_size );
  2381. if ( alloced && len < buf_size )
  2382. ReleaseCircBuf(buf+buf_size,buf_size-len-1);
  2383. return buf;
  2384. }
  2385. ///////////////////////////////////////////////////////////////////////////////
  2386. ///////////////////////////////////////////////////////////////////////////////
  2387. static inline u32 calc_rate ( u64 count, u64 duration )
  2388. { return ( count * USEC_PER_SEC + duration/2 ) / duration; }
  2389. static inline double calc_drate ( u64 count, u64 duration )
  2390. { return (double)( count * USEC_PER_SEC ) / duration; }
  2391. ///////////////////////////////////////////////////////////////////////////////
  2392. void PrintTranferStatistics
  2393. (
  2394. FILE *f, // output file, never NULL
  2395. ccp prefix, // NULL or prefix for each line
  2396. ccp name, // statistics name, up to 5 chars including colon
  2397. const TransferStats_t *stat,// statistics record
  2398. TransferStats_t *prev, // NULL statistics record with previous data
  2399. u64 duration, // delta duration in usec
  2400. ccp duration_info, // text representation of 'duration'
  2401. const ColorSet_t *colset // NULL (no colors) or color set to use
  2402. )
  2403. {
  2404. DASSERT(f);
  2405. DASSERT(name);
  2406. DASSERT(stat);
  2407. if (!prefix)
  2408. prefix = "";
  2409. if (!colset)
  2410. colset = GetColorSet0();
  2411. ccp color1 = colset->status;
  2412. ccp color0 = colset->reset;
  2413. if (stat->conn_count)
  2414. {
  2415. fprintf(f,
  2416. "%s%s#STAT-%-5s %u connect%s,"
  2417. " %u packet%s (%s) received, %u packet%s (%s) send.%s\n",
  2418. prefix, color1, name,
  2419. stat->conn_count, stat->conn_count == 1 ? "" : "s",
  2420. stat->recv_count, stat->recv_count == 1 ? "" : "s",
  2421. PrintSize1024(0,0,stat->recv_size,0),
  2422. stat->send_count, stat->send_count == 1 ? "" : "s",
  2423. PrintSize1024(0,0,stat->send_size,0),
  2424. color0 );
  2425. }
  2426. else if ( stat->recv_count || stat->send_count )
  2427. {
  2428. fprintf(f,
  2429. "%s%s#STAT-%-5s %u packet%s (%s) received, %u packet%s (%s) send.%s\n",
  2430. prefix, color1, name,
  2431. stat->recv_count, stat->recv_count == 1 ? "" : "s",
  2432. PrintSize1024(0,0,stat->recv_size,0),
  2433. stat->send_count, stat->send_count == 1 ? "" : "s",
  2434. PrintSize1024(0,0,stat->send_size,0),
  2435. color0 );
  2436. }
  2437. else
  2438. return;
  2439. if ( duration > 0 && prev )
  2440. {
  2441. TransferStats_t delta;
  2442. Sub3TransferStats(&delta,stat,prev);
  2443. char duration_buf[10];
  2444. if (!duration_info)
  2445. {
  2446. PrintTimerUSec6(duration_buf,sizeof(duration_buf),duration,false);
  2447. duration_info = duration_buf;
  2448. }
  2449. if ( delta.recv_count )
  2450. {
  2451. const double crate = calc_drate( delta.recv_count, duration );
  2452. const u32 srate = calc_rate( delta.recv_size, duration );
  2453. fprintf(f,
  2454. "%s%s#STAT-%-5s >Last "
  2455. "%s: %u (%4.2f/s) packet%s with %s (%s/s) received.%s\n",
  2456. prefix, color1, name,
  2457. duration_info,
  2458. delta.recv_count, crate,
  2459. delta.recv_count == 1 ? "" : "s",
  2460. PrintSize1024(0,0,delta.recv_size,0),
  2461. PrintSize1024(0,0,srate,0),
  2462. color0 );
  2463. }
  2464. if ( delta.send_count )
  2465. {
  2466. const double crate = calc_drate( delta.send_count, duration );
  2467. const u32 srate = calc_rate( delta.send_size, duration );
  2468. fprintf(f,
  2469. "%s%s#STAT-%-5s >Last "
  2470. "%s: %u (%4.2f/s) packet%s with %s (%s/s) send.%s\n",
  2471. prefix, color1, name,
  2472. duration_info,
  2473. delta.send_count, crate,
  2474. delta.send_count == 1 ? "" : "s",
  2475. PrintSize1024(0,0,delta.send_size,0),
  2476. PrintSize1024(0,0,srate,0),
  2477. color0 );
  2478. }
  2479. }
  2480. }
  2481. ///////////////////////////////////////////////////////////////////////////////
  2482. ///////////////////////////////////////////////////////////////////////////////
  2483. void SaveCurrentStateTransferStats
  2484. (
  2485. FILE *f, // output file
  2486. const TransferStats_t *stat // valid stat object
  2487. )
  2488. {
  2489. DASSERT(f);
  2490. DASSERT(stat);
  2491. fprintf(f,
  2492. "conn-count = %u\n"
  2493. "recv-count = %u\n"
  2494. "recv-size = %llu\n"
  2495. "send-count = %u\n"
  2496. "send-size = %llu\n"
  2497. ,stat->conn_count
  2498. ,stat->recv_count
  2499. ,stat->recv_size
  2500. ,stat->send_count
  2501. ,stat->send_size
  2502. );
  2503. }
  2504. ///////////////////////////////////////////////////////////////////////////////
  2505. void SaveCurrentStateTransferStats1
  2506. (
  2507. // print as single line
  2508. FILE *f, // output file
  2509. ccp name, // var name; use "tfer-stat" if NULL or EMPTY
  2510. const TransferStats_t *stat // valid stat object
  2511. )
  2512. {
  2513. DASSERT(f);
  2514. DASSERT(stat);
  2515. if ( !name || !*name )
  2516. name = "tfer-stat";
  2517. const int tab_size = ( 23 - strlen(name) ) / 8;
  2518. fprintf(f,
  2519. "%s%.*s= %u,%u,%llu,%u,%llu\n"
  2520. ,name
  2521. ,tab_size > 0 ? tab_size : 0
  2522. ,"\t\t"
  2523. ,stat->conn_count
  2524. ,stat->recv_count
  2525. ,stat->recv_size
  2526. ,stat->send_count
  2527. ,stat->send_size
  2528. );
  2529. }
  2530. ///////////////////////////////////////////////////////////////////////////////
  2531. void SaveCurrentStateTransferStatsN
  2532. (
  2533. // print multiple stats each as single line
  2534. FILE *f, // output file
  2535. ccp name, // var name; use "tfer-stat-" if NULL or EMPTY
  2536. const TransferStats_t *stat, // list of valid stat objects
  2537. uint n_stat // number of elements in 'stat'
  2538. )
  2539. {
  2540. DASSERT(f);
  2541. DASSERT(stat||!n_stat);
  2542. if ( !name || !*name )
  2543. name = "tfer-stat-";
  2544. const int tab_size = ( 23 - strlen(name) ) / 8;
  2545. fprintf(f,"%sn%.*s= %u\n",
  2546. name, tab_size > 0 ? tab_size : 0, "\t\t", n_stat );
  2547. uint i;
  2548. char buf[100];
  2549. for ( i = 0; i < n_stat; i++ )
  2550. {
  2551. snprintf(buf,sizeof(buf),"%s%u",name,i);
  2552. SaveCurrentStateTransferStats1(f,buf,stat++);
  2553. }
  2554. }
  2555. ///////////////////////////////////////////////////////////////////////////////
  2556. ///////////////////////////////////////////////////////////////////////////////
  2557. void RestoreStateTransferStats
  2558. (
  2559. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  2560. cvp user_table // pointer provided by RestoreStateTab_t[]
  2561. )
  2562. {
  2563. DASSERT(rs);
  2564. TransferStats_t *stat = (TransferStats_t*)user_table;
  2565. if (!stat)
  2566. return;
  2567. stat->conn_count = GetParamFieldUINT( rs, "conn-count", stat->conn_count );
  2568. stat->recv_count = GetParamFieldUINT( rs, "recv-count", stat->recv_count );
  2569. stat->send_count = GetParamFieldUINT( rs, "send-count", stat->send_count );
  2570. stat->recv_size = GetParamFieldU64 ( rs, "recv-size", stat->recv_size );
  2571. stat->send_size = GetParamFieldU64 ( rs, "send-size", stat->send_size );
  2572. }
  2573. ///////////////////////////////////////////////////////////////////////////////
  2574. void RestoreStateTransferStats1
  2575. (
  2576. // scan single line
  2577. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  2578. ccp name, // var name; use "tfer-stat" if NULL or EMPTY
  2579. TransferStats_t *stat, // valid stat object
  2580. bool fall_back // true: fall back to RestoreStateTransferStats()
  2581. )
  2582. {
  2583. DASSERT(rs);
  2584. DASSERT(stat);
  2585. if ( !name || !*name )
  2586. name = "tfer-stat";
  2587. char buf[100];
  2588. int res = GetParamFieldBUF( buf, sizeof(buf), rs, name, ENCODE_OFF, 0 );
  2589. if ( res > 0 )
  2590. {
  2591. memset(stat,0,sizeof(*stat));
  2592. char *ptr;
  2593. stat->conn_count = strtoul (buf,&ptr,10); if (*ptr == ',' ) ptr++;
  2594. stat->recv_count = strtoul (ptr,&ptr,10); if (*ptr == ',' ) ptr++;
  2595. stat->recv_size = strtoull(ptr,&ptr,10); if (*ptr == ',' ) ptr++;
  2596. stat->send_count = strtoul (ptr,&ptr,10); if (*ptr == ',' ) ptr++;
  2597. stat->send_size = strtoull(ptr,&ptr,10);
  2598. return;
  2599. }
  2600. if (fall_back)
  2601. RestoreStateTransferStats(rs,stat);
  2602. }
  2603. ///////////////////////////////////////////////////////////////////////////////
  2604. uint RestoreStateTransferStatsN
  2605. (
  2606. // print multiple stats each as single line
  2607. // returns the number of read elements; all others are set to NULL
  2608. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  2609. ccp name, // var name; use "tfer-stat-" if NULL or EMPTY
  2610. TransferStats_t *stat, // list of valid stat objects
  2611. uint n_stat // number of elements in 'stat'
  2612. )
  2613. {
  2614. DASSERT(rs);
  2615. DASSERT(stat||!n_stat);
  2616. if ( !name || !*name )
  2617. name = "tfer-stat-";
  2618. memset(stat,0,n_stat*sizeof(*stat));
  2619. char buf[100];
  2620. snprintf(buf,sizeof(buf),"%sn",name);
  2621. uint n_read = GetParamFieldUINT(rs,buf,0);
  2622. if ( n_read > n_stat )
  2623. n_read = n_stat;
  2624. uint i;
  2625. for ( i = 0; i < n_read; i++ )
  2626. {
  2627. snprintf(buf,sizeof(buf),"%s%u",name,i);
  2628. RestoreStateTransferStats1(rs,buf,stat++,false);
  2629. }
  2630. return n_read;
  2631. }
  2632. //
  2633. ///////////////////////////////////////////////////////////////////////////////
  2634. /////////////// TCP HANDLER ///////////////
  2635. ///////////////////////////////////////////////////////////////////////////////
  2636. #define LOG_TCP HAVE_PRINT0
  2637. #undef INC_TCP_INDENT
  2638. #undef DEC_TCP_INDENT
  2639. #undef LOG_TCP_BUFFER
  2640. #if LOG_TCP
  2641. static int tcp_indent = 5;
  2642. #define INC_TCP_INDENT tcp_indent += 2
  2643. #define DEC_TCP_INDENT tcp_indent -= 2
  2644. #define LOG_TCP_BUFFER(tb,f,...) LogGrowBuffer(stderr,tcp_indent,tb,f,__VA_ARGS__)
  2645. #define LOG_TCP_STREAM(ts,r,f,...) LogTCPStream(stderr,tcp_indent,ts,r,f,__VA_ARGS__)
  2646. #define LOG_TCP_HANDLER(th,r,f,...) LogTCPHandler(stderr,tcp_indent,th,r,f,__VA_ARGS__)
  2647. #else
  2648. #define INC_TCP_INDENT
  2649. #define DEC_TCP_INDENT
  2650. #define LOG_TCP_BUFFER(tb,f,...)
  2651. #define LOG_TCP_STREAM(ts,r,f,...)
  2652. #define LOG_TCP_HANDLER(th,r,f,...)
  2653. #endif
  2654. //
  2655. ///////////////////////////////////////////////////////////////////////////////
  2656. /////////////// TCPStream_t ///////////////
  2657. ///////////////////////////////////////////////////////////////////////////////
  2658. void InitializeTCPStream ( TCPStream_t *ts, int sock )
  2659. {
  2660. DASSERT(ts);
  2661. memset(ts,0,sizeof(*ts));
  2662. ts->unique_id = CreateUniqueId();
  2663. ts->sock = sock;
  2664. ts->poll_index = M1(ts->poll_index);
  2665. LOG_TCP_STREAM(ts,0,"%s","INIT()");
  2666. INC_TCP_INDENT;
  2667. InitializeGrowBuffer(&ts->ibuf,0x4000);
  2668. InitializeGrowBuffer(&ts->obuf,0x4000);
  2669. DEC_TCP_INDENT;
  2670. }
  2671. ///////////////////////////////////////////////////////////////////////////////
  2672. void ResetTCPStream
  2673. (
  2674. TCPStream_t *ts // valid TCP handler
  2675. )
  2676. {
  2677. DASSERT(ts);
  2678. LogTCPStreamActivity(ts,"ResetTCPStream");
  2679. TCPHandler_t *th = ts->handler;
  2680. if (th)
  2681. {
  2682. if (th->OnDestroyStream)
  2683. th->OnDestroyStream(ts);
  2684. th->used_streams--;
  2685. }
  2686. if ( ts->sock != -1 )
  2687. {
  2688. shutdown(ts->sock,SHUT_RDWR);
  2689. close(ts->sock);
  2690. ts->sock = -1;
  2691. }
  2692. INC_TCP_INDENT;
  2693. ResetGrowBuffer(&ts->ibuf);
  2694. ResetGrowBuffer(&ts->obuf);
  2695. DEC_TCP_INDENT;
  2696. if (th)
  2697. {
  2698. // chain is only valid if part of TCP-handler
  2699. if (ts->prev)
  2700. ts->prev->next = ts->next;
  2701. if (ts->next)
  2702. ts->next->prev = ts->prev;
  2703. if ( th->first == ts )
  2704. th->first = ts->next;
  2705. }
  2706. memset(ts,0,sizeof(*ts));
  2707. }
  2708. ///////////////////////////////////////////////////////////////////////////////
  2709. void DestroyTCPStream
  2710. (
  2711. TCPStream_t *ts // valid TCP handler
  2712. )
  2713. {
  2714. DASSERT(ts);
  2715. LogTCPStreamActivity(ts,"DestroyTCPStream");
  2716. ResetTCPStream(ts);
  2717. FREE(ts);
  2718. }
  2719. ///////////////////////////////////////////////////////////////////////////////
  2720. ssize_t UpdateRecvStatTCPStream
  2721. (
  2722. // returns 'send_stat'
  2723. TCPStream_t *ts, // valid TCP handler
  2724. ssize_t recv_stat, // result of recv(), update stats on >0
  2725. u64 now_usec // NULL or current time
  2726. )
  2727. {
  2728. DASSERT(ts);
  2729. if ( recv_stat > 0 )
  2730. {
  2731. ts->receive_usec = now_usec ? now_usec : GetTimeUSec(false);
  2732. ts->stat.recv_count++;
  2733. ts->stat.recv_size += recv_stat;
  2734. if (ts->xstat)
  2735. {
  2736. ts->xstat->recv_count++;
  2737. ts->xstat->recv_size += recv_stat;
  2738. }
  2739. if (ts->handler)
  2740. {
  2741. ts->handler->stat.recv_count++;
  2742. ts->handler->stat.recv_size += recv_stat;
  2743. }
  2744. }
  2745. return recv_stat;
  2746. }
  2747. ///////////////////////////////////////////////////////////////////////////////
  2748. ssize_t UpdateSendStatTCPStream
  2749. (
  2750. // returns 'send_stat'
  2751. TCPStream_t *ts, // valid TCP handler
  2752. ssize_t send_stat, // result of send(), update stats on >0
  2753. u64 now_usec // NULL or current time
  2754. )
  2755. {
  2756. DASSERT(ts);
  2757. if ( send_stat > 0 )
  2758. {
  2759. ts->send_usec = now_usec ? now_usec : GetTimeUSec(false);
  2760. ts->stat.send_count++;
  2761. ts->stat.send_size += send_stat;
  2762. if (ts->xstat)
  2763. {
  2764. ts->xstat->send_count++;
  2765. ts->xstat->send_size += send_stat;
  2766. }
  2767. if (ts->handler)
  2768. {
  2769. ts->handler->stat.send_count++;
  2770. ts->handler->stat.send_size += send_stat;
  2771. }
  2772. }
  2773. return send_stat;
  2774. }
  2775. ///////////////////////////////////////////////////////////////////////////////
  2776. ///////////////////////////////////////////////////////////////////////////////
  2777. int WriteDirectGrowBuffer
  2778. (
  2779. // write() data direct without blocking and without calling any notifier.
  2780. // If output buf is not empty or send failed, append the data to 'gb'.
  2781. // Returns the number of bytes added to the grow buffer or -1 on error.
  2782. // The data is send+stored completely (returns 'size') or not at all
  2783. // (returns '0'). -1 is returned if the socket is invalid.
  2784. GrowBuffer_t *gb, // grow buffer to cache data
  2785. int fd, // destination file
  2786. bool flush_output, // true: try to flush 'gb' before
  2787. cvp data, // data to send
  2788. uint size, // size of 'data', If NULL && flush: flush only
  2789. uint *send_count // not NULL: add num of sent bytes
  2790. )
  2791. {
  2792. DASSERT(gb);
  2793. DASSERT(data||!size);
  2794. const u8 *d = data;
  2795. if ( fd != -1 )
  2796. {
  2797. int final_stat = 0;
  2798. if ( gb->disabled <= 0 )
  2799. {
  2800. if ( flush_output && gb->used )
  2801. {
  2802. ssize_t stat = write(fd,gb->ptr,gb->used);
  2803. if ( stat > 0 )
  2804. {
  2805. if (send_count)
  2806. *send_count += stat;
  2807. DropGrowBuffer(gb,stat);
  2808. }
  2809. }
  2810. if ( !gb->used && size )
  2811. {
  2812. ssize_t stat = write(fd,d,size);
  2813. if ( stat > 0 )
  2814. {
  2815. if (send_count)
  2816. *send_count += stat;
  2817. size -= stat;
  2818. if (!size) // likely
  2819. return stat;
  2820. d += stat;
  2821. final_stat = stat;
  2822. // for this case: force growing buffer (because of 'all or none')
  2823. PrepareGrowBuffer(gb,size,true);
  2824. }
  2825. }
  2826. }
  2827. if ( size && size <= GetSpaceGrowBuffer(gb) )
  2828. final_stat += InsertGrowBuffer(gb,d,size);
  2829. return final_stat;
  2830. }
  2831. return -1;
  2832. }
  2833. ///////////////////////////////////////////////////////////////////////////////
  2834. int SendDirectGrowBuffer
  2835. (
  2836. // send() data direct without blocking and without calling any notifier.
  2837. // If output buf is not empty or send failed, append the data to 'gb'.
  2838. // Returns the number of bytes added to the grow buffer or -1 on error.
  2839. // The data is send+stored completely (returns 'size') or not at all
  2840. // (returns '0'). -1 is returned if the socket is invalid.
  2841. GrowBuffer_t *gb, // grow buffer to cache data
  2842. int sock, // destination socket
  2843. bool flush_output, // true: try to flush 'gb' before
  2844. cvp data, // data to send
  2845. uint size, // size of 'data', If NULL && flush: flush only
  2846. uint *send_count // not NULL: add num of sent bytes
  2847. )
  2848. {
  2849. DASSERT(gb);
  2850. DASSERT(data||!size);
  2851. const u8 *d = data;
  2852. if ( sock != -1 )
  2853. {
  2854. int final_stat = 0;
  2855. if ( gb->disabled <= 0 )
  2856. {
  2857. if ( flush_output && gb->used )
  2858. {
  2859. ssize_t stat = send(sock,gb->ptr,gb->used,MSG_DONTWAIT);
  2860. if ( stat > 0 )
  2861. {
  2862. if (send_count)
  2863. *send_count += stat;
  2864. DropGrowBuffer(gb,stat);
  2865. }
  2866. }
  2867. if ( !gb->used && size )
  2868. {
  2869. ssize_t stat = send(sock,d,size,MSG_DONTWAIT);
  2870. if ( stat > 0 )
  2871. {
  2872. if (send_count)
  2873. *send_count += stat;
  2874. size -= stat;
  2875. if (!size) // likely
  2876. return stat;
  2877. d += stat;
  2878. final_stat = stat;
  2879. // for this case: force growing buffer (because of 'all or none')
  2880. PrepareGrowBuffer(gb,size,true);
  2881. }
  2882. }
  2883. }
  2884. if ( size && size <= GetSpaceGrowBuffer(gb) )
  2885. final_stat += InsertGrowBuffer(gb,d,size);
  2886. return final_stat;
  2887. }
  2888. return -1;
  2889. }
  2890. ///////////////////////////////////////////////////////////////////////////////
  2891. int SendDirectTCPStream
  2892. (
  2893. // Send data direct without blocking and without calling any notifier.
  2894. // If output buf is not empty or send failed, append the data to output buf.
  2895. // Returns the number of bytes added to the output buffer or -1 on error.
  2896. // The data is send+stored completely (returns 'size') or not at all
  2897. // (returns '0'). -1 is returned if the socket is invalid.
  2898. TCPStream_t *ts, // valid TCP handler
  2899. bool flush_output, // true: try to flush out-buf before
  2900. cvp data, // data to send
  2901. uint size // size of 'data', If NULL && flush: flush only
  2902. )
  2903. {
  2904. DASSERT(ts);
  2905. DASSERT(data||!size);
  2906. uint count = 0;
  2907. const int stat
  2908. = SendDirectGrowBuffer(&ts->obuf,ts->sock,flush_output,data,size,&count);
  2909. if ( count > 0 )
  2910. UpdateSendStatTCPStream(ts,count,0);
  2911. return stat;
  2912. }
  2913. ///////////////////////////////////////////////////////////////////////////////
  2914. int PrintArgDirectTCPStream
  2915. (
  2916. // Printing interface for SendDirectTCPStream()
  2917. TCPStream_t *ts, // valid TCP handler
  2918. bool flush_output, // true: try to flush out-buf before
  2919. ccp format, // format string for vsnprintf()
  2920. va_list arg // parameters for 'vfprintf(...,format,...)'
  2921. )
  2922. {
  2923. DASSERT(ts);
  2924. if (!format)
  2925. return SendDirectTCPStream(ts,flush_output,0,0);
  2926. char buf[10000];
  2927. va_list arg2;
  2928. va_copy(arg2,arg);
  2929. int stat = vsnprintf(buf,sizeof(buf),format,arg2);
  2930. va_end(arg2);
  2931. if ( stat < sizeof(buf) )
  2932. return SendDirectTCPStream(ts,flush_output,buf,stat);
  2933. //--- buffer too small, use dynamic memory
  2934. noPRINT("PrintArgGrowBuffer() -> MALLOC(%u)\n",stat+1);
  2935. char *temp = MALLOC(stat+1);
  2936. stat = vsnprintf(temp,stat+1,format,arg);
  2937. stat = SendDirectTCPStream(ts,flush_output,temp,stat);
  2938. FREE(temp);
  2939. return stat;
  2940. }
  2941. ///////////////////////////////////////////////////////////////////////////////
  2942. int PrintDirectTCPStream
  2943. (
  2944. // Printing interface for SendDirectTCPStream()
  2945. TCPStream_t *ts, // valid TCP handler
  2946. bool flush_output, // true: try to flush out-buf before
  2947. ccp format, // format string for vfprintf()
  2948. ... // arguments for 'vfprintf(...,format,...)'
  2949. )
  2950. {
  2951. DASSERT(ts);
  2952. if (format)
  2953. {
  2954. va_list arg;
  2955. va_start(arg,format);
  2956. const int stat = PrintArgDirectTCPStream(ts,flush_output,format,arg);
  2957. va_end(arg);
  2958. return stat;
  2959. }
  2960. return SendDirectTCPStream(ts,flush_output,0,0);
  2961. }
  2962. ///////////////////////////////////////////////////////////////////////////////
  2963. ///////////////////////////////////////////////////////////////////////////////
  2964. int PrintBinary1TCPStream
  2965. (
  2966. TCPStream_t *ts, // NULL or destination
  2967. ccp cmd, // command name
  2968. cvp bin_data, // pointer to binary data
  2969. uint bin_size, // size of binary data
  2970. ccp format, // NULL or format string with final ';'
  2971. ... // parameters for 'format'
  2972. )
  2973. {
  2974. DASSERT(cmd);
  2975. DASSERT(bin_data||!bin_size);
  2976. if (!ts)
  2977. return -1;
  2978. char buf[10000], *end_buf = buf + sizeof(buf) - 4;
  2979. #if 0 // gcc-12: throws error: 'buf' may be used uninitialized
  2980. char *dest = StringCopyE(buf,end_buf,cmd);
  2981. #else
  2982. char *dest = StringCopyS(buf,sizeof(buf)-4,cmd);
  2983. #endif
  2984. if ( dest + 6 + bin_size >= end_buf )
  2985. return -1;
  2986. *dest++ = ' ';
  2987. *dest++ = 1;
  2988. write_be16(dest,bin_size);
  2989. dest += 2;
  2990. memcpy(dest,bin_data,bin_size);
  2991. dest += bin_size;
  2992. *dest++ = ' ';
  2993. *dest++ = '=';
  2994. int len;
  2995. if (format)
  2996. {
  2997. va_list arg;
  2998. va_start(arg,format);
  2999. len = vsnprintf(dest,end_buf-dest,format,arg);
  3000. va_end(arg);
  3001. if ( len < 0 )
  3002. return -1;
  3003. len += dest - buf;
  3004. if ( len >= sizeof(buf) )
  3005. return -1;
  3006. }
  3007. else
  3008. {
  3009. *dest++ = ';';
  3010. len = dest - buf;
  3011. }
  3012. return SendDirectTCPStream(ts,false,buf,len);
  3013. }
  3014. ///////////////////////////////////////////////////////////////////////////////
  3015. int PrintBinary2TCPStream
  3016. (
  3017. TCPStream_t *ts, // NULL or destination
  3018. ccp cmd, // command name
  3019. cvp bin1_data, // pointer to binary data
  3020. uint bin1_size, // size of binary data
  3021. cvp bin2_data, // pointer to binary data
  3022. uint bin2_size, // size of binary data
  3023. ccp format, // NULL or format string with final ';'
  3024. ... // parameters for 'format'
  3025. )
  3026. {
  3027. DASSERT(cmd);
  3028. DASSERT(bin1_data||!bin1_size);
  3029. DASSERT(bin2_data||!bin2_size);
  3030. if (!ts)
  3031. return -1;
  3032. char buf[10000], *end_buf = buf + sizeof(buf) - 4;
  3033. #if 0 // gcc-12: throws error: 'buf' may be used uninitialized
  3034. char *dest = StringCopyE(buf,end_buf,cmd);
  3035. #else
  3036. char *dest = StringCopyS(buf,sizeof(buf)-4,cmd);
  3037. #endif
  3038. if ( dest + 9 + bin1_size + bin2_size >= end_buf )
  3039. return -1;
  3040. *dest++ = ' ';
  3041. *dest++ = 1;
  3042. write_be16(dest,bin1_size);
  3043. dest += 2;
  3044. memcpy(dest,bin1_data,bin1_size);
  3045. dest += bin1_size;
  3046. *dest++ = 1;
  3047. write_be16(dest,bin2_size);
  3048. dest += 2;
  3049. memcpy(dest,bin2_data,bin2_size);
  3050. dest += bin2_size;
  3051. *dest++ = ' ';
  3052. *dest++ = '=';
  3053. int len;
  3054. if (format)
  3055. {
  3056. va_list arg;
  3057. va_start(arg,format);
  3058. len = vsnprintf(dest,end_buf-dest,format,arg);
  3059. va_end(arg);
  3060. if ( len < 0 )
  3061. return -1;
  3062. len += dest - buf;
  3063. if ( len >= sizeof(buf) )
  3064. return -1;
  3065. }
  3066. else
  3067. {
  3068. *dest++ = ';';
  3069. len = dest - buf;
  3070. }
  3071. return SendDirectTCPStream(ts,false,buf,len);
  3072. }
  3073. ///////////////////////////////////////////////////////////////////////////////
  3074. ///////////////////////////////////////////////////////////////////////////////
  3075. void LogTCPStream
  3076. (
  3077. FILE *f, // output file
  3078. int indent, // indention
  3079. const TCPStream_t *ts, // valid TCP handler
  3080. int recurse, // >0: print stream list, >1: print buffer status
  3081. ccp format, // format string for vfprintf()
  3082. ... // arguments for 'vfprintf(format,...)'
  3083. )
  3084. {
  3085. DASSERT(f);
  3086. DASSERT(ts);
  3087. indent = NormalizeIndent(indent);
  3088. fprintf(f,"%*sTS: id:%x, sock=%d, %u packets received (%s), %u packets send (%s)",
  3089. indent,"",
  3090. ts->unique_id, ts->sock,
  3091. ts->stat.recv_count, PrintSize1024(0,0,ts->stat.recv_size,0),
  3092. ts->stat.send_count, PrintSize1024(0,0,ts->stat.send_size,0) );
  3093. if (format)
  3094. {
  3095. fputs(" : ",f);
  3096. va_list arg;
  3097. va_start(arg,format);
  3098. vfprintf(f,format,arg);
  3099. va_end(arg);
  3100. }
  3101. fputc('\n',f);
  3102. if (recurse>0)
  3103. {
  3104. LogGrowBuffer(f,indent+2,&ts->ibuf,"in buf");
  3105. LogGrowBuffer(f,indent+2,&ts->obuf,"out buf");
  3106. }
  3107. }
  3108. ///////////////////////////////////////////////////////////////////////////////
  3109. void LogTCPStreamActivity
  3110. (
  3111. const TCPStream_t *ts, // valid TCP handler
  3112. ccp activity
  3113. )
  3114. {
  3115. if (!ts->tracelog)
  3116. return;
  3117. char hbuf[200];
  3118. if (ts->handler)
  3119. {
  3120. const TCPHandler_t *th = ts->handler;
  3121. const Socket_t *so = th->listen;
  3122. DASSERT( TCP_HANDLER_MAX_LISTEN >= 3 );
  3123. snprintf(hbuf,sizeof(hbuf),
  3124. " | TH#%u: %u/%u/%u, sock=%d,%d,%d",
  3125. th->unique_id,
  3126. th->used_streams, th->max_used_streams, th->total_streams,
  3127. so[0].sock, so[1].sock, so[2].sock );
  3128. }
  3129. else
  3130. *hbuf = 0;
  3131. TraceLogPrint(ts->tracelog,
  3132. "%p %-20s sock=%d%s\n", ts, activity, ts->sock, hbuf );
  3133. }
  3134. ///////////////////////////////////////////////////////////////////////////////
  3135. char * BufInfoHeadTCPStream
  3136. (
  3137. // returns a pointer to the head line
  3138. uint line // 0|1
  3139. )
  3140. {
  3141. switch (line)
  3142. {
  3143. case 0:
  3144. return "connect in buf out buf"
  3145. " received data send data";
  3146. case 1:
  3147. return " time sock status use/ max use/ max"
  3148. " time pkt size time pkt size stream info";
  3149. }
  3150. return 0;
  3151. }
  3152. ///////////////////////////////////////////////////////////////////////////////
  3153. char * BufInfoTCPStream
  3154. (
  3155. // returns a pointer to the buffer
  3156. char * buf, // result (BUF_INFO_TCP_STREAM_SIZE bytes are good)
  3157. // If NULL, a local circulary static buffer is used
  3158. size_t buf_size, // size of 'buf', ignored if buf==NULL
  3159. const TCPStream_t *ts, // valid TCP handler
  3160. u64 now_usec // NULL or current time, GetTimeUSec(false)
  3161. )
  3162. {
  3163. DASSERT(ts);
  3164. if (!now_usec)
  3165. now_usec = GetTimeUSec(false);
  3166. char connect_usec[7];
  3167. if ( ts->connect_usec )
  3168. PrintTimerUSec6(connect_usec,sizeof(connect_usec),
  3169. now_usec - ts->connect_usec, true );
  3170. else
  3171. connect_usec[0] = '-', connect_usec[1] = 0;
  3172. char receive_usec[7];
  3173. if ( ts->receive_usec )
  3174. PrintTimerUSec6(receive_usec,sizeof(receive_usec),
  3175. now_usec - ts->receive_usec, true );
  3176. else
  3177. receive_usec[0] = '-', receive_usec[1] = 0;
  3178. char send_usec[7];
  3179. if ( ts->send_usec )
  3180. PrintTimerUSec6(send_usec,sizeof(send_usec),
  3181. now_usec - ts->send_usec, true );
  3182. else
  3183. send_usec[0] = '-', send_usec[1] = 0;
  3184. if (!buf)
  3185. buf = GetCircBuf( buf_size = BUF_INFO_TCP_STREAM_SIZE );
  3186. snprintf(buf,buf_size,
  3187. "%6.6s%5d %c%c%c%c%c%c%c %s/%s %s/%s %6s %s %s %6s %s %s %s"
  3188. ,connect_usec
  3189. ,ts->sock
  3190. ,ts->protect > 0 ? 'P' : '-'
  3191. ,ts->auto_close > 0 ? 'A' : '-'
  3192. ,ts->rescan > 0 ? 'S' : '-'
  3193. ,ts->eof > 0 ? 'X' : '-'
  3194. ,ts->error > 0 ? 'E' : '-'
  3195. ,ts->ibuf.disabled ? 'D' : 'i'
  3196. ,ts->obuf.disabled ? 'D' : 'o'
  3197. ,PrintNumberU4(0,0,ts->ibuf.used,true)
  3198. ,PrintNumberU4(0,0,ts->ibuf.max_used,true)
  3199. ,PrintNumberU4(0,0,ts->obuf.used,true)
  3200. ,PrintNumberU4(0,0,ts->obuf.max_used,true)
  3201. ,receive_usec
  3202. ,PrintNumberU5(0,0,ts->stat.recv_count,true)
  3203. ,PrintSize1024(0,0,ts->stat.recv_size,DC_SFORM_TINY|DC_SFORM_ALIGN)
  3204. ,send_usec
  3205. ,PrintNumberU5(0,0,ts->stat.send_count,true)
  3206. ,PrintSize1024(0,0,ts->stat.send_size,DC_SFORM_TINY|DC_SFORM_ALIGN)
  3207. ,ts->info
  3208. );
  3209. return buf;
  3210. }
  3211. //
  3212. ///////////////////////////////////////////////////////////////////////////////
  3213. /////////////// TCPHandler_t ///////////////
  3214. ///////////////////////////////////////////////////////////////////////////////
  3215. void AddSocketTCPStream
  3216. (
  3217. TCPStream_t *ts, // valid TCP handler
  3218. FDList_t *fdl // valid file descriptor list
  3219. )
  3220. {
  3221. DASSERT(ts);
  3222. DASSERT(fdl);
  3223. if ( ts->OnFDList && ts->OnFDList(ts,fdl,TCP_FM_ADD_SOCK,false) < 0 || ts->sock == -1 )
  3224. return;
  3225. uint events = POLLERR|POLLRDHUP;
  3226. if ( !ts->eof && !ts->ibuf.disabled && GetSpaceGrowBuffer(&ts->ibuf) )
  3227. events |= POLLIN;
  3228. if ( !ts->obuf.disabled && ts->obuf.used )
  3229. events |= POLLOUT;
  3230. ts->poll_index = AddFDList(fdl,ts->sock,events);
  3231. if ( ts->OnTimeout && ts->trigger_usec && fdl->timeout_usec > ts->trigger_usec )
  3232. fdl->timeout_usec = ts->trigger_usec;
  3233. }
  3234. ///////////////////////////////////////////////////////////////////////////////
  3235. void CheckSocketTCPStream
  3236. (
  3237. TCPStream_t *ts, // valid TCP handler
  3238. FDList_t *fdl, // valid socket list
  3239. bool check_timeout // true: enable timeout checks
  3240. )
  3241. {
  3242. DASSERT(ts);
  3243. DASSERT(fdl);
  3244. if ( ts->OnFDList && ts->OnFDList(ts,fdl,TCP_FM_CHECK_SOCK,check_timeout) < 0
  3245. || ts->sock == -1 )
  3246. {
  3247. return;
  3248. }
  3249. const u64 now_usec = GetTimeUSec(false);
  3250. typeof(ts->rescan) rescan = ts->rescan;
  3251. ts->rescan = 0;
  3252. const uint revents = GetEventFDList(fdl,ts->sock,ts->poll_index);
  3253. if ( !ts->ibuf.disabled && revents & POLLIN )
  3254. {
  3255. noPRINT("RECV: %d\n",ts->sock);
  3256. OnReceivedStream(ts,now_usec);
  3257. rescan = 0;
  3258. }
  3259. if ( !ts->obuf.disabled && ts->obuf.used && revents & POLLOUT )
  3260. OnWriteStream(ts,now_usec);
  3261. if ( revents & (POLLERR|POLLHUP|POLLRDHUP|POLLNVAL) )
  3262. {
  3263. ts->error |= 1;
  3264. OnCloseStream(ts,now_usec);
  3265. }
  3266. if ( rescan && ts->OnReceived )
  3267. {
  3268. uchar ch = 0;
  3269. ts->OnReceived(ts,&ch,0);
  3270. }
  3271. if (check_timeout)
  3272. CheckTimeoutTCPStream(ts);
  3273. if (ts->rescan)
  3274. ts->trigger_usec = ts->accept_usec = now_usec;
  3275. }
  3276. ///////////////////////////////////////////////////////////////////////////////
  3277. #undef PRINT_TIMEOUT
  3278. #define PRINT_TIMEOUT(ts,now,info) \
  3279. noPRINT("%s[%d]: now=%lld, trig=%lld, accept=%lld, OnTimeout=%d\n", \
  3280. info, ts->sock, now, ts->trigger_usec ? ts->trigger_usec - now : 0, \
  3281. ts->accept_usec ? ts->accept_usec - now : 0, ts->OnTimeout != 0 )
  3282. ///////////////////////////////////////////////////////////////////////////////
  3283. ///////////////////////////////////////////////////////////////////////////////
  3284. void CheckTimeoutTCPStream ( TCPStream_t *ts )
  3285. {
  3286. DASSERT(ts);
  3287. if ( ts->OnFDList && ts->OnFDList(ts,0,TCP_FM_TIMEOUT,true) < 0 || ts->sock == -1 )
  3288. return;
  3289. const u64 now_usec = GetTimeUSec(false);
  3290. PRINT_TIMEOUT(ts,now_usec,"TIMEOUT");
  3291. if ( ts->trigger_usec && ts->trigger_usec <= now_usec
  3292. || ts->accept_usec && ts->accept_usec <= now_usec
  3293. )
  3294. {
  3295. ts->trigger_usec = ts->accept_usec = 0;
  3296. if (ts->OnTimeout)
  3297. ts->OnTimeout(ts,now_usec);
  3298. }
  3299. }
  3300. ///////////////////////////////////////////////////////////////////////////////
  3301. u64 GetLastActivityTCPStream ( TCPStream_t *ts )
  3302. {
  3303. DASSERT(ts);
  3304. const u64 ref = ts->connect_usec > ts->receive_usec
  3305. ? ts->connect_usec : ts->receive_usec;
  3306. return ref > ts->send_usec ? ref : ts->send_usec;
  3307. }
  3308. ///////////////////////////////////////////////////////////////////////////////
  3309. u64 GetTimeoutTCPStream ( TCPStream_t *ts )
  3310. {
  3311. DASSERT(ts);
  3312. return ts->timeout_usec
  3313. ? GetLastActivityTCPStream(ts) + ts->timeout_usec
  3314. : 0;
  3315. }
  3316. ///////////////////////////////////////////////////////////////////////////////
  3317. int OnTimeoutTCPStream ( TCPStream_t *ts, u64 now_usec )
  3318. {
  3319. DASSERT(ts);
  3320. if ( ts->sock != -1 && ts->timeout_usec )
  3321. {
  3322. if (!now_usec)
  3323. now_usec = GetTimeUSec(false);
  3324. if ( now_usec >= GetLastActivityTCPStream(ts) + ts->timeout_usec )
  3325. OnCloseStream(ts,now_usec);
  3326. else
  3327. SetupTriggerTCPStream(ts,now_usec);
  3328. }
  3329. return 0;
  3330. }
  3331. ///////////////////////////////////////////////////////////////////////////////
  3332. void SetupTriggerTCPStream ( TCPStream_t *ts, u64 now_usec )
  3333. {
  3334. DASSERT(ts);
  3335. const u64 next = GetTimeoutTCPStream(ts);
  3336. if (next)
  3337. {
  3338. if (!now_usec)
  3339. now_usec = GetTimeUSec(false);
  3340. if ( ts->accept_usec <= now_usec || ts->accept_usec > next )
  3341. ts->accept_usec = next;
  3342. ts->trigger_usec = ts->accept_usec + ts->delay_usec;
  3343. noPRINT("next=%lld [%lld], accept=%lld [%lld]\n",
  3344. next, next-now_usec, ts->accept_usec, ts->accept_usec-now_usec );
  3345. }
  3346. }
  3347. //
  3348. ///////////////////////////////////////////////////////////////////////////////
  3349. /////////////// TCPHandler_t ///////////////
  3350. ///////////////////////////////////////////////////////////////////////////////
  3351. void InitializeTCPHandler
  3352. (
  3353. TCPHandler_t *th, // not NULL
  3354. uint data_size // size of 'TCPStream_t::data'
  3355. )
  3356. {
  3357. DASSERT(th);
  3358. memset(th,0,sizeof(*th));
  3359. th->unique_id = CreateUniqueId();
  3360. th->data_size = data_size;
  3361. th->OnAllowStream = IsStreamAllowed;
  3362. uint i;
  3363. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3364. th->listen[i].sock = -1;
  3365. LOG_TCP_HANDLER(th,0,"INIT(%u)",data_size);
  3366. }
  3367. ///////////////////////////////////////////////////////////////////////////////
  3368. void ResetTCPHandler
  3369. (
  3370. TCPHandler_t *th // valid TCP handler
  3371. )
  3372. {
  3373. DASSERT(th);
  3374. th->allow_ip4 = DeleteReferenceAllowIP4(th->allow_ip4);
  3375. UnlistenAllTCP(th);
  3376. while (th->first)
  3377. DestroyTCPStream(th->first);
  3378. usleep(1);
  3379. InitializeTCPHandler(th,th->data_size);
  3380. }
  3381. ///////////////////////////////////////////////////////////////////////////////
  3382. uint CloseTCPHandler
  3383. (
  3384. // returns the number of waiting clients (obuf not empty and !disabled)
  3385. TCPHandler_t *th // valid TCP handler
  3386. )
  3387. {
  3388. DASSERT(th);
  3389. UnlistenAllTCP(th);
  3390. uint count = 0;
  3391. u64 now = GetTimeUSec(false);
  3392. TCPStream_t *ts;
  3393. for ( ts = th->first; ts; ts = ts->next )
  3394. {
  3395. OnCloseStream(ts,now);
  3396. if ( ts->obuf.used && !ts->obuf.disabled )
  3397. count++;
  3398. }
  3399. return count;
  3400. }
  3401. ///////////////////////////////////////////////////////////////////////////////
  3402. TCPStream_t * AddTCPStream
  3403. (
  3404. TCPHandler_t *th, // valid TCP handler
  3405. TCPStream_t *ts // the new stream
  3406. )
  3407. {
  3408. DASSERT(th);
  3409. DASSERT(ts);
  3410. ts->handler = th;
  3411. ts->prev = 0;
  3412. ts->next = th->first;
  3413. if (th->first)
  3414. th->first->prev = ts;
  3415. th->first = ts;
  3416. if ( th->max_used_streams < ++th->used_streams )
  3417. th->max_used_streams = th->used_streams;
  3418. th->total_streams++;
  3419. th->stat.conn_count++;
  3420. ts->connect_usec = GetTimeUSec(false);
  3421. LogTCPStreamActivity(ts,"AddTCPStream");
  3422. return ts;
  3423. }
  3424. ///////////////////////////////////////////////////////////////////////////////
  3425. TCPStream_t * CreateTCPStream
  3426. (
  3427. TCPHandler_t *th, // valid TCP handler
  3428. int sock, // -1 or valid socket
  3429. u64 allow_mode, // stored in 'allow_mode'
  3430. const Socket_t *listen // NULL or related listen object
  3431. )
  3432. {
  3433. DASSERT(th);
  3434. TCPStream_t *ts = listen && listen->OnCreateStream
  3435. ? listen->OnCreateStream(th,sock) : 0;
  3436. if (!ts)
  3437. {
  3438. if (th->OnCreateStream)
  3439. ts = th->OnCreateStream(th,sock);
  3440. if (!ts)
  3441. {
  3442. ts = CALLOC(sizeof(*ts)+th->data_size,1);
  3443. InitializeTCPStream(ts,sock);
  3444. }
  3445. }
  3446. if ( th->tracelog.level >= 0 )
  3447. {
  3448. ts->tracelog = &th->tracelog;
  3449. LogTCPStreamActivity(ts,"CreateTCPStream");
  3450. }
  3451. ts->allow_mode = allow_mode;
  3452. AddTCPStream(th,ts);
  3453. if ( listen && listen->OnAddedStream )
  3454. listen->OnAddedStream(ts);
  3455. else if (th->OnAddedStream)
  3456. th->OnAddedStream(ts);
  3457. return ts;
  3458. }
  3459. ///////////////////////////////////////////////////////////////////////////////
  3460. TCPStream_t * ConnectUnixTCPStream
  3461. (
  3462. TCPHandler_t *th, // valid TCP handler
  3463. ccp path, // NULL or path part 1 to socket file
  3464. bool silent // suppress error messages
  3465. )
  3466. {
  3467. DASSERT(th);
  3468. DASSERT(path);
  3469. int sock = socket(AF_UNIX,SOCK_STREAM,0);
  3470. if ( sock == -1 )
  3471. {
  3472. if (!silent)
  3473. ERROR1(ERR_CANT_CREATE,"Can't create UNIX stream socket: %s\n",path);
  3474. return 0;
  3475. }
  3476. struct sockaddr_un sa;
  3477. memset(&sa,0,sizeof(sa));
  3478. sa.sun_family = AF_UNIX;
  3479. StringCopyS(sa.sun_path,sizeof(sa.sun_path),path);
  3480. int stat = connect(sock,(struct sockaddr*)&sa,sizeof(sa));
  3481. if (stat)
  3482. {
  3483. if (!silent)
  3484. ERROR1(ERR_CANT_OPEN,"Can't connect UNIX stream socket: %s\n",path);
  3485. shutdown(sock,SHUT_RDWR);
  3486. close(sock);
  3487. return 0;
  3488. }
  3489. return CreateTCPStream(th,sock,ALLOW_MODE_ALLOW,0);
  3490. }
  3491. ///////////////////////////////////////////////////////////////////////////////
  3492. TCPStream_t * ConnectTCPStream
  3493. (
  3494. TCPHandler_t *th, // valid TCP handler
  3495. ccp addr, // address -> NetworkHost_t
  3496. u16 default_port, // default port
  3497. bool silent // suppress error messages
  3498. )
  3499. {
  3500. DASSERT(th);
  3501. DASSERT(addr);
  3502. ccp unix_path = CheckUnixSocketPath(addr,0);
  3503. if (unix_path)
  3504. return ConnectUnixTCPStream(th,unix_path,silent);
  3505. if (!strncasecmp(addr,"tcp:",4))
  3506. addr += 4;
  3507. NetworkHost_t nh;
  3508. ResolveHost(&nh,true,addr,default_port,false,false);
  3509. PRINT("SINGLE/CONNECT/TCP: %s -> %s\n",
  3510. addr, PrintIP4(0,0,nh.ip4,nh.port) );
  3511. int sock = socket(AF_INET,SOCK_STREAM|SOCK_NONBLOCK,0);
  3512. if ( sock == -1 )
  3513. {
  3514. if (!silent)
  3515. ERROR1(ERR_CANT_CREATE,"Can't create TCP socket: %s\n",
  3516. PrintIP4(0,0,nh.ip4,nh.port));
  3517. return 0;
  3518. }
  3519. struct sockaddr_in sa;
  3520. memset(&sa,0,sizeof(sa));
  3521. sa.sin_family = AF_INET;
  3522. sa.sin_addr.s_addr = htonl(nh.ip4);
  3523. sa.sin_port = htons(nh.port);
  3524. int stat = connect(sock,(struct sockaddr*)&sa,sizeof(sa));
  3525. if ( stat && errno != EINPROGRESS )
  3526. {
  3527. if (!silent)
  3528. ERROR1(ERR_CANT_OPEN,"Can't connect TCP socket: %s\n",
  3529. PrintIP4(0,0,nh.ip4,nh.port));
  3530. shutdown(sock,SHUT_RDWR);
  3531. close(sock);
  3532. ResetHost(&nh);
  3533. return 0;
  3534. }
  3535. return CreateTCPStream(th,sock,ALLOW_MODE_ALLOW,0);
  3536. }
  3537. ///////////////////////////////////////////////////////////////////////////////
  3538. TCPStream_t * FindTCPStreamByUniqueID
  3539. (
  3540. TCPHandler_t *th, // valid TCP handler
  3541. uint unique_id // id to search
  3542. )
  3543. {
  3544. TCPStream_t *ts;
  3545. for ( ts = th->first; ts; ts = ts->next )
  3546. if ( ts->unique_id == unique_id )
  3547. return ts;
  3548. return 0;
  3549. }
  3550. ///////////////////////////////////////////////////////////////////////////////
  3551. uint NumOfSocketsTCP ( const TCPHandler_t *th )
  3552. {
  3553. uint i, count = 0;
  3554. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3555. if ( th->listen[i].sock != -1 )
  3556. count++;
  3557. const TCPStream_t *ts;
  3558. for ( ts = th->first; ts; ts = ts->next )
  3559. if ( ts->sock != -1
  3560. && ( !ts->eof && !ts->ibuf.disabled
  3561. || !ts->obuf.disabled && ts->obuf.used ))
  3562. {
  3563. count++;
  3564. }
  3565. return count;
  3566. }
  3567. ///////////////////////////////////////////////////////////////////////////////
  3568. ///////////////////////////////////////////////////////////////////////////////
  3569. Socket_t * GetUnusedListenSocketTCP ( TCPHandler_t *th, bool silent )
  3570. {
  3571. DASSERT(th);
  3572. uint i;
  3573. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3574. if ( th->listen[i].sock == -1 )
  3575. return th->listen+i;
  3576. if (!silent)
  3577. ERROR0(ERR_CANT_CREATE,"No socket available.\n");
  3578. return 0;
  3579. }
  3580. ///////////////////////////////////////////////////////////////////////////////
  3581. enumError ListenUnixTCP
  3582. (
  3583. TCPHandler_t *th, // valid TCP handler
  3584. ccp path // path to unix file
  3585. )
  3586. {
  3587. DASSERT(th);
  3588. DASSERT(path);
  3589. PRINT("LISTEN/UNIX: %s\n",path);
  3590. Socket_t *lsock = GetUnusedListenSocketTCP(th,false);
  3591. if (!lsock)
  3592. return ERR_CANT_CREATE;
  3593. unlink(path);
  3594. int sock = socket(AF_UNIX,SOCK_STREAM,0);
  3595. if ( sock == -1 )
  3596. return ERROR1(ERR_CANT_CREATE,"Can't create UNIX socket: %s\n",path);
  3597. struct sockaddr_un sa;
  3598. memset(&sa,0,sizeof(sa));
  3599. sa.sun_family = AF_UNIX;
  3600. StringCopyS(sa.sun_path,sizeof(sa.sun_path),path);
  3601. int stat = bind(sock,(struct sockaddr*)&sa,sizeof(sa));
  3602. if ( stat == -1 )
  3603. {
  3604. close(sock);
  3605. return ERROR1(ERR_CANT_CREATE,"Can't bind UNIX socket: %s\n",path);
  3606. }
  3607. stat = listen(sock,50);
  3608. if ( stat == -1 )
  3609. {
  3610. close(sock);
  3611. return ERROR1(ERR_CANT_CREATE,"Can't listen UNIX socket: %s\n",path);
  3612. }
  3613. //SetSocketBlocking(cmdi_sock,false);
  3614. DASSERT(lsock);
  3615. lsock->sock = sock;
  3616. lsock->is_unix = true;
  3617. snprintf(lsock->info,sizeof(lsock->info),"UNIX socket %d",sock);
  3618. PRINT("LISTEN: %s [idx=%zu]\n",lsock->info,lsock-th->listen);
  3619. LOG_TCP_HANDLER(th,0,"LISTEN/UNIX[%u] %s",listen_idx,path);
  3620. return ERR_OK;
  3621. }
  3622. ///////////////////////////////////////////////////////////////////////////////
  3623. enumError ListenTCP
  3624. (
  3625. TCPHandler_t *th, // valid TCP handler
  3626. ccp addr, // IPv4 address with optional port -> NetworkHost_t
  3627. // fall back to ListenUnixTCP() if addr begins with
  3628. // 'unix:' or '/' or './ or '../'
  3629. u16 default_port // default port
  3630. )
  3631. {
  3632. DASSERT(th);
  3633. DASSERT(addr);
  3634. Socket_t *lsock = GetUnusedListenSocketTCP(th,false);
  3635. if (!lsock)
  3636. return ERR_CANT_CREATE;
  3637. const bool allow_unix = memcmp(addr,"tcp:",4) != 0;
  3638. if (!allow_unix)
  3639. {
  3640. addr += 4;
  3641. while ( *addr == '/' )
  3642. addr++;
  3643. }
  3644. NetworkHost_t nh;
  3645. if ( !ResolveHost(&nh,true,addr,default_port,allow_unix,true) && nh.filename )
  3646. {
  3647. ccp unix_path = nh.filename;
  3648. ResetHost(&nh);
  3649. return ListenUnixTCP(th,unix_path);
  3650. }
  3651. ccp path = GetHostName(&nh);
  3652. PRINT("LISTEN/TCP: %s:%u -> %s\n",nh.name,default_port,PrintIP4(0,0,nh.ip4,nh.port));
  3653. int sock = socket(AF_INET,SOCK_STREAM|SOCK_NONBLOCK,0);
  3654. if ( sock == -1 )
  3655. {
  3656. ERROR1(ERR_CANT_CREATE,"Can't create TCP socket: %s\n",path);
  3657. ResetHost(&nh);
  3658. return ERR_CANT_CREATE;
  3659. }
  3660. int on = 1;
  3661. setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (ccp)&on, sizeof(on) );
  3662. struct sockaddr_in sa;
  3663. memset(&sa,0,sizeof(sa));
  3664. sa.sin_family = AF_INET;
  3665. sa.sin_addr.s_addr = htonl(nh.ip4);
  3666. sa.sin_port = htons(nh.port);
  3667. int stat = bind(sock,(struct sockaddr*)&sa,sizeof(sa));
  3668. if ( stat == -1 )
  3669. {
  3670. ERROR1(ERR_CANT_CREATE,"Can't bind TCP socket: %s\n",
  3671. PrintIP4(0,0,nh.ip4,nh.port));
  3672. close(sock);
  3673. ResetHost(&nh);
  3674. return ERR_CANT_CREATE;
  3675. }
  3676. stat = listen(sock,50);
  3677. if ( stat == -1 )
  3678. {
  3679. ERROR1(ERR_CANT_CREATE,"Can't listen TCP socket: %s\n",
  3680. PrintIP4(0,0,nh.ip4,nh.port));
  3681. close(sock);
  3682. ResetHost(&nh);
  3683. return ERR_CANT_CREATE;
  3684. }
  3685. //SetSocketBlocking(cmdi_sock,false);
  3686. DASSERT(lsock);
  3687. lsock->sock = sock;
  3688. lsock->is_unix = false;
  3689. snprintf(lsock->info,sizeof(lsock->info),"TCP socket %d",sock);
  3690. PRINT("LISTEN: %s [idx=%zu]\n",lsock->info,lsock-th->listen);
  3691. ResetHost(&nh);
  3692. return ERR_OK;
  3693. }
  3694. ///////////////////////////////////////////////////////////////////////////////
  3695. ///////////////////////////////////////////////////////////////////////////////
  3696. int UnlistenTCP
  3697. (
  3698. // returns the index of the closed socket, or if not found
  3699. TCPHandler_t *th, // valid TCP handler
  3700. int sock // socket to close
  3701. )
  3702. {
  3703. uint i;
  3704. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3705. if ( th->listen[i].sock == sock )
  3706. {
  3707. close(sock);
  3708. th->listen[i].sock = -1;
  3709. return i;
  3710. }
  3711. return -1;
  3712. }
  3713. ///////////////////////////////////////////////////////////////////////////////
  3714. uint UnlistenAllTCP
  3715. (
  3716. // returns the number of closed sockets
  3717. TCPHandler_t *th // valid TCP handler
  3718. )
  3719. {
  3720. uint i, count = 0;
  3721. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3722. if ( th->listen[i].sock != -1 )
  3723. {
  3724. socket_info_t si;
  3725. GetSocketInfoBySocket(&si,th->listen[i].sock,true);
  3726. if ( si.is_valid && si.protocol == AF_UNIX
  3727. && si.address && *si.address )
  3728. {
  3729. PRINT("unlink(%s)\n",si.address);
  3730. unlink(si.address);
  3731. }
  3732. ResetSocketInfo(&si);
  3733. close(th->listen[i].sock);
  3734. th->listen[i].sock = -1;
  3735. count++;
  3736. }
  3737. return count;
  3738. }
  3739. ///////////////////////////////////////////////////////////////////////////////
  3740. ///////////////////////////////////////////////////////////////////////////////
  3741. void AddSocketsTCP
  3742. (
  3743. TCPHandler_t *th, // valid TCP handler
  3744. FDList_t *fdl // valid file descriptor list
  3745. )
  3746. {
  3747. DASSERT(th);
  3748. DASSERT(fdl);
  3749. AnnounceFDList(fdl,TCP_HANDLER_MAX_LISTEN+th->used_streams+1);
  3750. if ( !th->max_conn || th->used_streams < th->max_conn )
  3751. {
  3752. uint i;
  3753. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3754. {
  3755. Socket_t *lsock = th->listen + i;
  3756. lsock->poll_index = AddFDList(fdl,lsock->sock,POLLIN);
  3757. }
  3758. }
  3759. TCPStream_t *ts;
  3760. for ( ts = th->first; ts; ts = ts->next )
  3761. AddSocketTCPStream(ts,fdl);
  3762. }
  3763. ///////////////////////////////////////////////////////////////////////////////
  3764. ///////////////////////////////////////////////////////////////////////////////
  3765. bool IsStreamAllowed
  3766. (
  3767. // returns true if access is allowed
  3768. struct TCPHandler_t *th, // valid TCP handler
  3769. const Socket_t *lsock, // valid listen-socket
  3770. int sock, // valid socket to verify
  3771. u64 *allow // not NULL: store allow code here
  3772. )
  3773. {
  3774. DASSERT(th);
  3775. if ( !th->allow_ip4 || lsock && lsock->is_unix )
  3776. {
  3777. // no checks for unix sockets
  3778. if (allow)
  3779. *allow = ALLOW_MODE_ALLOW;
  3780. return true;
  3781. }
  3782. const u64 res = GetAutoAllowIP4BySock(th->allow_ip4,sock);
  3783. if (allow)
  3784. *allow = res;
  3785. return ( res & th->allow_ip4->allow_mode ) != 0;
  3786. }
  3787. ///////////////////////////////////////////////////////////////////////////////
  3788. ///////////////////////////////////////////////////////////////////////////////
  3789. TCPStream_t * OnAcceptStream
  3790. (
  3791. TCPHandler_t *th, // valid TCP handler
  3792. const Socket_t *lsock, // listen-socket
  3793. u64 now_usec // time for timestamps, GetTimeUSec(false)
  3794. )
  3795. {
  3796. DASSERT(th);
  3797. DASSERT(lsock);
  3798. DASSERT( lsock >= th->listen );
  3799. DASSERT( lsock < th->listen + TCP_HANDLER_MAX_LISTEN );
  3800. DASSERT( lsock->sock != -1 );
  3801. PRINT("OnAcceptStream() lsock=%d,%s\n",lsock->sock,lsock->info);
  3802. TCPStream_t *ts = NULL;
  3803. int new_sock = accept(lsock->sock,0,0);
  3804. if ( new_sock != -1 )
  3805. {
  3806. RegisterFileId(new_sock);
  3807. u64 allow_code = 0;
  3808. const u64 is_allowed = th->OnAllowStream
  3809. ? th->OnAllowStream(th,lsock,new_sock,&allow_code)
  3810. : ALLOW_MODE_ALLOW;
  3811. if ( !is_allowed || th->OnAcceptStream && th->OnAcceptStream(th,lsock,new_sock) )
  3812. {
  3813. PRINT("NOT ACCEPTED: %d -> %d\n",lsock->sock,new_sock);
  3814. shutdown(new_sock,SHUT_RDWR);
  3815. close(new_sock);
  3816. }
  3817. else
  3818. {
  3819. PRINT("ACCEPTED: %d -> %d [alloe=%llx]\n",lsock->sock,new_sock,allow_code);
  3820. ts = CreateTCPStream(th,new_sock,allow_code,lsock);
  3821. if (ts)
  3822. {
  3823. if (!ts->info[0])
  3824. {
  3825. if (lsock->info[0])
  3826. snprintf(ts->info,sizeof(ts->info),
  3827. "by %s [%x]",
  3828. lsock->info, ts->unique_id );
  3829. else
  3830. snprintf(ts->info,sizeof(ts->info),
  3831. "by socket %d [%x]",
  3832. lsock->sock, ts->unique_id );
  3833. }
  3834. }
  3835. else
  3836. {
  3837. shutdown(new_sock,SHUT_RDWR);
  3838. close(new_sock);
  3839. }
  3840. }
  3841. }
  3842. return ts;
  3843. }
  3844. ///////////////////////////////////////////////////////////////////////////////
  3845. void OnCloseStream
  3846. (
  3847. TCPStream_t *ts, // valid TCP stream
  3848. u64 now_usec // time for timestamps, GetTimeUSec(false)
  3849. )
  3850. {
  3851. DASSERT(ts);
  3852. if ( ts->sock != -1 )
  3853. {
  3854. PRINT("CLOSE: %d\n",ts->sock);
  3855. if (ts->OnClose)
  3856. ts->OnClose(ts,now_usec);
  3857. if ( ts->sock != -1 )
  3858. {
  3859. // if not closed by OnClose()
  3860. shutdown(ts->sock,SHUT_RDWR);
  3861. close(ts->sock);
  3862. ts->sock = -1;
  3863. }
  3864. if ( !ts->protect && ts->handler )
  3865. ts->handler->need_maintenance |= 1;
  3866. ts->OnReceived = 0;
  3867. ts->OnSend = 0;
  3868. ts->OnTimeout = 0;
  3869. ts->OnClose = 0;
  3870. ts->OnFDList = 0;
  3871. }
  3872. }
  3873. ///////////////////////////////////////////////////////////////////////////////
  3874. void SetNotSocketStream
  3875. (
  3876. TCPStream_t *ts // valid TCP stream
  3877. )
  3878. {
  3879. DASSERT(ts);
  3880. if ( ts->sock != -1 )
  3881. {
  3882. ts->not_socket = true;
  3883. int flags = fcntl(ts->sock,F_GETFL,0);
  3884. if ( flags != -1 )
  3885. {
  3886. flags |= O_NONBLOCK;
  3887. fcntl(ts->sock,F_SETFL,flags);
  3888. }
  3889. }
  3890. }
  3891. ///////////////////////////////////////////////////////////////////////////////
  3892. void OnReceivedStream
  3893. (
  3894. TCPStream_t *ts, // valid TCP stream
  3895. u64 now_usec // time for timestamps, GetTimeUSec(false)
  3896. )
  3897. {
  3898. DASSERT(ts);
  3899. uint max_read = GetSpaceGrowBuffer(&ts->ibuf);
  3900. if (max_read)
  3901. {
  3902. u8 buf[0x4000];
  3903. if ( max_read > sizeof(buf) )
  3904. max_read = sizeof(buf);
  3905. ssize_t stat;
  3906. retry:
  3907. if (ts->not_socket)
  3908. stat = read(ts->sock,buf,max_read);
  3909. else
  3910. stat = recv(ts->sock,buf,max_read,MSG_DONTWAIT);
  3911. if ( stat < 0 && !ts->not_socket && errno == ENOTSOCK )
  3912. {
  3913. SetNotSocketStream(ts);
  3914. goto retry;
  3915. }
  3916. #if HAVE_PRINT
  3917. noPRINT("RECV[%d] %lld/%u, err=%d\n",ts->sock,(s64)stat,max_read,errno);
  3918. if ( stat < 0 )
  3919. PRINT("!! %s(), ERRNO=%d: %s\n",__FUNCTION__,errno,strerror(errno));
  3920. #endif
  3921. if ( stat >= 0 )
  3922. {
  3923. if ( stat > 0 )
  3924. UpdateRecvStatTCPStream(ts,stat,now_usec);
  3925. else
  3926. ts->eof |= 1;
  3927. if (ts->OnReceived)
  3928. stat = ts->OnReceived(ts,buf,stat);
  3929. if ( stat > 0 )
  3930. InsertGrowBuffer(&ts->ibuf,buf,stat);
  3931. //X if ( ts->eof && !ts->ibuf.used && !ts->obuf.used )
  3932. //X OnCloseStream(ts,now_usec);
  3933. }
  3934. else if ( errno != EWOULDBLOCK )
  3935. OnCloseStream(ts,now_usec);
  3936. }
  3937. }
  3938. ///////////////////////////////////////////////////////////////////////////////
  3939. void OnWriteStream
  3940. (
  3941. TCPStream_t *ts, // valid TCP stream
  3942. u64 now_usec // time for timestamps, GetTimeUSec(false)
  3943. )
  3944. {
  3945. DASSERT(ts);
  3946. restart:;
  3947. ssize_t stat;
  3948. if (ts->not_socket)
  3949. stat = write(ts->sock,ts->obuf.ptr,ts->obuf.used);
  3950. else
  3951. stat = send(ts->sock,ts->obuf.ptr,ts->obuf.used,MSG_DONTWAIT);
  3952. noPRINT("SEND[%d] %lld/%u, err=%d\n",ts->sock,(s64)stat,ts->obuf.used,errno);
  3953. if ( stat < 0 )
  3954. {
  3955. if ( !ts->not_socket && errno == ENOTSOCK )
  3956. {
  3957. SetNotSocketStream(ts);
  3958. goto restart;
  3959. }
  3960. PRINT("!! %s(), ERRNO=%d: %s\n",__FUNCTION__,errno,strerror(errno));
  3961. OnCloseStream(ts,now_usec);
  3962. }
  3963. else if (!stat)
  3964. ts->obuf.disabled |= 1;
  3965. else
  3966. {
  3967. UpdateSendStatTCPStream(ts,stat,now_usec);
  3968. if (ts->OnSend)
  3969. stat = ts->OnSend(ts,ts->obuf.ptr,stat);
  3970. if ( stat > 0 )
  3971. DropGrowBuffer(&ts->obuf,stat);
  3972. if ( ts->auto_close && !ts->obuf.used )
  3973. OnCloseStream(ts,now_usec);
  3974. }
  3975. }
  3976. ///////////////////////////////////////////////////////////////////////////////
  3977. void CheckSocketsTCP
  3978. (
  3979. TCPHandler_t *th, // valid TCP handler
  3980. FDList_t *fdl, // valid socket list
  3981. bool check_timeout // true: enable timeout checks
  3982. )
  3983. {
  3984. DASSERT(th);
  3985. DASSERT(fdl);
  3986. const u64 now_usec = GetTimeUSec(false);
  3987. uint i;
  3988. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  3989. {
  3990. Socket_t *lsock = th->listen + i;
  3991. if ( lsock->sock != -1 )
  3992. {
  3993. const uint revents = GetEventFDList(fdl,lsock->sock,lsock->poll_index);
  3994. if ( revents & POLLIN )
  3995. OnAcceptStream(th,lsock,now_usec);
  3996. }
  3997. }
  3998. TCPStream_t *next = th->first;
  3999. while (next)
  4000. {
  4001. // Do it in this way, because 'ts' may become invalid
  4002. TCPStream_t *ts = next;
  4003. next = ts->next;
  4004. CheckSocketTCPStream(ts,fdl,check_timeout);
  4005. }
  4006. }
  4007. ///////////////////////////////////////////////////////////////////////////////
  4008. void CheckTimeoutTCP ( TCPHandler_t *th )
  4009. {
  4010. DASSERT(th);
  4011. TCPStream_t *next = th->first;
  4012. while (next)
  4013. {
  4014. // Do it in this way, because 'ts' may becomes invalid
  4015. TCPStream_t *ts = next;
  4016. next = ts->next;
  4017. CheckTimeoutTCPStream(ts);
  4018. }
  4019. }
  4020. ///////////////////////////////////////////////////////////////////////////////
  4021. bool MaintainTCP ( TCPHandler_t *th )
  4022. {
  4023. DASSERT(th);
  4024. th->need_maintenance = 0;
  4025. const u64 now_usec = GetTimeUSec(false);
  4026. TCPStream_t *next = th->first;
  4027. while (next)
  4028. {
  4029. // Do it in this way, because 'ts' may becomes invalid
  4030. TCPStream_t *ts = next;
  4031. next = ts->next;
  4032. if ( ts->sock == -1 && ts->protect <= 0 )
  4033. DestroyTCPStream(ts);
  4034. else if (ts->OnMaintenance)
  4035. ts->OnMaintenance(ts,now_usec);
  4036. }
  4037. return true;
  4038. }
  4039. ///////////////////////////////////////////////////////////////////////////////
  4040. void ManageSocketsTCP
  4041. (
  4042. // call CheckSocketsTCP(), CheckTimeoutTCP(), MaintainTCP()
  4043. TCPHandler_t *th, // valid TCP handler
  4044. FDList_t *fdl, // valid socket list
  4045. int stat // result of a WAIT function
  4046. )
  4047. {
  4048. if ( stat > 0 )
  4049. CheckSocketsTCP(th,fdl,true);
  4050. else
  4051. CheckTimeoutTCP(th);
  4052. if (th->need_maintenance)
  4053. MaintainTCP(th);
  4054. }
  4055. ///////////////////////////////////////////////////////////////////////////////
  4056. ///////////////////////////////////////////////////////////////////////////////
  4057. void LogTCPHandler
  4058. (
  4059. FILE *f, // output file
  4060. int indent, // indention
  4061. const TCPHandler_t *th, // valid TCP handler
  4062. int recurse, // >0: print stream list, >1: print buffer status
  4063. ccp format, // format string for vfprintf()
  4064. ... // arguments for 'vfprintf(format,...)'
  4065. )
  4066. {
  4067. DASSERT(f);
  4068. DASSERT(th);
  4069. indent = NormalizeIndent(indent);
  4070. fprintf(f,"%*sTH: id:%x, n=%u/%u/%u, listen=",
  4071. indent,"", th->unique_id,
  4072. th->used_streams, th->max_used_streams, th->total_streams );
  4073. uint i;
  4074. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  4075. fprintf(f,"%d,",th->listen[i].sock);
  4076. fprintf(f," max=%u, dsize=%u, ready=%u",
  4077. th->max_conn, th->data_size, NumOfSocketsTCP(th) );
  4078. if (format)
  4079. {
  4080. fputs(" : ",f);
  4081. va_list arg;
  4082. va_start(arg,format);
  4083. vfprintf(f,format,arg);
  4084. va_end(arg);
  4085. }
  4086. fprintf(f,"\n%*s %u connects, %u packets received (%s), %u packets send (%s)\n",
  4087. indent,"",
  4088. th->stat.conn_count,
  4089. th->stat.recv_count, PrintSize1024(0,0,th->stat.recv_size,0),
  4090. th->stat.send_count, PrintSize1024(0,0,th->stat.send_size,0) );
  4091. if (recurse>0)
  4092. {
  4093. recurse--;
  4094. uint idx = 0;
  4095. const TCPStream_t *ts;
  4096. for ( ts = th->first; ts; ts = ts->next )
  4097. LogTCPStream(f,indent+2,ts,recurse,"Stream #%u",idx++);
  4098. }
  4099. }
  4100. ///////////////////////////////////////////////////////////////////////////////
  4101. void PrintStreamTableTCPHandler
  4102. (
  4103. FILE *f, // output file
  4104. const ColorSet_t *colset, // NULL (no colors) or valid color set
  4105. int indent, // indention
  4106. const TCPHandler_t *th // valid TCP handler
  4107. )
  4108. {
  4109. DASSERT(f);
  4110. DASSERT(th);
  4111. indent = NormalizeIndent(indent);
  4112. if (!colset)
  4113. colset = GetColorSet0();
  4114. const u64 now_usec = GetTimeUSec(false);
  4115. const TCPStream_t *ts;
  4116. ccp line1 = BufInfoHeadTCPStream(0);
  4117. ccp line2 = BufInfoHeadTCPStream(1);
  4118. const uint sep_len = strlen(line2)+sizeof(ts->info)-13;
  4119. fprintf(f,"%s%*s%.*s\n%s%*s%s\n%s%*s%s\n%s%*s%.*s%s\n",
  4120. colset->heading, indent,"", sep_len, Minus300,
  4121. colset->heading, indent,"", line1,
  4122. colset->heading, indent,"", line2,
  4123. colset->heading, indent,"", sep_len, Minus300,
  4124. colset->reset );
  4125. char buf[BUF_INFO_TCP_STREAM_SIZE];
  4126. for ( ts = th->first; ts; ts = ts->next )
  4127. {
  4128. BufInfoTCPStream(buf,BUF_INFO_TCP_STREAM_SIZE,ts,now_usec);
  4129. fprintf(f,"%*s%s\n",indent,"",buf);
  4130. }
  4131. if (th->used_streams)
  4132. fprintf(f,
  4133. "%s%*s%.*s%s\n",
  4134. colset->heading, indent,"", sep_len, Minus300,
  4135. colset->reset );
  4136. if ( th->total_streams > 1 || th->total_streams > th->used_streams )
  4137. {
  4138. snprintf(buf,sizeof(buf),"TOTAL: %u current client%s, %u max",
  4139. th->used_streams, th->used_streams == 1 ? "" : "s",
  4140. th->max_used_streams );
  4141. fprintf(f,
  4142. "%s%*s%-45s%s %s%13s %s Summary of %u stream%s\n%s%*s%.*s%s\n",
  4143. colset->status, indent,"", buf,
  4144. PrintNumberU7(0,0,th->stat.recv_count,true),
  4145. PrintSize1024(0,0,th->stat.recv_size,DC_SFORM_TINY|DC_SFORM_ALIGN),
  4146. PrintNumberU7(0,0,th->stat.send_count,true),
  4147. PrintSize1024(0,0,th->stat.send_size,DC_SFORM_TINY|DC_SFORM_ALIGN),
  4148. th->total_streams, th->total_streams == 1 ? "" : "s",
  4149. colset->heading, indent,"", sep_len,Minus300,
  4150. colset->reset );
  4151. }
  4152. }
  4153. ///////////////////////////////////////////////////////////////////////////////
  4154. ///////////////////////////////////////////////////////////////////////////////
  4155. bool GetSocketInfoBySocket
  4156. (
  4157. // returns TRUE, if infos retrived
  4158. socket_info_t *si, // result, not NULL, will be initialized
  4159. int sock, // socket id, maybe -1
  4160. bool get_name // true: alloc 'address' and copy name
  4161. // -> call ResetSocketInfo() to free mem
  4162. )
  4163. {
  4164. DASSERT(si);
  4165. InitializeSocketInfo(si);
  4166. if ( sock == -1 )
  4167. return false;
  4168. si->sock = sock;
  4169. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in) );
  4170. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in6) );
  4171. struct sockaddr_un sa;
  4172. memset(&sa,0,sizeof(sa));
  4173. socklen_t sa_len = sizeof(sa);
  4174. if (getsockname(sock,(struct sockaddr*)&sa,&sa_len))
  4175. return false;
  4176. char buf[INET6_ADDRSTRLEN+10];
  4177. switch (sa.sun_family)
  4178. {
  4179. case AF_UNIX:
  4180. si->protocol = AF_UNIX;
  4181. if ( get_name && sa.sun_path[0] )
  4182. {
  4183. si->address = STRDUP(sa.sun_path);
  4184. si->alloced = true;
  4185. }
  4186. break;
  4187. case AF_INET:
  4188. si->protocol = AF_INET;
  4189. if (get_name)
  4190. {
  4191. const struct sockaddr_in *sin = (struct sockaddr_in*)&sa;
  4192. PrintIP4sa(buf,sizeof(buf),sin);
  4193. si->address = STRDUP(buf);
  4194. si->alloced = true;
  4195. }
  4196. break;
  4197. case AF_INET6:
  4198. si->protocol = AF_INET6;
  4199. if (get_name)
  4200. {
  4201. const struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&sa;
  4202. if (inet_ntop(AF_INET6,&sin6->sin6_addr,buf+1,sizeof(buf)-1))
  4203. {
  4204. *buf = '[';
  4205. char *dest = buf + strlen(buf);
  4206. snprintf(dest,buf+sizeof(buf)-dest,"]:%u",ntohs(sin6->sin6_port));
  4207. si->address = STRDUP(buf);
  4208. si->alloced = true;
  4209. }
  4210. }
  4211. break;
  4212. default:
  4213. return false;
  4214. }
  4215. int socktype = -1;
  4216. socklen_t psize = sizeof(socktype);
  4217. if (!getsockopt(sock,SOL_SOCKET,SO_TYPE,&socktype,&psize))
  4218. si->type = socktype;
  4219. return si->is_valid = true;
  4220. }
  4221. ///////////////////////////////////////////////////////////////////////////////
  4222. ///////////////////////////////////////////////////////////////////////////////
  4223. uint GetSocketNameBySA
  4224. (
  4225. char *buf, // dest buffer
  4226. uint bufsize, // size of 'dest'
  4227. const struct sockaddr *sa, // socket address
  4228. socklen_t sa_len // length of 'sa'
  4229. )
  4230. {
  4231. DASSERT(buf);
  4232. DASSERT(bufsize>0);
  4233. DASSERT(sa);
  4234. DASSERT(sa_len>0);
  4235. if ( sa_len >= sizeof(struct sockaddr_un) )
  4236. {
  4237. const struct sockaddr_un *sun = (struct sockaddr_un*)sa;
  4238. if ( sun->sun_family == AF_UNIX && sun->sun_path[0] )
  4239. return snprintfS(buf,bufsize,"unix:%s",sun->sun_path);
  4240. }
  4241. if ( sa_len >= sizeof(struct sockaddr_in) )
  4242. {
  4243. const struct sockaddr_in *sin = (struct sockaddr_in*)sa;
  4244. if ( sin->sin_family == AF_INET && bufsize > 5 )
  4245. {
  4246. strcpy(buf,"tcp:");
  4247. return PrintIP4sa(buf+4,bufsize-4,sin) - buf;
  4248. }
  4249. }
  4250. if ( sa_len >= sizeof(struct sockaddr_in6) )
  4251. {
  4252. const struct sockaddr_in6 *sin = (struct sockaddr_in6*)sa;
  4253. if ( sin->sin6_family == AF_INET6 && bufsize >= 5 + INET6_ADDRSTRLEN )
  4254. {
  4255. // [[2do]] ??? "[addr]:port"
  4256. strcpy(buf,"tcp6:");
  4257. if (inet_ntop(AF_INET6,&sin->sin6_addr,buf+5,bufsize-5))
  4258. return strlen(buf);
  4259. }
  4260. }
  4261. *buf = 0;
  4262. return 0;
  4263. }
  4264. ///////////////////////////////////////////////////////////////////////////////
  4265. uint GetSocketName ( char *buf, uint bufsize, int sock )
  4266. {
  4267. DASSERT(buf);
  4268. DASSERT(bufsize>0);
  4269. if ( sock != -1 )
  4270. {
  4271. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in) );
  4272. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in6) );
  4273. struct sockaddr_un sun;
  4274. memset(&sun,0,sizeof(sun));
  4275. socklen_t sun_len = sizeof(sun);
  4276. if (!getsockname(sock,(struct sockaddr*)&sun,&sun_len))
  4277. return GetSocketNameBySA(buf,bufsize,(struct sockaddr*)&sun,sun_len);
  4278. }
  4279. *buf = 0;
  4280. return 0;
  4281. }
  4282. ///////////////////////////////////////////////////////////////////////////////
  4283. uint GetPeerName ( char *buf, uint bufsize, int sock )
  4284. {
  4285. DASSERT(buf);
  4286. DASSERT(bufsize>0);
  4287. if ( sock != -1 )
  4288. {
  4289. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in) );
  4290. struct sockaddr_un sun;
  4291. memset(&sun,0,sizeof(sun));
  4292. socklen_t sun_len = sizeof(sun);
  4293. if (!getpeername(sock,(struct sockaddr*)&sun,&sun_len))
  4294. return GetSocketNameBySA(buf,bufsize,(struct sockaddr*)&sun,sun_len);
  4295. }
  4296. *buf = 0;
  4297. return 0;
  4298. }
  4299. ///////////////////////////////////////////////////////////////////////////////
  4300. ///////////////////////////////////////////////////////////////////////////////
  4301. bool DeleteSocketFile ( int sock )
  4302. {
  4303. if ( sock != -1 )
  4304. {
  4305. DASSERT( sizeof(struct sockaddr_un) >= sizeof(struct sockaddr_in) );
  4306. struct sockaddr_un sun;
  4307. memset(&sun,0,sizeof(sun));
  4308. socklen_t sun_len = sizeof(sun);
  4309. if (!getsockname(sock,(struct sockaddr*)&sun,&sun_len))
  4310. {
  4311. if ( sun.sun_family == AF_UNIX )
  4312. {
  4313. unlink(sun.sun_path);
  4314. return true;
  4315. }
  4316. }
  4317. }
  4318. return false;
  4319. }
  4320. //
  4321. ///////////////////////////////////////////////////////////////////////////////
  4322. /////////////// TCP: send single strings ///////////////
  4323. ///////////////////////////////////////////////////////////////////////////////
  4324. static int OnTimeoutSingleTCP ( struct TCPStream_t * ts, u64 now_usec )
  4325. {
  4326. PRINT("OnTimeoutSingleTCP(%p,%llu) sock=%d, to=%lld,%lld d=%lld,%lld\n",
  4327. ts, now_usec, ts->sock,
  4328. ts->trigger_usec, ts->trigger_usec - now_usec,
  4329. ts->accept_usec, ts->accept_usec - now_usec );
  4330. DASSERT(ts);
  4331. OnCloseStream(ts,now_usec);
  4332. return 0;
  4333. }
  4334. ///////////////////////////////////////////////////////////////////////////////
  4335. static int OnReceivedSingleTCP ( struct TCPStream_t * ts, u8 *buf, uint size )
  4336. {
  4337. PRINT("OnReceivedSingleTCP(%p,%p,%u) to=%lld\n",ts,buf,size,*(u64*)ts->data);
  4338. DASSERT(ts);
  4339. ts->accept_usec = GetTimeUSec(false) + *(u64*)ts->data;
  4340. ts->trigger_usec = ts->accept_usec + 100000;
  4341. return 0;
  4342. }
  4343. ///////////////////////////////////////////////////////////////////////////////
  4344. static int OnSendSingleTCP ( struct TCPStream_t * ts, u8 *buf, uint size )
  4345. {
  4346. PRINT("OnSendSingleTCP(%p,%p,%u) to=%lld\n",ts,buf,size,*(u64*)ts->data);
  4347. DASSERT(ts);
  4348. ts->accept_usec = GetTimeUSec(false) + *(u64*)ts->data;
  4349. ts->trigger_usec = ts->accept_usec + 100000;
  4350. return size;
  4351. }
  4352. ///////////////////////////////////////////////////////////////////////////////
  4353. static TCPStream_t * SendSingleTCPHelper
  4354. (
  4355. TCPHandler_t *th, // valid handle
  4356. int sock, // valid socket
  4357. const void *data, // data to send
  4358. uint size, // size of 'data'
  4359. u64 timeout_usec, // timeout before closing the connection
  4360. TransferStats_t *xstat, // NULL or pointer to summary statistics
  4361. bool silent // suppress error messages
  4362. )
  4363. {
  4364. DASSERT(th);
  4365. DASSERT(sock!=-1);
  4366. DASSERT(data||!size);
  4367. PRINT("SendSingleStringTCPHelper(%p,%d,%lld,%d)\n",th,sock,timeout_usec,silent);
  4368. th->stat.conn_count++;
  4369. TCPStream_t *ts = CALLOC(sizeof(*ts)+sizeof(u64),1);
  4370. InitializeTCPStream(ts,sock);
  4371. AddTCPStream(th,ts);
  4372. ts->xstat = xstat;
  4373. ts->OnTimeout = OnTimeoutSingleTCP;
  4374. ts->OnReceived = OnReceivedSingleTCP;
  4375. ts->OnSend = OnSendSingleTCP;
  4376. ts->accept_usec = GetTimeUSec(false) + timeout_usec;
  4377. ts->trigger_usec = ts->accept_usec + 100000;
  4378. *(u64*)ts->data = timeout_usec;
  4379. snprintf(ts->info,sizeof(ts->info),"send single, %u bytes",size);
  4380. #if 1
  4381. ts->obuf.max_size = size > 10240 ? size : 10240;
  4382. SendDirectTCPStream(ts,false,data,size);
  4383. #else
  4384. ts->obuf.max_size = size;
  4385. InsertGrowBuffer(&ts->obuf,data,size);
  4386. #endif
  4387. return ts;
  4388. }
  4389. ///////////////////////////////////////////////////////////////////////////////
  4390. TCPStream_t * SendSingleUnixTCP
  4391. (
  4392. TCPHandler_t *th, // valid handle
  4393. ccp path, // path to socket file
  4394. const void *data, // data to send
  4395. uint size, // size of 'data'
  4396. u64 timeout_usec, // timeout before closing the connection
  4397. TransferStats_t *xstat, // NULL or pointer to summary statistics
  4398. bool silent // suppress error messages
  4399. )
  4400. {
  4401. DASSERT(th);
  4402. DASSERT(path);
  4403. DASSERT(data||!size);
  4404. PRINT("SINGLE/CONNECT/UNIX: %s\n",path);
  4405. int sock = socket(AF_UNIX,SOCK_STREAM,0);
  4406. if ( sock == -1 )
  4407. {
  4408. if (!silent)
  4409. ERROR1(ERR_CANT_CREATE,"Can't create UNIX socket: %s\n",path);
  4410. return 0;
  4411. }
  4412. struct sockaddr_un sa;
  4413. memset(&sa,0,sizeof(sa));
  4414. sa.sun_family = AF_UNIX;
  4415. StringCopyS(sa.sun_path,sizeof(sa.sun_path),path);
  4416. int stat = connect(sock,(struct sockaddr*)&sa,sizeof(sa));
  4417. if (stat)
  4418. {
  4419. if (!silent)
  4420. ERROR1(ERR_CANT_OPEN,"Can't connect UNIX socket: %s\n",path);
  4421. shutdown(sock,SHUT_RDWR);
  4422. close(sock);
  4423. return 0;
  4424. }
  4425. return SendSingleTCPHelper(th,sock,data,size,timeout_usec,xstat,silent);
  4426. }
  4427. ///////////////////////////////////////////////////////////////////////////////
  4428. TCPStream_t * SendSingleTCP
  4429. (
  4430. TCPHandler_t *th, // valid handle
  4431. ccp addr, // address -> NetworkHost_t
  4432. u16 default_port, // default port
  4433. const void *data, // data to send
  4434. uint size, // size of 'data'
  4435. u64 timeout_usec, // timeout before closing the connection
  4436. TransferStats_t *xstat, // NULL or pointer to summary statistics
  4437. bool silent // suppress error messages
  4438. )
  4439. {
  4440. DASSERT(th);
  4441. DASSERT(addr);
  4442. DASSERT(data||!size);
  4443. ccp unix_path = CheckUnixSocketPath(addr,0);
  4444. if (unix_path)
  4445. return SendSingleUnixTCP(th,unix_path,data,size,timeout_usec,xstat,silent);
  4446. if (!strncasecmp(addr,"tcp:",4))
  4447. addr += 4;
  4448. NetworkHost_t nh;
  4449. ResolveHost(&nh,true,addr,default_port,false,false);
  4450. PRINT("SINGLE/CONNECT/TCP: %s -> %s\n",
  4451. addr, PrintIP4(0,0,nh.ip4,nh.port) );
  4452. int sock = socket(AF_INET,SOCK_STREAM|SOCK_NONBLOCK,0);
  4453. if ( sock == -1 )
  4454. {
  4455. if (!silent)
  4456. ERROR1(ERR_CANT_CREATE,"Can't create TCP socket: %s\n",
  4457. PrintIP4(0,0,nh.ip4,nh.port));
  4458. return 0;
  4459. }
  4460. struct sockaddr_in sa;
  4461. memset(&sa,0,sizeof(sa));
  4462. sa.sin_family = AF_INET;
  4463. sa.sin_addr.s_addr = htonl(nh.ip4);
  4464. sa.sin_port = htons(nh.port);
  4465. int stat = connect(sock,(struct sockaddr*)&sa,sizeof(sa));
  4466. if ( stat && errno != EINPROGRESS )
  4467. {
  4468. if (!silent)
  4469. ERROR1(ERR_CANT_OPEN,"Can't connect TCP socket: %s\n",
  4470. PrintIP4(0,0,nh.ip4,nh.port));
  4471. shutdown(sock,SHUT_RDWR);
  4472. close(sock);
  4473. ResetHost(&nh);
  4474. return 0;
  4475. }
  4476. TCPStream_t *ts = SendSingleTCPHelper(th,sock,data,size,timeout_usec,xstat,silent);
  4477. ResetHost(&nh);
  4478. return ts;
  4479. }
  4480. //
  4481. ///////////////////////////////////////////////////////////////////////////////
  4482. /////////////// TCP: CommandTCP ///////////////
  4483. ///////////////////////////////////////////////////////////////////////////////
  4484. void SetTimeoutCommandTCP
  4485. (
  4486. TCPStream_t *ts, // valid stream
  4487. u64 now_usec // NULL or current time in usec
  4488. )
  4489. {
  4490. DASSERT(ts);
  4491. const CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4492. if (!ci->timeout_usec)
  4493. ts->accept_usec = ts->trigger_usec = 0;
  4494. else
  4495. {
  4496. if (!now_usec)
  4497. now_usec = GetTimeUSec(false);
  4498. ts->accept_usec = now_usec + ci->timeout_usec;
  4499. ts->trigger_usec = ts->accept_usec + 100000;
  4500. }
  4501. }
  4502. ///////////////////////////////////////////////////////////////////////////////
  4503. static char * ScanLineCommandTCP
  4504. (
  4505. // return first non scanned character, or NULL on error
  4506. struct TCPStream_t *ts,
  4507. char *line,
  4508. char *line_end,
  4509. u64 now_usec
  4510. )
  4511. {
  4512. DASSERT(ts);
  4513. DASSERT(line);
  4514. DASSERT(line_end);
  4515. DASSERT( line <= line_end );
  4516. *line_end = 0;
  4517. const CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4518. if (ci->OnScanArg)
  4519. {
  4520. SplitArg_t sa;
  4521. ScanSplitArg(&sa,true,line,line_end,line);
  4522. sa.argv[0] = ts->info;
  4523. const int stat = ci->OnScanArg(ts,sa.argc,sa.argv,now_usec);
  4524. ResetSplitArg(&sa);
  4525. return stat > ERR_WARNING ? line : line_end;
  4526. }
  4527. if (ci->OnScanLine)
  4528. return ci->OnScanLine(ts,line,line_end,now_usec);
  4529. //--- fall back: mirror
  4530. InsertGrowBuffer(&ts->obuf,line,line_end-line);
  4531. InsertCharGrowBuffer(&ts->obuf,'\n');
  4532. return line_end;
  4533. }
  4534. ///////////////////////////////////////////////////////////////////////////////
  4535. static void ScanBufferCommandTCP ( struct TCPStream_t * ts, bool finish )
  4536. {
  4537. DASSERT(ts);
  4538. //--- setup
  4539. const u64 now_usec = GetTimeUSec(false);
  4540. const CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4541. const u8 comma = ci->comma_is_eol ? ',' : ';';
  4542. //--- skip uneeded data
  4543. u8 *beg = ts->ibuf.ptr, *end = beg + ts->ibuf.used;
  4544. while ( beg < end )
  4545. {
  4546. const u8 ch = *beg;
  4547. if ( ch > ' ' && ch != ';' && ch != comma )
  4548. break;
  4549. beg++;
  4550. }
  4551. DropGrowBuffer(&ts->ibuf,beg-ts->ibuf.ptr);
  4552. //--- find end of command
  4553. u8 *ptr;
  4554. for ( ptr = beg; ptr < end; ptr++ )
  4555. {
  4556. const u8 ch = *ptr;
  4557. if ( !ch || ch == '\n' || ch == '\r' || ch == ';' || ch == comma )
  4558. {
  4559. DropGrowBuffer(&ts->ibuf,ptr+1-beg);
  4560. ScanLineCommandTCP(ts,(char*)beg,(char*)ptr,now_usec);
  4561. return;
  4562. }
  4563. }
  4564. if ( ptr > beg && ( finish || ts->eof ) )
  4565. {
  4566. DropGrowBuffer(&ts->ibuf,ptr-beg);
  4567. ScanLineCommandTCP(ts,(char*)beg,(char*)ptr,now_usec);
  4568. }
  4569. }
  4570. ///////////////////////////////////////////////////////////////////////////////
  4571. static int OnCommandTCP ( struct TCPStream_t * ts )
  4572. {
  4573. DASSERT(ts);
  4574. SetTimeoutCommandTCP(ts,0);
  4575. while ( ts->sock != -1 && !ts->obuf.used )
  4576. {
  4577. const uint watermark = ts->ibuf.used;
  4578. ScanBufferCommandTCP(ts,false);
  4579. if ( watermark == ts->ibuf.used )
  4580. break;
  4581. }
  4582. if ( ts->eof && !ts->obuf.used && !ts->ibuf.used )
  4583. OnCloseStream(ts,0);
  4584. return 0;
  4585. }
  4586. ///////////////////////////////////////////////////////////////////////////////
  4587. static int OnReceivedCommandTCP ( struct TCPStream_t * ts, u8 *buf, uint size )
  4588. {
  4589. DASSERT(ts);
  4590. noPRINT("---------- OnReceivedCommandTCP(%p,%p,%u), used=%d,%d\n",
  4591. ts, buf, size, ts->ibuf.used, ts->obuf.used );
  4592. InsertGrowBuffer(&ts->ibuf,buf,size);
  4593. return OnCommandTCP(ts);
  4594. }
  4595. ///////////////////////////////////////////////////////////////////////////////
  4596. static int OnSendCommandTCP ( struct TCPStream_t * ts, u8 *buf, uint size )
  4597. {
  4598. DASSERT(ts);
  4599. noPRINT("---------- OnSendCommandTCP(%p,%p,%u), used=%d,%d\n",
  4600. ts, buf, size, ts->ibuf.used, ts->obuf.used );
  4601. DropGrowBuffer(&ts->obuf,size);
  4602. return OnCommandTCP(ts);
  4603. }
  4604. ///////////////////////////////////////////////////////////////////////////////
  4605. static int OnTimeoutCommandTCP ( struct TCPStream_t * ts, u64 now_usec )
  4606. {
  4607. DASSERT(ts);
  4608. noPRINT("---------- OnTimeoutCommandTCP(%p,%llu)\n",ts,now_usec);
  4609. if ( ts->sock != -1 )
  4610. {
  4611. if (!ts->obuf.used)
  4612. {
  4613. ScanBufferCommandTCP(ts,true);
  4614. if (ts->obuf.used)
  4615. {
  4616. SetTimeoutCommandTCP(ts,now_usec);
  4617. return 0;
  4618. }
  4619. }
  4620. OnCloseStream(ts,now_usec);
  4621. }
  4622. return 0;
  4623. }
  4624. ///////////////////////////////////////////////////////////////////////////////
  4625. int OnCreateCommandTCP ( TCPStream_t *ts )
  4626. {
  4627. noPRINT("---------- OnCreateCommandTCP(%p)\n",ts);
  4628. DASSERT(ts);
  4629. ts->OnReceived = OnReceivedCommandTCP;
  4630. ts->OnSend = OnSendCommandTCP;
  4631. ts->OnTimeout = OnTimeoutCommandTCP;
  4632. CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4633. ci->OnScanLine = 0;
  4634. ci->timeout_usec = 10*USEC_PER_SEC;
  4635. ci->comma_is_eol = false;
  4636. SetTimeoutCommandTCP(ts,0);
  4637. return 0;
  4638. }
  4639. //
  4640. ///////////////////////////////////////////////////////////////////////////////
  4641. /////////////// SaveCurrentState*() ///////////////
  4642. ///////////////////////////////////////////////////////////////////////////////
  4643. void SaveCurrentStateSocket
  4644. (
  4645. FILE *f, // output file
  4646. const Socket_t *sock // valid socket object
  4647. )
  4648. {
  4649. DASSERT(f);
  4650. DASSERT(sock);
  4651. char info[3*sizeof(sock->info)];
  4652. PrintEscapedString(info,sizeof(info),sock->info,-1,CHMD__ALL,0,0);
  4653. fprintf(f,
  4654. "sock = %d\n"
  4655. "is-unix = %d\n"
  4656. "info = %s\n"
  4657. ,sock->sock
  4658. ,sock->is_unix
  4659. ,info
  4660. );
  4661. }
  4662. ///////////////////////////////////////////////////////////////////////////////
  4663. void SaveCurrentStateTCPStream
  4664. (
  4665. FILE *f, // output file
  4666. const TCPStream_t *ts, // valid TCP stream
  4667. TCPStreamSaveFunc func // NULL or function for 'TCPStream_t.data' extend
  4668. )
  4669. {
  4670. DASSERT(f);
  4671. DASSERT(ts);
  4672. char info[1000];
  4673. PrintEscapedString(info,sizeof(info),ts->info,-1,CHMD__ALL,0,0);
  4674. fprintf(f,
  4675. "sock = %d\n"
  4676. "rescan = %u\n"
  4677. "eof = %u\n"
  4678. "protect = %u\n"
  4679. "auto-close = %u\n"
  4680. "accept-usec = %llu\n"
  4681. "trigger-usec = %llu\n"
  4682. "delay-usec = %llu\n"
  4683. "timeout-usec = %llu\n"
  4684. "connect-usec = %llu\n"
  4685. "receive-usec = %llu\n"
  4686. "send-usec = %llu\n"
  4687. "info = %s\n"
  4688. ,ts->sock
  4689. ,ts->rescan
  4690. ,ts->eof
  4691. ,ts->protect
  4692. ,ts->auto_close
  4693. ,ts->accept_usec
  4694. ,ts->trigger_usec
  4695. ,ts->delay_usec
  4696. ,ts->timeout_usec
  4697. ,ts->connect_usec
  4698. ,ts->receive_usec
  4699. ,ts->send_usec
  4700. ,info
  4701. );
  4702. if (func)
  4703. func(f,ts);
  4704. SaveCurrentStateTransferStats1(f,"tfer-stat",&ts->stat);
  4705. SaveCurrentStateGrowBuffer(f,"ibuf-",2,&ts->ibuf);
  4706. SaveCurrentStateGrowBuffer(f,"obuf-",2,&ts->obuf);
  4707. }
  4708. ///////////////////////////////////////////////////////////////////////////////
  4709. void SaveCurrentStateCommandTCP
  4710. (
  4711. FILE *f, // output file
  4712. const TCPStream_t *ts // valid TCP stream
  4713. )
  4714. {
  4715. DASSERT(f);
  4716. DASSERT(ts);
  4717. const CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4718. fprintf(f,
  4719. "cmd-comma = %d\n"
  4720. "cmd-timeout = %llu\n"
  4721. ,ci->comma_is_eol
  4722. ,ci->timeout_usec
  4723. );
  4724. }
  4725. ///////////////////////////////////////////////////////////////////////////////
  4726. void SaveCurrentStateTCPHandler
  4727. (
  4728. FILE *f, // output file
  4729. ccp sect_name, // section base name
  4730. const TCPHandler_t *th, // valid TCP handler
  4731. TCPStreamSaveFunc func // NULL or function for 'TCPStream_t.data' extend
  4732. )
  4733. {
  4734. DASSERT(f);
  4735. DASSERT(sect_name);
  4736. DASSERT(th);
  4737. fprintf(f,
  4738. "\n#%.50s\n"
  4739. "[%s]\n"
  4740. "\n"
  4741. "data-size = %u\n"
  4742. "max-conn = %u\n"
  4743. "maintenance = %u\n"
  4744. "used-streams = %u\n"
  4745. "max-used = %u\n"
  4746. "total-streams = %u\n"
  4747. ,Minus300
  4748. ,sect_name
  4749. ,th->data_size
  4750. ,th->max_conn
  4751. ,th->need_maintenance
  4752. ,th->used_streams
  4753. ,th->max_used_streams
  4754. ,th->total_streams
  4755. );
  4756. SaveCurrentStateTransferStats1(f,"tfer-stat",&th->stat);
  4757. uint i;
  4758. for ( i = 0; i < TCP_HANDLER_MAX_LISTEN; i++ )
  4759. {
  4760. if ( th->listen[i].sock != -1 )
  4761. {
  4762. fprintf(f,"\n[%s/socket:%u]\n\n",sect_name,i);
  4763. SaveCurrentStateSocket(f,th->listen+i);
  4764. }
  4765. }
  4766. const TCPStream_t *ts;
  4767. for ( ts = th->first, i = 0; ts; ts = ts->next, i++ )
  4768. {
  4769. fprintf(f,"\n[%s/stream:%u]\n\n",sect_name,i);
  4770. SaveCurrentStateTCPStream(f,ts,func);
  4771. }
  4772. }
  4773. //
  4774. ///////////////////////////////////////////////////////////////////////////////
  4775. /////////////// RestoreState*() ///////////////
  4776. ///////////////////////////////////////////////////////////////////////////////
  4777. void RestoreStateSocket
  4778. (
  4779. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  4780. cvp user_table // pointer provided by RestoreStateTab_t[]
  4781. )
  4782. {
  4783. DASSERT(rs);
  4784. Socket_t *sock = (Socket_t*)user_table;
  4785. if (!sock)
  4786. return;
  4787. int fd = GetParamFieldINT(rs,"sock",-1);
  4788. if ( fd != -1 && fcntl(fd,F_GETFD) != -1 )
  4789. {
  4790. sock->sock = fd;
  4791. sock->is_unix = GetParamFieldINT(rs,"is-unix",0);
  4792. GetParamFieldBUF(sock->info,sizeof(sock->info),rs,"info",ENCODE_STRING,"?");
  4793. }
  4794. }
  4795. ///////////////////////////////////////////////////////////////////////////////
  4796. ///////////////////////////////////////////////////////////////////////////////
  4797. TCPStream_t * RestoreStateTCPStream
  4798. (
  4799. // return 'ts' or the new TCPStream_t
  4800. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  4801. TCPStream_t *ts, // if NULL: create it
  4802. uint extra_size // if 'ts' alloced: alloc some byte more
  4803. )
  4804. {
  4805. DASSERT(rs);
  4806. TRACE("RestoreStateTCPStream()\n");
  4807. int fd = ts ? ts->sock : -1;
  4808. if ( fd == -1 )
  4809. {
  4810. fd = GetParamFieldINT(rs,"sock",-1);
  4811. if ( fd != -1 && fcntl(fd,F_GETFD) == -1 )
  4812. fd = -1;
  4813. }
  4814. if (!ts)
  4815. {
  4816. ts = CALLOC(sizeof(*ts)+extra_size,1);
  4817. InitializeTCPStream(ts,fd);
  4818. }
  4819. else
  4820. ts->sock = fd;
  4821. DASSERT(ts);
  4822. ts->protect = GetParamFieldUINT(rs, "protect", ts->protect);
  4823. ts->auto_close = GetParamFieldUINT(rs, "auto-close", ts->auto_close);
  4824. ts->rescan = GetParamFieldUINT(rs, "rescan", ts->rescan );
  4825. ts->eof = GetParamFieldUINT(rs, "eof", ts->eof );
  4826. ts->accept_usec = GetParamFieldU64 (rs, "accept-usec", ts->accept_usec );
  4827. ts->trigger_usec = GetParamFieldU64 (rs, "trigger-usec", ts->trigger_usec );
  4828. ts->delay_usec = GetParamFieldU64 (rs, "delay-usec", ts->delay_usec );
  4829. ts->timeout_usec = GetParamFieldU64 (rs, "timeout-usec", ts->timeout_usec );
  4830. ts->connect_usec = GetParamFieldU64 (rs, "connect-usec", ts->connect_usec );
  4831. ts->receive_usec = GetParamFieldU64 (rs, "receive-usec", ts->receive_usec );
  4832. ts->send_usec = GetParamFieldU64 (rs, "send-usec", ts->send_usec );
  4833. GetParamFieldBUF(ts->info,sizeof(ts->info),rs,"info",ENCODE_STRING,"?");
  4834. RestoreStateTransferStats1(rs,"tfer-stat",&ts->stat,true);
  4835. RestoreStateGrowBuffer(&ts->ibuf,"ibuf-",rs);
  4836. RestoreStateGrowBuffer(&ts->obuf,"obuf-",rs);
  4837. return ts;
  4838. }
  4839. ///////////////////////////////////////////////////////////////////////////////
  4840. ///////////////////////////////////////////////////////////////////////////////
  4841. void RestoreStateTCPHandler_base
  4842. (
  4843. TCPHandler_t *th, // valid TCPHandler_t
  4844. RestoreState_t *rs // info data, can be modified (cleaned after call)
  4845. )
  4846. {
  4847. DASSERT(th);
  4848. DASSERT(rs);
  4849. TRACE("RestoreStateTCPHandler_base()\n");
  4850. //ResetTCPHandler(th); // don't call, because call back functions are cleared
  4851. struct uint_parm_t
  4852. {
  4853. ccp name;
  4854. uint *param;
  4855. };
  4856. const struct uint_parm_t uint_parm_tab[] =
  4857. {
  4858. { "max-conn", &th->max_conn },
  4859. { "maintenance", &th->need_maintenance },
  4860. { "max-used", &th->max_used_streams },
  4861. { "total-streams", &th->total_streams },
  4862. {0,0}
  4863. };
  4864. const struct uint_parm_t *up;
  4865. for ( up = uint_parm_tab; up->name; up++ )
  4866. *up->param = GetParamFieldUINT(rs,up->name,*up->param);
  4867. RestoreStateTransferStats1(rs,"tfer-stat",&th->stat,true);
  4868. if ( rs->log_mode & RSL_UNUSED_NAMES )
  4869. {
  4870. // known as 'unused'
  4871. GetParamField(rs,"data-size");
  4872. GetParamField(rs,"used-streams");
  4873. }
  4874. }
  4875. ///////////////////////////////////////////////////////////////////////////////
  4876. Socket_t * RestoreStateTCPHandler_socket
  4877. (
  4878. TCPHandler_t *th, // valid TCPHandler_t
  4879. RestoreState_t *rs // info data, can be modified (cleaned after call)
  4880. )
  4881. {
  4882. DASSERT(th);
  4883. DASSERT(rs);
  4884. TRACE("RestoreStateTCPHandler_socket()\n");
  4885. Socket_t *sock = GetUnusedListenSocketTCP(th,false);
  4886. if (sock)
  4887. RestoreStateSocket(rs,sock);
  4888. return sock;
  4889. }
  4890. ///////////////////////////////////////////////////////////////////////////////
  4891. TCPStream_t * RestoreStateTCPHandler_stream
  4892. (
  4893. TCPHandler_t *th, // valid TCPHandler_t
  4894. RestoreState_t *rs // info data, can be modified (cleaned after call)
  4895. )
  4896. {
  4897. DASSERT(th);
  4898. DASSERT(rs);
  4899. TRACE("RestoreStateTCPHandler_stream()\n");
  4900. int fd = GetParamFieldINT(rs,"sock",-1);
  4901. bool protect = GetParamFieldUINT(rs,"protect",0);
  4902. #ifdef TEST
  4903. if ( !protect && fd == -1 )
  4904. return 0;
  4905. #else
  4906. if ( !protect && ( fd == -1 || fcntl(fd,F_GETFD) == -1 ))
  4907. return 0;
  4908. #endif
  4909. TCPStream_t *ts = CreateTCPStream(th,fd,ALLOW_MODE_ALLOW,0);
  4910. RestoreStateTCPStream(rs,ts,th->data_size);
  4911. return ts;
  4912. }
  4913. ///////////////////////////////////////////////////////////////////////////////
  4914. void RestoreStateTCPHandler
  4915. (
  4916. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  4917. cvp user_table // pointer provided by RestoreStateTab_t[]
  4918. )
  4919. {
  4920. DASSERT(rs);
  4921. TRACE("Scan TCP Handler (%s/%s,%d)\n",rs->sect,rs->path,rs->index);
  4922. TCPHandler_t *th = (TCPHandler_t*)user_table;
  4923. if (!th)
  4924. return;
  4925. if (!*rs->path)
  4926. RestoreStateTCPHandler_base(th,rs);
  4927. else if (!strcmp(rs->path,"socket"))
  4928. RestoreStateTCPHandler_socket(th,rs);
  4929. else if (!strcmp(rs->path,"stream"))
  4930. RestoreStateTCPHandler_stream(th,rs);
  4931. }
  4932. ///////////////////////////////////////////////////////////////////////////////
  4933. ///////////////////////////////////////////////////////////////////////////////
  4934. void RestoreStateCommandTCP
  4935. (
  4936. RestoreState_t *rs, // info data, can be modified (cleaned after call)
  4937. cvp user_table // pointer provided by RestoreStateTab_t[]
  4938. )
  4939. {
  4940. DASSERT(rs);
  4941. TCPHandler_t *th = (TCPHandler_t*)user_table;
  4942. if (!th)
  4943. return;
  4944. if (!strcmp(rs->path,"stream"))
  4945. {
  4946. TCPStream_t *ts = RestoreStateTCPHandler_stream(th,rs);
  4947. if (ts)
  4948. {
  4949. CommandTCPInfo_t *ci = (CommandTCPInfo_t*)ts->data;
  4950. ci->comma_is_eol = GetParamFieldINT( rs, "cmd-comma", ci->comma_is_eol ) > 0;
  4951. ci->timeout_usec = GetParamFieldU64( rs, "cmd-timeout", ci->timeout_usec );
  4952. }
  4953. }
  4954. else
  4955. RestoreStateTCPHandler(rs,user_table);
  4956. }
  4957. //
  4958. ///////////////////////////////////////////////////////////////////////////////
  4959. /////////////// Misc ///////////////
  4960. ///////////////////////////////////////////////////////////////////////////////
  4961. bool fix_ether_head_vlan ( ether_head_vlan_t *head )
  4962. {
  4963. DASSERT(head);
  4964. const u16 vlan_tag_type = ntohs(head->vlan_tag_type);
  4965. if ( vlan_tag_type == 0x8100 )
  4966. {
  4967. head->have_vlan = true;
  4968. head->head_size = 18;
  4969. return true;
  4970. }
  4971. head->ether_type = head->vlan_tag_type;
  4972. head->have_vlan = false;
  4973. head->head_size = 14;
  4974. return false;
  4975. }
  4976. ///////////////////////////////////////////////////////////////////////////////
  4977. void ntoh_ether_head_vlan ( ether_head_vlan_t *dest, const void * src )
  4978. {
  4979. if (dest)
  4980. {
  4981. if (src)
  4982. memcpy(dest,src,sizeof(*dest));
  4983. fix_ether_head_vlan(dest);
  4984. dest->vlan_tag_type = ntohs(dest->vlan_tag_type);
  4985. dest->vlan_param = ntohs(dest->vlan_param);
  4986. dest->ether_type = ntohs(dest->ether_type);
  4987. }
  4988. }
  4989. ///////////////////////////////////////////////////////////////////////////////
  4990. void ntoh_ether_head ( ether_head_t *dest, const void * src )
  4991. {
  4992. if (dest)
  4993. {
  4994. if (src)
  4995. memcpy(dest,src,sizeof(*dest));
  4996. dest->ether_type = ntohs(dest->ether_type);
  4997. }
  4998. }
  4999. ///////////////////////////////////////////////////////////////////////////////
  5000. void ntoh_ip4_head ( ip4_head_t *dest, const void * src )
  5001. {
  5002. if (dest)
  5003. {
  5004. if (src)
  5005. memcpy(dest,src,sizeof(*dest));
  5006. dest->total_len = ntohs(dest->total_len);
  5007. dest->id = ntohs(dest->id);
  5008. dest->frag_off = ntohs(dest->frag_off);
  5009. dest->checksum = ntohs(dest->checksum);
  5010. dest->ip_src = ntohl(dest->ip_src);
  5011. dest->ip_dest = ntohl(dest->ip_dest);
  5012. }
  5013. }
  5014. ///////////////////////////////////////////////////////////////////////////////
  5015. void ntoh_udp_head ( udp_head_t *dest, const void * src )
  5016. {
  5017. if (dest)
  5018. {
  5019. const udp_head_t *usrc = src ? src : dest;
  5020. dest->port_src = ntohs(usrc->port_src);
  5021. dest->port_dest = ntohs(usrc->port_dest);
  5022. dest->data_len = ntohs(usrc->data_len);
  5023. dest->checksum = ntohs(usrc->checksum);
  5024. }
  5025. }
  5026. ///////////////////////////////////////////////////////////////////////////////
  5027. void ntoh_tcp_head ( tcp_head_t *dest, const void * src )
  5028. {
  5029. if (dest)
  5030. {
  5031. const tcp_head_t *usrc = src ? src : dest;
  5032. dest->port_src = ntohs(usrc->port_src);
  5033. dest->port_dest = ntohs(usrc->port_dest);
  5034. dest->seq_num = ntohl(usrc->seq_num);
  5035. dest->acc_num = ntohl(usrc->acc_num);
  5036. dest->data_off = usrc->data_off;
  5037. dest->flags = usrc->flags;
  5038. dest->window = ntohs(usrc->window);
  5039. dest->checksum = ntohs(usrc->checksum);
  5040. dest->urgent = ntohs(usrc->urgent);
  5041. }
  5042. }
  5043. //
  5044. ///////////////////////////////////////////////////////////////////////////////
  5045. /////////////// Linux support ///////////////
  5046. ///////////////////////////////////////////////////////////////////////////////
  5047. #if defined(SYSTEM_LINUX) || defined(__CYGWIN__)
  5048. #include "dclib-network-linux.c"
  5049. #endif // SYSTEM_LINUX
  5050. //
  5051. ///////////////////////////////////////////////////////////////////////////////
  5052. /////////////// END ///////////////
  5053. ///////////////////////////////////////////////////////////////////////////////