gnunet-service-tng.c 299 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2016, 2018, 2019 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file transport/gnunet-service-tng.c
  18. * @brief main for gnunet-service-tng
  19. * @author Christian Grothoff
  20. *
  21. * TODO:
  22. * Implement next:
  23. * - review retransmission logic, right now there is no smartness there!
  24. * => congestion control, etc [PERFORMANCE-BASICS]
  25. *
  26. * Optimizations-Statistics:
  27. * - Track ACK losses based on ACK-counter [ROUTING]
  28. * - Need to track total bandwidth per VirtualLink and adjust how frequently
  29. * we send FC messages based on bandwidth-delay-product (and relation
  30. * to the window size!). See OPTIMIZE-FC-BDP.
  31. * - Consider more statistics in #check_connection_quality() [FIXME-CONQ-STATISTICS]
  32. * - Adapt available_fc_window_size, using larger values for high-bandwidth
  33. * and high-latency links *if* we have the RAM [GOODPUT / utilization / stalls]
  34. * - Set last_window_consum_limit promise properly based on
  35. * latency and bandwidth of the respective connection [GOODPUT / utilization / stalls]
  36. *
  37. * Optimizations-DV:
  38. * - When forwarding DV learn messages, if a peer is reached that
  39. * has a *bidirectional* link to the origin beyond 1st hop,
  40. * do NOT forward it to peers _other_ than the origin, as
  41. * there is clearly a better path directly from the origin to
  42. * whatever else we could reach.
  43. * - When we passively learned DV (with unconfirmed freshness), we
  44. * right now add the path to our list but with a zero path_valid_until
  45. * time and only use it for unconfirmed routes. However, we could consider
  46. * triggering an explicit validation mechansim ourselves, specifically routing
  47. * a challenge-response message over the path [ROUTING]
  48. * = if available, try to confirm unconfirmed DV paths when trying to establish
  49. * virtual link for a `struct IncomingRequest`. (i.e. if DVH is
  50. * unconfirmed, incoming requests cause us to try to validate a passively
  51. * learned path (requires new message type!))
  52. *
  53. * Optimizations-Fragmentation:
  54. * - Fragments send over a reliable channel could do without the
  55. * AcknowledgementUUIDP altogether, as they won't be acked! [BANDWIDTH]
  56. * (-> have 2nd type of acknowledgment message; low priority, as we
  57. * do not have an MTU-limited *reliable* communicator) [FIXME-FRAG-REL-UUID]
  58. * - if messages are below MTU, consider adding ACKs and other stuff
  59. * to the same transmission to avoid tiny messages (requires planning at
  60. * receiver, and additional MST-style demultiplex at receiver!) [PACKET COUNT]
  61. *
  62. * Optimizations-internals:
  63. * - queue_send_msg by API design has to make a copy
  64. * of the payload, and route_message on top of that requires a malloc/free.
  65. * Change design to approximate "zero" copy better... [CPU]
  66. * - could avoid copying body of message into each fragment and keep
  67. * fragments as just pointers into the original message and only
  68. * fully build fragments just before transmission (optimization, should
  69. * reduce CPU and memory use) [CPU, MEMORY]
  70. */
  71. #include "platform.h"
  72. #include "gnunet_util_lib.h"
  73. #include "gnunet_statistics_service.h"
  74. #include "gnunet_transport_monitor_service.h"
  75. #include "gnunet_peerstore_service.h"
  76. #include "gnunet_hello_lib.h"
  77. #include "gnunet_signatures.h"
  78. #include "transport.h"
  79. /**
  80. * Maximum number of messages we acknowledge together in one
  81. * cummulative ACK. Larger values may save a bit of bandwidth.
  82. */
  83. #define MAX_CUMMULATIVE_ACKS 64
  84. /**
  85. * What is the 1:n chance that we send a Flow control response when
  86. * receiving a flow control message that did not change anything for
  87. * us? Basically, this is used in the case where both peers are stuck
  88. * on flow control (no window changes), but one might continue sending
  89. * flow control messages to the other peer as the first FC message
  90. * when things stalled got lost, and then subsequently the other peer
  91. * does *usually* not respond as nothing changed. So to ensure that
  92. * eventually the FC messages stop, we do send with 1/8th probability
  93. * an FC message even if nothing changed. That prevents one peer
  94. * being stuck in sending (useless) FC messages "forever".
  95. */
  96. #define FC_NO_CHANGE_REPLY_PROBABILITY 8
  97. /**
  98. * What is the size we assume for a read operation in the
  99. * absence of an MTU for the purpose of flow control?
  100. */
  101. #define IN_PACKET_SIZE_WITHOUT_MTU 128
  102. /**
  103. * Number of slots we keep of historic data for computation of
  104. * goodput / message loss ratio.
  105. */
  106. #define GOODPUT_AGING_SLOTS 4
  107. /**
  108. * How big is the flow control window size by default;
  109. * limits per-neighbour RAM utilization.
  110. */
  111. #define DEFAULT_WINDOW_SIZE (128 * 1024)
  112. /**
  113. * For how many incoming connections do we try to create a
  114. * virtual link for (at the same time!). This does NOT
  115. * limit the number of incoming connections, just the number
  116. * for which we are actively trying to find working addresses
  117. * in the absence (!) of our own applications wanting the
  118. * link to go up.
  119. */
  120. #define MAX_INCOMING_REQUEST 16
  121. /**
  122. * Maximum number of peers we select for forwarding DVInit
  123. * messages at the same time (excluding initiator).
  124. */
  125. #define MAX_DV_DISCOVERY_SELECTION 16
  126. /**
  127. * Window size. How many messages to the same target do we pass
  128. * to CORE without a RECV_OK in between? Small values limit
  129. * thoughput, large values will increase latency.
  130. *
  131. * FIXME-OPTIMIZE: find out what good values are experimentally,
  132. * maybe set adaptively (i.e. to observed available bandwidth).
  133. */
  134. #define RECV_WINDOW_SIZE 4
  135. /**
  136. * Minimum number of hops we should forward DV learn messages
  137. * even if they are NOT useful for us in hope of looping
  138. * back to the initiator?
  139. *
  140. * FIXME: allow initiator some control here instead?
  141. */
  142. #define MIN_DV_PATH_LENGTH_FOR_INITIATOR 3
  143. /**
  144. * Maximum DV distance allowed ever.
  145. */
  146. #define MAX_DV_HOPS_ALLOWED 16
  147. /**
  148. * Maximum number of DV learning activities we may
  149. * have pending at the same time.
  150. */
  151. #define MAX_DV_LEARN_PENDING 64
  152. /**
  153. * Maximum number of DV paths we keep simultaneously to the same target.
  154. */
  155. #define MAX_DV_PATHS_TO_TARGET 3
  156. /**
  157. * If a queue delays the next message by more than this number
  158. * of seconds we log a warning. Note: this is for testing,
  159. * the value chosen here might be too aggressively low!
  160. */
  161. #define DELAY_WARN_THRESHOLD \
  162. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
  163. /**
  164. * If a DVBox could not be forwarded after this number of
  165. * seconds we drop it.
  166. */
  167. #define DV_FORWARD_TIMEOUT \
  168. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
  169. /**
  170. * We only consider queues as "quality" connections when
  171. * suppressing the generation of DV initiation messages if
  172. * the latency of the queue is below this threshold.
  173. */
  174. #define DV_QUALITY_RTT_THRESHOLD \
  175. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
  176. /**
  177. * How long do we consider a DV path valid if we see no
  178. * further updates on it? Note: the value chosen here might be too low!
  179. */
  180. #define DV_PATH_VALIDITY_TIMEOUT \
  181. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
  182. /**
  183. * How long do we cache backchannel (struct Backtalker) information
  184. * after a backchannel goes inactive?
  185. */
  186. #define BACKCHANNEL_INACTIVITY_TIMEOUT \
  187. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
  188. /**
  189. * How long before paths expire would we like to (re)discover DV paths? Should
  190. * be below #DV_PATH_VALIDITY_TIMEOUT.
  191. */
  192. #define DV_PATH_DISCOVERY_FREQUENCY \
  193. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
  194. /**
  195. * How long are ephemeral keys valid?
  196. */
  197. #define EPHEMERAL_VALIDITY \
  198. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
  199. /**
  200. * How long do we keep partially reassembled messages around before giving up?
  201. */
  202. #define REASSEMBLY_EXPIRATION \
  203. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
  204. /**
  205. * What is the fastest rate at which we send challenges *if* we keep learning
  206. * an address (gossip, DHT, etc.)?
  207. */
  208. #define FAST_VALIDATION_CHALLENGE_FREQ \
  209. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
  210. /**
  211. * What is the slowest rate at which we send challenges?
  212. */
  213. #define MAX_VALIDATION_CHALLENGE_FREQ \
  214. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
  215. /**
  216. * How long until we forget about historic accumulators and thus
  217. * reset the ACK counter? Should exceed the maximum time an
  218. * active connection experiences without an ACK.
  219. */
  220. #define ACK_CUMMULATOR_TIMEOUT \
  221. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
  222. /**
  223. * What is the non-randomized base frequency at which we
  224. * would initiate DV learn messages?
  225. */
  226. #define DV_LEARN_BASE_FREQUENCY GNUNET_TIME_UNIT_MINUTES
  227. /**
  228. * How many good connections (confirmed, bi-directional, not DV)
  229. * do we need to have to suppress initiating DV learn messages?
  230. */
  231. #define DV_LEARN_QUALITY_THRESHOLD 100
  232. /**
  233. * When do we forget an invalid address for sure?
  234. */
  235. #define MAX_ADDRESS_VALID_UNTIL \
  236. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
  237. /**
  238. * How long do we consider an address valid if we just checked?
  239. */
  240. #define ADDRESS_VALIDATION_LIFETIME \
  241. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
  242. /**
  243. * What is the maximum frequency at which we do address validation?
  244. * A random value between 0 and this value is added when scheduling
  245. * the #validation_task (both to ensure we do not validate too often,
  246. * and to randomize a bit).
  247. */
  248. #define MIN_DELAY_ADDRESS_VALIDATION GNUNET_TIME_UNIT_MILLISECONDS
  249. /**
  250. * How many network RTTs before an address validation expires should we begin
  251. * trying to revalidate? (Note that the RTT used here is the one that we
  252. * experienced during the last validation, not necessarily the latest RTT
  253. * observed).
  254. */
  255. #define VALIDATION_RTT_BUFFER_FACTOR 3
  256. /**
  257. * How many messages can we have pending for a given communicator
  258. * process before we start to throttle that communicator?
  259. *
  260. * Used if a communicator might be CPU-bound and cannot handle the traffic.
  261. */
  262. #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512
  263. /**
  264. * How many messages can we have pending for a given queue (queue to
  265. * a particular peer via a communicator) process before we start to
  266. * throttle that queue?
  267. */
  268. #define QUEUE_LENGTH_LIMIT 32
  269. GNUNET_NETWORK_STRUCT_BEGIN
  270. /**
  271. * Unique identifier we attach to a message.
  272. */
  273. struct MessageUUIDP
  274. {
  275. /**
  276. * Unique value, generated by incrementing the
  277. * `message_uuid_ctr` of `struct Neighbour`.
  278. */
  279. uint64_t uuid GNUNET_PACKED;
  280. };
  281. /**
  282. * Unique identifier to map an acknowledgement to a transmission.
  283. */
  284. struct AcknowledgementUUIDP
  285. {
  286. /**
  287. * The UUID value.
  288. */
  289. struct GNUNET_Uuid value;
  290. };
  291. /**
  292. * Type of a nonce used for challenges.
  293. */
  294. struct ChallengeNonceP
  295. {
  296. /**
  297. * The value of the nonce. Note that this is NOT a hash.
  298. */
  299. struct GNUNET_ShortHashCode value;
  300. };
  301. /**
  302. * Outer layer of an encapsulated backchannel message.
  303. */
  304. struct TransportBackchannelEncapsulationMessage
  305. {
  306. /**
  307. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION.
  308. */
  309. struct GNUNET_MessageHeader header;
  310. /* Followed by *another* message header which is the message to
  311. the communicator */
  312. /* Followed by a 0-terminated name of the communicator */
  313. };
  314. /**
  315. * Body by which a peer confirms that it is using an ephemeral key.
  316. */
  317. struct EphemeralConfirmationPS
  318. {
  319. /**
  320. * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
  321. */
  322. struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  323. /**
  324. * How long is this signature over the ephemeral key valid?
  325. *
  326. * Note that the receiver MUST IGNORE the absolute time, and only interpret
  327. * the value as a mononic time and reject "older" values than the last one
  328. * observed. This is necessary as we do not want to require synchronized
  329. * clocks and may not have a bidirectional communication channel.
  330. *
  331. * Even with this, there is no real guarantee against replay achieved here,
  332. * unless the latest timestamp is persisted. While persistence should be
  333. * provided via PEERSTORE, we do not consider the mechanism reliable! Thus,
  334. * communicators must protect against replay attacks when using backchannel
  335. * communication!
  336. */
  337. struct GNUNET_TIME_AbsoluteNBO sender_monotonic_time;
  338. /**
  339. * Target's peer identity.
  340. */
  341. struct GNUNET_PeerIdentity target;
  342. /**
  343. * Ephemeral key setup by the sender for @e target, used
  344. * to encrypt the payload.
  345. */
  346. struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
  347. };
  348. /**
  349. * Plaintext of the variable-size payload that is encrypted
  350. * within a `struct TransportBackchannelEncapsulationMessage`
  351. */
  352. struct TransportDVBoxPayloadP
  353. {
  354. /**
  355. * Sender's peer identity.
  356. */
  357. struct GNUNET_PeerIdentity sender;
  358. /**
  359. * Signature of the sender over an
  360. * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL.
  361. */
  362. struct GNUNET_CRYPTO_EddsaSignature sender_sig;
  363. /**
  364. * Current monotonic time of the sending transport service. Used to
  365. * detect replayed messages. Note that the receiver should remember
  366. * a list of the recently seen timestamps and only reject messages
  367. * if the timestamp is in the list, or the list is "full" and the
  368. * timestamp is smaller than the lowest in the list.
  369. *
  370. * Like the @e ephemeral_validity, the list of timestamps per peer should be
  371. * persisted to guard against replays after restarts.
  372. */
  373. struct GNUNET_TIME_AbsoluteNBO monotonic_time;
  374. /* Followed by a `struct GNUNET_MessageHeader` with a message
  375. for the target peer */
  376. };
  377. /**
  378. * Outer layer of an encapsulated unfragmented application message sent
  379. * over an unreliable channel.
  380. */
  381. struct TransportReliabilityBoxMessage
  382. {
  383. /**
  384. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX
  385. */
  386. struct GNUNET_MessageHeader header;
  387. /**
  388. * Number of messages still to be sent before a commulative
  389. * ACK is requested. Zero if an ACK is requested immediately.
  390. * In NBO. Note that the receiver may send the ACK faster
  391. * if it believes that is reasonable.
  392. */
  393. uint32_t ack_countdown GNUNET_PACKED;
  394. /**
  395. * Unique ID of the message used for signalling receipt of
  396. * messages sent over possibly unreliable channels. Should
  397. * be a random.
  398. */
  399. struct AcknowledgementUUIDP ack_uuid;
  400. };
  401. /**
  402. * Acknowledgement payload.
  403. */
  404. struct TransportCummulativeAckPayloadP
  405. {
  406. /**
  407. * How long was the ACK delayed for generating cummulative ACKs?
  408. * Used to calculate the correct network RTT by taking the receipt
  409. * time of the ack minus the transmission time of the sender minus
  410. * this value.
  411. */
  412. struct GNUNET_TIME_RelativeNBO ack_delay;
  413. /**
  414. * UUID of a message being acknowledged.
  415. */
  416. struct AcknowledgementUUIDP ack_uuid;
  417. };
  418. /**
  419. * Confirmation that the receiver got a
  420. * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. Note that the
  421. * confirmation may be transmitted over a completely different queue,
  422. * so ACKs are identified by a combination of PID of sender and
  423. * message UUID, without the queue playing any role!
  424. */
  425. struct TransportReliabilityAckMessage
  426. {
  427. /**
  428. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK
  429. */
  430. struct GNUNET_MessageHeader header;
  431. /**
  432. * Counter of ACKs transmitted by the sender to us. Incremented
  433. * by one for each ACK, used to detect how many ACKs were lost.
  434. */
  435. uint32_t ack_counter GNUNET_PACKED;
  436. /* followed by any number of `struct TransportCummulativeAckPayloadP`
  437. messages providing ACKs */
  438. };
  439. /**
  440. * Outer layer of an encapsulated fragmented application message.
  441. */
  442. struct TransportFragmentBoxMessage
  443. {
  444. /**
  445. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT
  446. */
  447. struct GNUNET_MessageHeader header;
  448. /**
  449. * Offset of this fragment in the overall message.
  450. */
  451. uint16_t frag_off GNUNET_PACKED;
  452. /**
  453. * Total size of the message that is being fragmented.
  454. */
  455. uint16_t msg_size GNUNET_PACKED;
  456. /**
  457. * Unique ID of this fragment (and fragment transmission!). Will
  458. * change even if a fragement is retransmitted to make each
  459. * transmission attempt unique! If a client receives a duplicate
  460. * fragment (same @e frag_off for same @a msg_uuid, it must send
  461. * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK immediately.
  462. */
  463. struct AcknowledgementUUIDP ack_uuid;
  464. /**
  465. * Original message ID for of the message that all the fragments
  466. * belong to. Must be the same for all fragments.
  467. */
  468. struct MessageUUIDP msg_uuid;
  469. };
  470. /**
  471. * Content signed by the initator during DV learning.
  472. *
  473. * The signature is required to prevent DDoS attacks. A peer sending out this
  474. * message is potentially generating a lot of traffic that will go back to the
  475. * initator, as peers receiving this message will try to let the initiator
  476. * know that they got the message.
  477. *
  478. * Without this signature, an attacker could abuse this mechanism for traffic
  479. * amplification, sending a lot of traffic to a peer by putting out this type
  480. * of message with the victim's peer identity.
  481. *
  482. * Even with just a signature, traffic amplification would be possible via
  483. * replay attacks. The @e monotonic_time limits such replay attacks, as every
  484. * potential amplificator will check the @e monotonic_time and only respond
  485. * (at most) once per message.
  486. */
  487. struct DvInitPS
  488. {
  489. /**
  490. * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
  491. */
  492. struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  493. /**
  494. * Time at the initiator when generating the signature.
  495. *
  496. * Note that the receiver MUST IGNORE the absolute time, and only interpret
  497. * the value as a mononic time and reject "older" values than the last one
  498. * observed. This is necessary as we do not want to require synchronized
  499. * clocks and may not have a bidirectional communication channel.
  500. *
  501. * Even with this, there is no real guarantee against replay achieved here,
  502. * unless the latest timestamp is persisted. Persistence should be
  503. * provided via PEERSTORE if possible.
  504. */
  505. struct GNUNET_TIME_AbsoluteNBO monotonic_time;
  506. /**
  507. * Challenge value used by the initiator to re-identify the path.
  508. */
  509. struct ChallengeNonceP challenge;
  510. };
  511. /**
  512. * Content signed by each peer during DV learning.
  513. *
  514. * This assues the initiator of the DV learning operation that the hop from @e
  515. * pred via the signing peer to @e succ actually exists. This makes it
  516. * impossible for an adversary to supply the network with bogus routes.
  517. *
  518. * The @e challenge is included to provide replay protection for the
  519. * initiator. This way, the initiator knows that the hop existed after the
  520. * original @e challenge was first transmitted, providing a freshness metric.
  521. *
  522. * Peers other than the initiator that passively learn paths by observing
  523. * these messages do NOT benefit from this. Here, an adversary may indeed
  524. * replay old messages. Thus, passively learned paths should always be
  525. * immediately marked as "potentially stale".
  526. */
  527. struct DvHopPS
  528. {
  529. /**
  530. * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
  531. */
  532. struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  533. /**
  534. * Identity of the previous peer on the path.
  535. */
  536. struct GNUNET_PeerIdentity pred;
  537. /**
  538. * Identity of the next peer on the path.
  539. */
  540. struct GNUNET_PeerIdentity succ;
  541. /**
  542. * Challenge value used by the initiator to re-identify the path.
  543. */
  544. struct ChallengeNonceP challenge;
  545. };
  546. /**
  547. * An entry describing a peer on a path in a
  548. * `struct TransportDVLearnMessage` message.
  549. */
  550. struct DVPathEntryP
  551. {
  552. /**
  553. * Identity of a peer on the path.
  554. */
  555. struct GNUNET_PeerIdentity hop;
  556. /**
  557. * Signature of this hop over the path, of purpose
  558. * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
  559. */
  560. struct GNUNET_CRYPTO_EddsaSignature hop_sig;
  561. };
  562. /**
  563. * Internal message used by transport for distance vector learning.
  564. * If @e num_hops does not exceed the threshold, peers should append
  565. * themselves to the peer list and flood the message (possibly only
  566. * to a subset of their neighbours to limit discoverability of the
  567. * network topology). To the extend that the @e bidirectional bits
  568. * are set, peers may learn the inverse paths even if they did not
  569. * initiate.
  570. *
  571. * Unless received on a bidirectional queue and @e num_hops just
  572. * zero, peers that can forward to the initator should always try to
  573. * forward to the initiator.
  574. */
  575. struct TransportDVLearnMessage
  576. {
  577. /**
  578. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN
  579. */
  580. struct GNUNET_MessageHeader header;
  581. /**
  582. * Number of hops this messages has travelled, in NBO. Zero if
  583. * sent by initiator.
  584. */
  585. uint16_t num_hops GNUNET_PACKED;
  586. /**
  587. * Bitmask of the last 16 hops indicating whether they are confirmed
  588. * available (without DV) in both directions or not, in NBO. Used
  589. * to possibly instantly learn a path in both directions. Each peer
  590. * should shift this value by one to the left, and then set the
  591. * lowest bit IF the current sender can be reached from it (without
  592. * DV routing).
  593. */
  594. uint16_t bidirectional GNUNET_PACKED;
  595. /**
  596. * Peers receiving this message and delaying forwarding to other
  597. * peers for any reason should increment this value by the non-network
  598. * delay created by the peer.
  599. */
  600. struct GNUNET_TIME_RelativeNBO non_network_delay;
  601. /**
  602. * Time at the initiator when generating the signature.
  603. *
  604. * Note that the receiver MUST IGNORE the absolute time, and only interpret
  605. * the value as a mononic time and reject "older" values than the last one
  606. * observed. This is necessary as we do not want to require synchronized
  607. * clocks and may not have a bidirectional communication channel.
  608. *
  609. * Even with this, there is no real guarantee against replay achieved here,
  610. * unless the latest timestamp is persisted. Persistence should be
  611. * provided via PEERSTORE if possible.
  612. */
  613. struct GNUNET_TIME_AbsoluteNBO monotonic_time;
  614. /**
  615. * Signature of this hop over the path, of purpose
  616. * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
  617. */
  618. struct GNUNET_CRYPTO_EddsaSignature init_sig;
  619. /**
  620. * Identity of the peer that started this learning activity.
  621. */
  622. struct GNUNET_PeerIdentity initiator;
  623. /**
  624. * Challenge value used by the initiator to re-identify the path.
  625. */
  626. struct ChallengeNonceP challenge;
  627. /* Followed by @e num_hops `struct DVPathEntryP` values,
  628. excluding the initiator of the DV trace; the last entry is the
  629. current sender; the current peer must not be included. */
  630. };
  631. /**
  632. * Outer layer of an encapsulated message send over multiple hops.
  633. * The path given only includes the identities of the subsequent
  634. * peers, i.e. it will be empty if we are the receiver. Each
  635. * forwarding peer should scan the list from the end, and if it can,
  636. * forward to the respective peer. The list should then be shortened
  637. * by all the entries up to and including that peer. Each hop should
  638. * also increment @e total_hops to allow the receiver to get a precise
  639. * estimate on the number of hops the message travelled. Senders must
  640. * provide a learned path that thus should work, but intermediaries
  641. * know of a shortcut, they are allowed to send the message via that
  642. * shortcut.
  643. *
  644. * If a peer finds itself still on the list, it must drop the message.
  645. *
  646. * The payload of the box can only be decrypted and verified by the
  647. * ultimate receiver. Intermediaries do not learn the sender's
  648. * identity and the path the message has taken. However, the first
  649. * hop does learn the sender as @e total_hops would be zero and thus
  650. * the predecessor must be the origin (so this is not really useful
  651. * for anonymization).
  652. */
  653. struct TransportDVBoxMessage
  654. {
  655. /**
  656. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX
  657. */
  658. struct GNUNET_MessageHeader header;
  659. /**
  660. * Number of total hops this messages travelled. In NBO.
  661. * @e origin sets this to zero, to be incremented at
  662. * each hop. Peers should limit the @e total_hops value
  663. * they accept from other peers.
  664. */
  665. uint16_t total_hops GNUNET_PACKED;
  666. /**
  667. * Number of hops this messages includes. In NBO. Reduced by one
  668. * or more at each hop. Peers should limit the @e num_hops value
  669. * they accept from other peers.
  670. */
  671. uint16_t num_hops GNUNET_PACKED;
  672. /**
  673. * Ephemeral key setup by the sender for target, used to encrypt the
  674. * payload. Intermediaries must not change this value.
  675. */
  676. struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
  677. /**
  678. * We use an IV here as the @e ephemeral_key is re-used for
  679. * #EPHEMERAL_VALIDITY time to avoid re-signing it all the time.
  680. * Intermediaries must not change this value.
  681. */
  682. struct GNUNET_ShortHashCode iv;
  683. /**
  684. * HMAC over the ciphertext of the encrypted, variable-size body
  685. * that follows. Verified via DH of target and @e ephemeral_key.
  686. * Intermediaries must not change this value.
  687. */
  688. struct GNUNET_HashCode hmac;
  689. /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values;
  690. excluding the @e origin and the current peer, the last must be
  691. the ultimate target; if @e num_hops is zero, the receiver of this
  692. message is the ultimate target. */
  693. /* Followed by encrypted, variable-size payload, which
  694. must begin with a `struct TransportDVBoxPayloadP` */
  695. /* Followed by the actual message, which itself must not be a
  696. a DV_LEARN or DV_BOX message! */
  697. };
  698. /**
  699. * Message send to another peer to validate that it can indeed
  700. * receive messages at a particular address.
  701. */
  702. struct TransportValidationChallengeMessage
  703. {
  704. /**
  705. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE
  706. */
  707. struct GNUNET_MessageHeader header;
  708. /**
  709. * Always zero.
  710. */
  711. uint32_t reserved GNUNET_PACKED;
  712. /**
  713. * Challenge to be signed by the receiving peer.
  714. */
  715. struct ChallengeNonceP challenge;
  716. /**
  717. * Timestamp of the sender, to be copied into the reply to allow
  718. * sender to calculate RTT. Must be monotonically increasing!
  719. */
  720. struct GNUNET_TIME_AbsoluteNBO sender_time;
  721. };
  722. /**
  723. * Message signed by a peer to confirm that it can indeed
  724. * receive messages at a particular address.
  725. */
  726. struct TransportValidationPS
  727. {
  728. /**
  729. * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE
  730. */
  731. struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  732. /**
  733. * How long does the sender believe the address on
  734. * which the challenge was received to remain valid?
  735. */
  736. struct GNUNET_TIME_RelativeNBO validity_duration;
  737. /**
  738. * Challenge signed by the receiving peer.
  739. */
  740. struct ChallengeNonceP challenge;
  741. };
  742. /**
  743. * Message send to a peer to respond to a
  744. * #GNUNET_MESSAGE_TYPE_ADDRESS_VALIDATION_CHALLENGE
  745. */
  746. struct TransportValidationResponseMessage
  747. {
  748. /**
  749. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE
  750. */
  751. struct GNUNET_MessageHeader header;
  752. /**
  753. * Always zero.
  754. */
  755. uint32_t reserved GNUNET_PACKED;
  756. /**
  757. * The peer's signature matching the
  758. * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE purpose.
  759. */
  760. struct GNUNET_CRYPTO_EddsaSignature signature;
  761. /**
  762. * The challenge that was signed by the receiving peer.
  763. */
  764. struct ChallengeNonceP challenge;
  765. /**
  766. * Original timestamp of the sender (was @code{sender_time}),
  767. * copied into the reply to allow sender to calculate RTT.
  768. */
  769. struct GNUNET_TIME_AbsoluteNBO origin_time;
  770. /**
  771. * How long does the sender believe this address to remain
  772. * valid?
  773. */
  774. struct GNUNET_TIME_RelativeNBO validity_duration;
  775. };
  776. /**
  777. * Message for Transport-to-Transport Flow control. Specifies the size
  778. * of the flow control window, including how much we believe to have
  779. * consumed (at transmission time), how much we believe to be allowed
  780. * (at transmission time), and how much the other peer is allowed to
  781. * send to us, and how much data we already received from the other
  782. * peer.
  783. */
  784. struct TransportFlowControlMessage
  785. {
  786. /**
  787. * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL
  788. */
  789. struct GNUNET_MessageHeader header;
  790. /**
  791. * Sequence number of the flow control message. Incremented by one
  792. * for each message. Starts at zero when a virtual link goes up.
  793. * Used to detect one-sided connection drops. On wrap-around, the
  794. * flow control counters will be reset as if the connection had
  795. * dropped.
  796. */
  797. uint32_t seq GNUNET_PACKED;
  798. /**
  799. * Flow control window size in bytes, in NBO.
  800. * The receiver can send this many bytes at most.
  801. */
  802. uint64_t inbound_window_size GNUNET_PACKED;
  803. /**
  804. * How many bytes has the sender sent that count for flow control at
  805. * this time. Used to allow the receiver to estimate the packet
  806. * loss rate.
  807. */
  808. uint64_t outbound_sent GNUNET_PACKED;
  809. /**
  810. * Latest flow control window size we learned from the other peer,
  811. * in bytes, in NBO. We are limited to sending at most this many
  812. * bytes to the other peer. May help the other peer detect when
  813. * flow control messages were lost and should thus be retransmitted.
  814. * In particular, if the delta to @e outbound_sent is too small,
  815. * this signals that we are stalled.
  816. */
  817. uint64_t outbound_window_size GNUNET_PACKED;
  818. /**
  819. * Timestamp of the sender. Must be monotonically increasing!
  820. * Used to enable receiver to ignore out-of-order packets in
  821. * combination with the @e seq. Note that @e seq will go down
  822. * (back to zero) whenever either side believes the connection
  823. * was dropped, allowing the peers to detect that they need to
  824. * reset the counters for the number of bytes sent!
  825. */
  826. struct GNUNET_TIME_AbsoluteNBO sender_time;
  827. };
  828. GNUNET_NETWORK_STRUCT_END
  829. /**
  830. * What type of client is the `struct TransportClient` about?
  831. */
  832. enum ClientType
  833. {
  834. /**
  835. * We do not know yet (client is fresh).
  836. */
  837. CT_NONE = 0,
  838. /**
  839. * Is the CORE service, we need to forward traffic to it.
  840. */
  841. CT_CORE = 1,
  842. /**
  843. * It is a monitor, forward monitor data.
  844. */
  845. CT_MONITOR = 2,
  846. /**
  847. * It is a communicator, use for communication.
  848. */
  849. CT_COMMUNICATOR = 3,
  850. /**
  851. * "Application" telling us where to connect (i.e. TOPOLOGY, DHT or CADET).
  852. */
  853. CT_APPLICATION = 4
  854. };
  855. /**
  856. * Which transmission options are allowable for transmission?
  857. * Interpreted bit-wise!
  858. */
  859. enum RouteMessageOptions
  860. {
  861. /**
  862. * Only confirmed, non-DV direct neighbours.
  863. */
  864. RMO_NONE = 0,
  865. /**
  866. * We are allowed to use DV routing for this @a hdr
  867. */
  868. RMO_DV_ALLOWED = 1,
  869. /**
  870. * We are allowed to use unconfirmed queues or DV routes for this message
  871. */
  872. RMO_UNCONFIRMED_ALLOWED = 2,
  873. /**
  874. * Reliable and unreliable, DV and non-DV are all acceptable.
  875. */
  876. RMO_ANYTHING_GOES = (RMO_DV_ALLOWED | RMO_UNCONFIRMED_ALLOWED),
  877. /**
  878. * If we have multiple choices, it is OK to send this message
  879. * over multiple channels at the same time to improve loss tolerance.
  880. * (We do at most 2 transmissions.)
  881. */
  882. RMO_REDUNDANT = 4
  883. };
  884. /**
  885. * When did we launch this DV learning activity?
  886. */
  887. struct LearnLaunchEntry
  888. {
  889. /**
  890. * Kept (also) in a DLL sorted by launch time.
  891. */
  892. struct LearnLaunchEntry *prev;
  893. /**
  894. * Kept (also) in a DLL sorted by launch time.
  895. */
  896. struct LearnLaunchEntry *next;
  897. /**
  898. * Challenge that uniquely identifies this activity.
  899. */
  900. struct ChallengeNonceP challenge;
  901. /**
  902. * When did we transmit the DV learn message (used to calculate RTT) and
  903. * determine freshness of paths learned via this operation.
  904. */
  905. struct GNUNET_TIME_Absolute launch_time;
  906. };
  907. /**
  908. * Information we keep per #GOODPUT_AGING_SLOTS about historic
  909. * (or current) transmission performance.
  910. */
  911. struct TransmissionHistoryEntry
  912. {
  913. /**
  914. * Number of bytes actually sent in the interval.
  915. */
  916. uint64_t bytes_sent;
  917. /**
  918. * Number of bytes received and acknowledged by the other peer in
  919. * the interval.
  920. */
  921. uint64_t bytes_received;
  922. };
  923. /**
  924. * Performance data for a transmission possibility.
  925. */
  926. struct PerformanceData
  927. {
  928. /**
  929. * Weighted average for the RTT.
  930. */
  931. struct GNUNET_TIME_Relative aged_rtt;
  932. /**
  933. * Historic performance data, using a ring buffer of#GOODPUT_AGING_SLOTS
  934. * entries.
  935. */
  936. struct TransmissionHistoryEntry the[GOODPUT_AGING_SLOTS];
  937. /**
  938. * What was the last age when we wrote to @e the? Used to clear
  939. * old entries when the age advances.
  940. */
  941. unsigned int last_age;
  942. };
  943. /**
  944. * Client connected to the transport service.
  945. */
  946. struct TransportClient;
  947. /**
  948. * A neighbour that at least one communicator is connected to.
  949. */
  950. struct Neighbour;
  951. /**
  952. * Entry in our #dv_routes table, representing a (set of) distance
  953. * vector routes to a particular peer.
  954. */
  955. struct DistanceVector;
  956. /**
  957. * A queue is a message queue provided by a communicator
  958. * via which we can reach a particular neighbour.
  959. */
  960. struct Queue;
  961. /**
  962. * Message awaiting transmission. See detailed comments below.
  963. */
  964. struct PendingMessage;
  965. /**
  966. * One possible hop towards a DV target.
  967. */
  968. struct DistanceVectorHop;
  969. /**
  970. * A virtual link is another reachable peer that is known to CORE. It
  971. * can be either a `struct Neighbour` with at least one confirmed
  972. * `struct Queue`, or a `struct DistanceVector` with at least one
  973. * confirmed `struct DistanceVectorHop`. With a virtual link we track
  974. * data that is per neighbour that is not specific to how the
  975. * connectivity is established.
  976. */
  977. struct VirtualLink;
  978. /**
  979. * Context from #handle_incoming_msg(). Closure for many
  980. * message handlers below.
  981. */
  982. struct CommunicatorMessageContext
  983. {
  984. /**
  985. * Kept in a DLL of `struct VirtualLink` if waiting for CORE
  986. * flow control to unchoke.
  987. */
  988. struct CommunicatorMessageContext *next;
  989. /**
  990. * Kept in a DLL of `struct VirtualLink` if waiting for CORE
  991. * flow control to unchoke.
  992. */
  993. struct CommunicatorMessageContext *prev;
  994. /**
  995. * Which communicator provided us with the message.
  996. */
  997. struct TransportClient *tc;
  998. /**
  999. * Additional information for flow control and about the sender.
  1000. */
  1001. struct GNUNET_TRANSPORT_IncomingMessage im;
  1002. /**
  1003. * Number of hops the message has travelled (if DV-routed).
  1004. * FIXME: make use of this in ACK handling!
  1005. */
  1006. uint16_t total_hops;
  1007. };
  1008. /**
  1009. * Closure for #core_env_sent_cb.
  1010. */
  1011. struct CoreSentContext
  1012. {
  1013. /**
  1014. * Kept in a DLL to clear @e vl in case @e vl is lost.
  1015. */
  1016. struct CoreSentContext *next;
  1017. /**
  1018. * Kept in a DLL to clear @e vl in case @e vl is lost.
  1019. */
  1020. struct CoreSentContext *prev;
  1021. /**
  1022. * Virtual link this is about.
  1023. */
  1024. struct VirtualLink *vl;
  1025. /**
  1026. * How big was the message.
  1027. */
  1028. uint16_t size;
  1029. /**
  1030. * By how much should we increment @e vl's
  1031. * incoming_fc_window_size_used once we are done sending to CORE?
  1032. * Use to ensure we do not increment twice if there is more than one
  1033. * CORE client.
  1034. */
  1035. uint16_t isize;
  1036. };
  1037. /**
  1038. * A virtual link is another reachable peer that is known to CORE. It
  1039. * can be either a `struct Neighbour` with at least one confirmed
  1040. * `struct Queue`, or a `struct DistanceVector` with at least one
  1041. * confirmed `struct DistanceVectorHop`. With a virtual link we track
  1042. * data that is per neighbour that is not specific to how the
  1043. * connectivity is established.
  1044. */
  1045. struct VirtualLink
  1046. {
  1047. /**
  1048. * Identity of the peer at the other end of the link.
  1049. */
  1050. struct GNUNET_PeerIdentity target;
  1051. /**
  1052. * Communicators blocked for receiving on @e target as we are waiting
  1053. * on the @e core_recv_window to increase.
  1054. */
  1055. struct CommunicatorMessageContext *cmc_head;
  1056. /**
  1057. * Communicators blocked for receiving on @e target as we are waiting
  1058. * on the @e core_recv_window to increase.
  1059. */
  1060. struct CommunicatorMessageContext *cmc_tail;
  1061. /**
  1062. * Head of list of messages pending for this VL.
  1063. */
  1064. struct PendingMessage *pending_msg_head;
  1065. /**
  1066. * Tail of list of messages pending for this VL.
  1067. */
  1068. struct PendingMessage *pending_msg_tail;
  1069. /**
  1070. * Kept in a DLL to clear @e vl in case @e vl is lost.
  1071. */
  1072. struct CoreSentContext *csc_tail;
  1073. /**
  1074. * Kept in a DLL to clear @e vl in case @e vl is lost.
  1075. */
  1076. struct CoreSentContext *csc_head;
  1077. /**
  1078. * Task scheduled to possibly notfiy core that this peer is no
  1079. * longer counting as confirmed. Runs the #core_visibility_check(),
  1080. * which checks that some DV-path or a queue exists that is still
  1081. * considered confirmed.
  1082. */
  1083. struct GNUNET_SCHEDULER_Task *visibility_task;
  1084. /**
  1085. * Task scheduled to periodically retransmit FC messages (in
  1086. * case one got lost).
  1087. */
  1088. struct GNUNET_SCHEDULER_Task *fc_retransmit_task;
  1089. /**
  1090. * Neighbour used by this virtual link, NULL if @e dv is used.
  1091. */
  1092. struct Neighbour *n;
  1093. /**
  1094. * Distance vector used by this virtual link, NULL if @e n is used.
  1095. */
  1096. struct DistanceVector *dv;
  1097. /**
  1098. * Sender timestamp of @e n_challenge, used to generate out-of-order
  1099. * challenges (as sender's timestamps must be monotonically
  1100. * increasing). FIXME: where do we need this?
  1101. */
  1102. struct GNUNET_TIME_Absolute n_challenge_time;
  1103. /**
  1104. * When did we last send a
  1105. * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message?
  1106. * Used to determine whether it is time to re-transmit the message.
  1107. */
  1108. struct GNUNET_TIME_Absolute last_fc_transmission;
  1109. /**
  1110. * Sender timestamp of the last
  1111. * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message we have
  1112. * received. Note that we do not persist this monotonic time as we
  1113. * do not really have to worry about ancient flow control window
  1114. * sizes after restarts.
  1115. */
  1116. struct GNUNET_TIME_Absolute last_fc_timestamp;
  1117. /**
  1118. * Expected RTT from the last FC transmission. (Zero if the last
  1119. * attempt failed, but could theoretically be zero even on success.)
  1120. */
  1121. struct GNUNET_TIME_Relative last_fc_rtt;
  1122. /**
  1123. * Used to generate unique UUIDs for messages that are being
  1124. * fragmented.
  1125. */
  1126. uint64_t message_uuid_ctr;
  1127. /**
  1128. * Memory allocated for this virtual link. Expresses how much RAM
  1129. * we are willing to allocate to this virtual link. OPTIMIZE-ME:
  1130. * Can be adapted to dedicate more RAM to links that need it, while
  1131. * sticking to some overall RAM limit. For now, set to
  1132. * #DEFAULT_WINDOW_SIZE.
  1133. */
  1134. uint64_t available_fc_window_size;
  1135. /**
  1136. * Memory actually used to buffer packets on this virtual link.
  1137. * Expresses how much RAM we are currently using for virtual link.
  1138. * Note that once CORE is done with a packet, we decrement the value
  1139. * here.
  1140. */
  1141. uint64_t incoming_fc_window_size_ram;
  1142. /**
  1143. * Last flow control window size we provided to the other peer, in
  1144. * bytes. We are allowing the other peer to send this
  1145. * many bytes.
  1146. */
  1147. uint64_t incoming_fc_window_size;
  1148. /**
  1149. * How much of the window did the other peer successfully use (and
  1150. * we already passed it on to CORE)? Must be below @e
  1151. * incoming_fc_window_size. We should effectively signal the
  1152. * other peer that the window is this much bigger at the next
  1153. * opportunity / challenge.
  1154. */
  1155. uint64_t incoming_fc_window_size_used;
  1156. /**
  1157. * What is our current estimate on the message loss rate for the sender?
  1158. * Based on the difference between how much the sender sent according
  1159. * to the last #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message
  1160. * (@e outbound_sent field) and how much we actually received at that
  1161. * time (@e incoming_fc_window_size_used). This delta is then
  1162. * added onto the @e incoming_fc_window_size when determining the
  1163. * @e outbound_window_size we send to the other peer. Initially zero.
  1164. * May be negative if we (due to out-of-order delivery) actually received
  1165. * more than the sender claims to have sent in its last FC message.
  1166. */
  1167. int64_t incoming_fc_window_size_loss;
  1168. /**
  1169. * Our current flow control window size in bytes. We
  1170. * are allowed to transmit this many bytes to @a n.
  1171. */
  1172. uint64_t outbound_fc_window_size;
  1173. /**
  1174. * How much of our current flow control window size have we
  1175. * used (in bytes). Must be below
  1176. * @e outbound_fc_window_size.
  1177. */
  1178. uint64_t outbound_fc_window_size_used;
  1179. /**
  1180. * What is the most recent FC window the other peer sent us
  1181. * in `outbound_window_size`? This is basically the window
  1182. * size value the other peer has definitively received from
  1183. * us. If it matches @e incoming_fc_window_size, we should
  1184. * not send a FC message to increase the FC window. However,
  1185. * we may still send an FC message to notify the other peer
  1186. * that we received the other peer's FC message.
  1187. */
  1188. uint64_t last_outbound_window_size_received;
  1189. /**
  1190. * Generator for the sequence numbers of
  1191. * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL messages we send.
  1192. */
  1193. uint32_t fc_seq_gen;
  1194. /**
  1195. * Last sequence number of a
  1196. * #GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL message we have
  1197. * received.
  1198. */
  1199. uint32_t last_fc_seq;
  1200. /**
  1201. * How many more messages can we send to CORE before we exhaust
  1202. * the receive window of CORE for this peer? If this hits zero,
  1203. * we must tell communicators to stop providing us more messages
  1204. * for this peer. In fact, the window can go negative as we
  1205. * have multiple communicators, so per communicator we can go
  1206. * down by one into the negative range. Furthermore, we count
  1207. * delivery per CORE client, so if we had multiple cores, that
  1208. * might also cause a negative window size here (as one message
  1209. * would decrement the window by one per CORE client).
  1210. */
  1211. int core_recv_window;
  1212. };
  1213. /**
  1214. * Data structure kept when we are waiting for an acknowledgement.
  1215. */
  1216. struct PendingAcknowledgement
  1217. {
  1218. /**
  1219. * If @e pm is non-NULL, this is the DLL in which this acknowledgement
  1220. * is kept in relation to its pending message.
  1221. */
  1222. struct PendingAcknowledgement *next_pm;
  1223. /**
  1224. * If @e pm is non-NULL, this is the DLL in which this acknowledgement
  1225. * is kept in relation to its pending message.
  1226. */
  1227. struct PendingAcknowledgement *prev_pm;
  1228. /**
  1229. * If @e queue is non-NULL, this is the DLL in which this acknowledgement
  1230. * is kept in relation to the queue that was used to transmit the
  1231. * @a pm.
  1232. */
  1233. struct PendingAcknowledgement *next_queue;
  1234. /**
  1235. * If @e queue is non-NULL, this is the DLL in which this acknowledgement
  1236. * is kept in relation to the queue that was used to transmit the
  1237. * @a pm.
  1238. */
  1239. struct PendingAcknowledgement *prev_queue;
  1240. /**
  1241. * If @e dvh is non-NULL, this is the DLL in which this acknowledgement
  1242. * is kept in relation to the DVH that was used to transmit the
  1243. * @a pm.
  1244. */
  1245. struct PendingAcknowledgement *next_dvh;
  1246. /**
  1247. * If @e dvh is non-NULL, this is the DLL in which this acknowledgement
  1248. * is kept in relation to the DVH that was used to transmit the
  1249. * @a pm.
  1250. */
  1251. struct PendingAcknowledgement *prev_dvh;
  1252. /**
  1253. * Pointers for the DLL of all pending acknowledgements.
  1254. * This list is sorted by @e transmission time. If the list gets too
  1255. * long, the oldest entries are discarded.
  1256. */
  1257. struct PendingAcknowledgement *next_pa;
  1258. /**
  1259. * Pointers for the DLL of all pending acknowledgements.
  1260. * This list is sorted by @e transmission time. If the list gets too
  1261. * long, the oldest entries are discarded.
  1262. */
  1263. struct PendingAcknowledgement *prev_pa;
  1264. /**
  1265. * Unique identifier for this transmission operation.
  1266. */
  1267. struct AcknowledgementUUIDP ack_uuid;
  1268. /**
  1269. * Message that was transmitted, may be NULL if the message was ACKed
  1270. * via another channel.
  1271. */
  1272. struct PendingMessage *pm;
  1273. /**
  1274. * Distance vector path chosen for this transmission, NULL if transmission
  1275. * was to a direct neighbour OR if the path was forgotten in the meantime.
  1276. */
  1277. struct DistanceVectorHop *dvh;
  1278. /**
  1279. * Queue used for transmission, NULL if the queue has been destroyed
  1280. * (which may happen before we get an acknowledgement).
  1281. */
  1282. struct Queue *queue;
  1283. /**
  1284. * Time of the transmission, for RTT calculation.
  1285. */
  1286. struct GNUNET_TIME_Absolute transmission_time;
  1287. /**
  1288. * Number of bytes of the original message (to calculate bandwidth).
  1289. */
  1290. uint16_t message_size;
  1291. };
  1292. /**
  1293. * One possible hop towards a DV target.
  1294. */
  1295. struct DistanceVectorHop
  1296. {
  1297. /**
  1298. * Kept in a MDLL, sorted by @e timeout.
  1299. */
  1300. struct DistanceVectorHop *next_dv;
  1301. /**
  1302. * Kept in a MDLL, sorted by @e timeout.
  1303. */
  1304. struct DistanceVectorHop *prev_dv;
  1305. /**
  1306. * Kept in a MDLL.
  1307. */
  1308. struct DistanceVectorHop *next_neighbour;
  1309. /**
  1310. * Kept in a MDLL.
  1311. */
  1312. struct DistanceVectorHop *prev_neighbour;
  1313. /**
  1314. * Head of DLL of PAs that used our @a path.
  1315. */
  1316. struct PendingAcknowledgement *pa_head;
  1317. /**
  1318. * Tail of DLL of PAs that used our @a path.
  1319. */
  1320. struct PendingAcknowledgement *pa_tail;
  1321. /**
  1322. * What would be the next hop to @e target?
  1323. */
  1324. struct Neighbour *next_hop;
  1325. /**
  1326. * Distance vector entry this hop belongs with.
  1327. */
  1328. struct DistanceVector *dv;
  1329. /**
  1330. * Array of @e distance hops to the target, excluding @e next_hop.
  1331. * NULL if the entire path is us to @e next_hop to `target`. Allocated
  1332. * at the end of this struct. Excludes the target itself!
  1333. */
  1334. const struct GNUNET_PeerIdentity *path;
  1335. /**
  1336. * At what time do we forget about this path unless we see it again
  1337. * while learning?
  1338. */
  1339. struct GNUNET_TIME_Absolute timeout;
  1340. /**
  1341. * For how long is the validation of this path considered
  1342. * valid?
  1343. * Set to ZERO if the path is learned by snooping on DV learn messages
  1344. * initiated by other peers, and to the time at which we generated the
  1345. * challenge for DV learn operations this peer initiated.
  1346. */
  1347. struct GNUNET_TIME_Absolute path_valid_until;
  1348. /**
  1349. * Performance data for this transmission possibility.
  1350. */
  1351. struct PerformanceData pd;
  1352. /**
  1353. * Number of hops in total to the `target` (excluding @e next_hop and `target`
  1354. * itself). Thus 0 still means a distance of 2 hops (to @e next_hop and then
  1355. * to `target`).
  1356. */
  1357. unsigned int distance;
  1358. };
  1359. /**
  1360. * Entry in our #dv_routes table, representing a (set of) distance
  1361. * vector routes to a particular peer.
  1362. */
  1363. struct DistanceVector
  1364. {
  1365. /**
  1366. * To which peer is this a route?
  1367. */
  1368. struct GNUNET_PeerIdentity target;
  1369. /**
  1370. * Known paths to @e target.
  1371. */
  1372. struct DistanceVectorHop *dv_head;
  1373. /**
  1374. * Known paths to @e target.
  1375. */
  1376. struct DistanceVectorHop *dv_tail;
  1377. /**
  1378. * Task scheduled to purge expired paths from @e dv_head MDLL.
  1379. */
  1380. struct GNUNET_SCHEDULER_Task *timeout_task;
  1381. /**
  1382. * Do we have a confirmed working queue and are thus visible to
  1383. * CORE? If so, this is the virtual link, otherwise NULL.
  1384. */
  1385. struct VirtualLink *vl;
  1386. /**
  1387. * Signature affirming @e ephemeral_key of type
  1388. * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
  1389. */
  1390. struct GNUNET_CRYPTO_EddsaSignature sender_sig;
  1391. /**
  1392. * How long is @e sender_sig valid
  1393. */
  1394. struct GNUNET_TIME_Absolute ephemeral_validity;
  1395. /**
  1396. * What time was @e sender_sig created
  1397. */
  1398. struct GNUNET_TIME_Absolute monotime;
  1399. /**
  1400. * Our ephemeral key.
  1401. */
  1402. struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
  1403. /**
  1404. * Our private ephemeral key.
  1405. */
  1406. struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
  1407. };
  1408. /**
  1409. * Entry identifying transmission in one of our `struct
  1410. * Queue` which still awaits an ACK. This is used to
  1411. * ensure we do not overwhelm a communicator and limit the number of
  1412. * messages outstanding per communicator (say in case communicator is
  1413. * CPU bound) and per queue (in case bandwidth allocation exceeds
  1414. * what the communicator can actually provide towards a particular
  1415. * peer/target).
  1416. */
  1417. struct QueueEntry
  1418. {
  1419. /**
  1420. * Kept as a DLL.
  1421. */
  1422. struct QueueEntry *next;
  1423. /**
  1424. * Kept as a DLL.
  1425. */
  1426. struct QueueEntry *prev;
  1427. /**
  1428. * Queue this entry is queued with.
  1429. */
  1430. struct Queue *queue;
  1431. /**
  1432. * Pending message this entry is for, or NULL for none.
  1433. */
  1434. struct PendingMessage *pm;
  1435. /**
  1436. * Message ID used for this message with the queue used for transmission.
  1437. */
  1438. uint64_t mid;
  1439. };
  1440. /**
  1441. * A queue is a message queue provided by a communicator
  1442. * via which we can reach a particular neighbour.
  1443. */
  1444. struct Queue
  1445. {
  1446. /**
  1447. * Kept in a MDLL.
  1448. */
  1449. struct Queue *next_neighbour;
  1450. /**
  1451. * Kept in a MDLL.
  1452. */
  1453. struct Queue *prev_neighbour;
  1454. /**
  1455. * Kept in a MDLL.
  1456. */
  1457. struct Queue *prev_client;
  1458. /**
  1459. * Kept in a MDLL.
  1460. */
  1461. struct Queue *next_client;
  1462. /**
  1463. * Head of DLL of PAs that used this queue.
  1464. */
  1465. struct PendingAcknowledgement *pa_head;
  1466. /**
  1467. * Tail of DLL of PAs that used this queue.
  1468. */
  1469. struct PendingAcknowledgement *pa_tail;
  1470. /**
  1471. * Head of DLL of unacked transmission requests.
  1472. */
  1473. struct QueueEntry *queue_head;
  1474. /**
  1475. * End of DLL of unacked transmission requests.
  1476. */
  1477. struct QueueEntry *queue_tail;
  1478. /**
  1479. * Which neighbour is this queue for?
  1480. */
  1481. struct Neighbour *neighbour;
  1482. /**
  1483. * Which communicator offers this queue?
  1484. */
  1485. struct TransportClient *tc;
  1486. /**
  1487. * Address served by the queue.
  1488. */
  1489. const char *address;
  1490. /**
  1491. * Task scheduled for the time when this queue can (likely) transmit the
  1492. * next message.
  1493. */
  1494. struct GNUNET_SCHEDULER_Task *transmit_task;
  1495. /**
  1496. * How long do *we* consider this @e address to be valid? In the past or
  1497. * zero if we have not yet validated it. Can be updated based on
  1498. * challenge-response validations (via address validation logic), or when we
  1499. * receive ACKs that we can definitively map to transmissions via this
  1500. * queue.
  1501. */
  1502. struct GNUNET_TIME_Absolute validated_until;
  1503. /**
  1504. * Performance data for this queue.
  1505. */
  1506. struct PerformanceData pd;
  1507. /**
  1508. * Message ID generator for transmissions on this queue to the
  1509. * communicator.
  1510. */
  1511. uint64_t mid_gen;
  1512. /**
  1513. * Unique identifier of this queue with the communicator.
  1514. */
  1515. uint32_t qid;
  1516. /**
  1517. * Maximum transmission unit supported by this queue.
  1518. */
  1519. uint32_t mtu;
  1520. /**
  1521. * Messages pending.
  1522. */
  1523. uint32_t num_msg_pending;
  1524. /**
  1525. * Bytes pending.
  1526. */
  1527. uint32_t num_bytes_pending;
  1528. /**
  1529. * Length of the DLL starting at @e queue_head.
  1530. */
  1531. unsigned int queue_length;
  1532. /**
  1533. * Network type offered by this queue.
  1534. */
  1535. enum GNUNET_NetworkType nt;
  1536. /**
  1537. * Connection status for this queue.
  1538. */
  1539. enum GNUNET_TRANSPORT_ConnectionStatus cs;
  1540. /**
  1541. * Set to #GNUNET_YES if this queue is idle waiting for some
  1542. * virtual link to give it a pending message.
  1543. */
  1544. int idle;
  1545. };
  1546. /**
  1547. * Information we keep for a message that we are reassembling.
  1548. */
  1549. struct ReassemblyContext
  1550. {
  1551. /**
  1552. * Original message ID for of the message that all the fragments
  1553. * belong to.
  1554. */
  1555. struct MessageUUIDP msg_uuid;
  1556. /**
  1557. * Which neighbour is this context for?
  1558. */
  1559. struct Neighbour *neighbour;
  1560. /**
  1561. * Entry in the reassembly heap (sorted by expiration).
  1562. */
  1563. struct GNUNET_CONTAINER_HeapNode *hn;
  1564. /**
  1565. * Bitfield with @e msg_size bits representing the positions
  1566. * where we have received fragments. When we receive a fragment,
  1567. * we check the bits in @e bitfield before incrementing @e msg_missing.
  1568. *
  1569. * Allocated after the reassembled message.
  1570. */
  1571. uint8_t *bitfield;
  1572. /**
  1573. * At what time will we give up reassembly of this message?
  1574. */
  1575. struct GNUNET_TIME_Absolute reassembly_timeout;
  1576. /**
  1577. * Time we received the last fragment. @e avg_ack_delay must be
  1578. * incremented by now - @e last_frag multiplied by @e num_acks.
  1579. */
  1580. struct GNUNET_TIME_Absolute last_frag;
  1581. /**
  1582. * How big is the message we are reassembling in total?
  1583. */
  1584. uint16_t msg_size;
  1585. /**
  1586. * How many bytes of the message are still missing? Defragmentation
  1587. * is complete when @e msg_missing == 0.
  1588. */
  1589. uint16_t msg_missing;
  1590. /* Followed by @e msg_size bytes of the (partially) defragmented original
  1591. * message */
  1592. /* Followed by @e bitfield data */
  1593. };
  1594. /**
  1595. * A neighbour that at least one communicator is connected to.
  1596. */
  1597. struct Neighbour
  1598. {
  1599. /**
  1600. * Which peer is this about?
  1601. */
  1602. struct GNUNET_PeerIdentity pid;
  1603. /**
  1604. * Map with `struct ReassemblyContext` structs for fragments under
  1605. * reassembly. May be NULL if we currently have no fragments from
  1606. * this @e pid (lazy initialization).
  1607. */
  1608. struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map;
  1609. /**
  1610. * Heap with `struct ReassemblyContext` structs for fragments under
  1611. * reassembly. May be NULL if we currently have no fragments from
  1612. * this @e pid (lazy initialization).
  1613. */
  1614. struct GNUNET_CONTAINER_Heap *reassembly_heap;
  1615. /**
  1616. * Task to free old entries from the @e reassembly_heap and @e reassembly_map.
  1617. */
  1618. struct GNUNET_SCHEDULER_Task *reassembly_timeout_task;
  1619. /**
  1620. * Head of MDLL of DV hops that have this neighbour as next hop. Must be
  1621. * purged if this neighbour goes down.
  1622. */
  1623. struct DistanceVectorHop *dv_head;
  1624. /**
  1625. * Tail of MDLL of DV hops that have this neighbour as next hop. Must be
  1626. * purged if this neighbour goes down.
  1627. */
  1628. struct DistanceVectorHop *dv_tail;
  1629. /**
  1630. * Head of DLL of queues to this peer.
  1631. */
  1632. struct Queue *queue_head;
  1633. /**
  1634. * Tail of DLL of queues to this peer.
  1635. */
  1636. struct Queue *queue_tail;
  1637. /**
  1638. * Handle for an operation to fetch @e last_dv_learn_monotime information from
  1639. * the PEERSTORE, or NULL.
  1640. */
  1641. struct GNUNET_PEERSTORE_IterateContext *get;
  1642. /**
  1643. * Handle to a PEERSTORE store operation to store this @e pid's @e
  1644. * @e last_dv_learn_monotime. NULL if no PEERSTORE operation is pending.
  1645. */
  1646. struct GNUNET_PEERSTORE_StoreContext *sc;
  1647. /**
  1648. * Do we have a confirmed working queue and are thus visible to
  1649. * CORE? If so, this is the virtual link, otherwise NULL.
  1650. */
  1651. struct VirtualLink *vl;
  1652. /**
  1653. * Latest DVLearn monotonic time seen from this peer. Initialized only
  1654. * if @e dl_monotime_available is #GNUNET_YES.
  1655. */
  1656. struct GNUNET_TIME_Absolute last_dv_learn_monotime;
  1657. /**
  1658. * Do we have the lastest value for @e last_dv_learn_monotime from
  1659. * PEERSTORE yet, or are we still waiting for a reply of PEERSTORE?
  1660. */
  1661. int dv_monotime_available;
  1662. };
  1663. /**
  1664. * Another peer attempted to talk to us, we should try to establish
  1665. * a connection in the other direction.
  1666. */
  1667. struct IncomingRequest
  1668. {
  1669. /**
  1670. * Kept in a DLL.
  1671. */
  1672. struct IncomingRequest *next;
  1673. /**
  1674. * Kept in a DLL.
  1675. */
  1676. struct IncomingRequest *prev;
  1677. /**
  1678. * Handle for watching the peerstore for HELLOs for this peer.
  1679. */
  1680. struct GNUNET_PEERSTORE_WatchContext *wc;
  1681. /**
  1682. * Which peer is this about?
  1683. */
  1684. struct GNUNET_PeerIdentity pid;
  1685. };
  1686. /**
  1687. * A peer that an application (client) would like us to talk to directly.
  1688. */
  1689. struct PeerRequest
  1690. {
  1691. /**
  1692. * Which peer is this about?
  1693. */
  1694. struct GNUNET_PeerIdentity pid;
  1695. /**
  1696. * Client responsible for the request.
  1697. */
  1698. struct TransportClient *tc;
  1699. /**
  1700. * Handle for watching the peerstore for HELLOs for this peer.
  1701. */
  1702. struct GNUNET_PEERSTORE_WatchContext *wc;
  1703. /**
  1704. * What kind of performance preference does this @e tc have?
  1705. *
  1706. * TODO: use this!
  1707. */
  1708. enum GNUNET_MQ_PriorityPreferences pk;
  1709. /**
  1710. * How much bandwidth would this @e tc like to see?
  1711. */
  1712. struct GNUNET_BANDWIDTH_Value32NBO bw;
  1713. };
  1714. /**
  1715. * Types of different pending messages.
  1716. */
  1717. enum PendingMessageType
  1718. {
  1719. /**
  1720. * Ordinary message received from the CORE service.
  1721. */
  1722. PMT_CORE = 0,
  1723. /**
  1724. * Fragment box.
  1725. */
  1726. PMT_FRAGMENT_BOX = 1,
  1727. /**
  1728. * Reliability box.
  1729. */
  1730. PMT_RELIABILITY_BOX = 2,
  1731. /**
  1732. * Pending message created during #forward_dv_box().
  1733. */
  1734. PMT_DV_BOX = 3
  1735. };
  1736. /**
  1737. * Transmission request that is awaiting delivery. The original
  1738. * transmission requests from CORE may be too big for some queues.
  1739. * In this case, a *tree* of fragments is created. At each
  1740. * level of the tree, fragments are kept in a DLL ordered by which
  1741. * fragment should be sent next (at the head). The tree is searched
  1742. * top-down, with the original message at the root.
  1743. *
  1744. * To select a node for transmission, first it is checked if the
  1745. * current node's message fits with the MTU. If it does not, we
  1746. * either calculate the next fragment (based on @e frag_off) from the
  1747. * current node, or, if all fragments have already been created,
  1748. * descend to the @e head_frag. Even though the node was already
  1749. * fragmented, the fragment may be too big if the fragment was
  1750. * generated for a queue with a larger MTU. In this case, the node
  1751. * may be fragmented again, thus creating a tree.
  1752. *
  1753. * When acknowledgements for fragments are received, the tree
  1754. * must be pruned, removing those parts that were already
  1755. * acknowledged. When fragments are sent over a reliable
  1756. * channel, they can be immediately removed.
  1757. *
  1758. * If a message is ever fragmented, then the original "full" message
  1759. * is never again transmitted (even if it fits below the MTU), and
  1760. * only (remaining) fragments are sent.
  1761. */
  1762. struct PendingMessage
  1763. {
  1764. /**
  1765. * Kept in a MDLL of messages for this @a vl.
  1766. */
  1767. struct PendingMessage *next_vl;
  1768. /**
  1769. * Kept in a MDLL of messages for this @a vl.
  1770. */
  1771. struct PendingMessage *prev_vl;
  1772. /**
  1773. * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE)
  1774. */
  1775. struct PendingMessage *next_client;
  1776. /**
  1777. * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE)
  1778. */
  1779. struct PendingMessage *prev_client;
  1780. /**
  1781. * Kept in a MDLL of messages from this @a cpm (if @e pmt is
  1782. * #PMT_FRAGMENT_BOx)
  1783. */
  1784. struct PendingMessage *next_frag;
  1785. /**
  1786. * Kept in a MDLL of messages from this @a cpm (if @e pmt is
  1787. * #PMT_FRAGMENT_BOX)
  1788. */
  1789. struct PendingMessage *prev_frag;
  1790. /**
  1791. * Head of DLL of PAs for this pending message.
  1792. */
  1793. struct PendingAcknowledgement *pa_head;
  1794. /**
  1795. * Tail of DLL of PAs for this pending message.
  1796. */
  1797. struct PendingAcknowledgement *pa_tail;
  1798. /**
  1799. * This message, reliability *or* DV-boxed. Only possibly available
  1800. * if @e pmt is #PMT_CORE.
  1801. */
  1802. struct PendingMessage *bpm;
  1803. /**
  1804. * Target of the request (always the ultimate destination!).
  1805. */
  1806. struct VirtualLink *vl;
  1807. /**
  1808. * Set to non-NULL value if this message is currently being given to a
  1809. * communicator and we are awaiting that communicator's acknowledgement.
  1810. * Note that we must not retransmit a pending message while we're still
  1811. * in the process of giving it to a communicator. If a pending message
  1812. * is free'd while this entry is non-NULL, the @e qe reference to us
  1813. * should simply be set to NULL.
  1814. */
  1815. struct QueueEntry *qe;
  1816. /**
  1817. * Client that issued the transmission request, if @e pmt is #PMT_CORE.
  1818. */
  1819. struct TransportClient *client;
  1820. /**
  1821. * Head of a MDLL of fragments created for this core message.
  1822. */
  1823. struct PendingMessage *head_frag;
  1824. /**
  1825. * Tail of a MDLL of fragments created for this core message.
  1826. */
  1827. struct PendingMessage *tail_frag;
  1828. /**
  1829. * Our parent in the fragmentation tree.
  1830. */
  1831. struct PendingMessage *frag_parent;
  1832. /**
  1833. * At what time should we give up on the transmission (and no longer retry)?
  1834. */
  1835. struct GNUNET_TIME_Absolute timeout;
  1836. /**
  1837. * What is the earliest time for us to retry transmission of this message?
  1838. */
  1839. struct GNUNET_TIME_Absolute next_attempt;
  1840. /**
  1841. * UUID to use for this message (used for reassembly of fragments, only
  1842. * initialized if @e msg_uuid_set is #GNUNET_YES).
  1843. */
  1844. struct MessageUUIDP msg_uuid;
  1845. /**
  1846. * UUID we use to identify this message in our logs.
  1847. * Generated by incrementing the "logging_uuid_gen".
  1848. */
  1849. unsigned long long logging_uuid;
  1850. /**
  1851. * Type of the pending message.
  1852. */
  1853. enum PendingMessageType pmt;
  1854. /**
  1855. * Preferences for this message.
  1856. * TODO: actually use this!
  1857. */
  1858. enum GNUNET_MQ_PriorityPreferences prefs;
  1859. /**
  1860. * Size of the original message.
  1861. */
  1862. uint16_t bytes_msg;
  1863. /**
  1864. * Offset at which we should generate the next fragment.
  1865. */
  1866. uint16_t frag_off;
  1867. /**
  1868. * #GNUNET_YES once @e msg_uuid was initialized
  1869. */
  1870. int16_t msg_uuid_set;
  1871. /* Followed by @e bytes_msg to transmit */
  1872. };
  1873. /**
  1874. * Acknowledgement payload.
  1875. */
  1876. struct TransportCummulativeAckPayload
  1877. {
  1878. /**
  1879. * When did we receive the message we are ACKing? Used to calculate
  1880. * the delay we introduced by cummulating ACKs.
  1881. */
  1882. struct GNUNET_TIME_Absolute receive_time;
  1883. /**
  1884. * UUID of a message being acknowledged.
  1885. */
  1886. struct AcknowledgementUUIDP ack_uuid;
  1887. };
  1888. /**
  1889. * Data structure in which we track acknowledgements still to
  1890. * be sent to the
  1891. */
  1892. struct AcknowledgementCummulator
  1893. {
  1894. /**
  1895. * Target peer for which we are accumulating ACKs here.
  1896. */
  1897. struct GNUNET_PeerIdentity target;
  1898. /**
  1899. * ACK data being accumulated. Only @e num_acks slots are valid.
  1900. */
  1901. struct TransportCummulativeAckPayload ack_uuids[MAX_CUMMULATIVE_ACKS];
  1902. /**
  1903. * Task scheduled either to transmit the cummulative ACK message,
  1904. * or to clean up this data structure after extended periods of
  1905. * inactivity (if @e num_acks is zero).
  1906. */
  1907. struct GNUNET_SCHEDULER_Task *task;
  1908. /**
  1909. * When is @e task run (only used if @e num_acks is non-zero)?
  1910. */
  1911. struct GNUNET_TIME_Absolute min_transmission_time;
  1912. /**
  1913. * Counter to produce the `ack_counter` in the `struct
  1914. * TransportReliabilityAckMessage`. Allows the receiver to detect
  1915. * lost ACK messages. Incremented by @e num_acks upon transmission.
  1916. */
  1917. uint32_t ack_counter;
  1918. /**
  1919. * Number of entries used in @e ack_uuids. Reset to 0 upon transmission.
  1920. */
  1921. unsigned int num_acks;
  1922. };
  1923. /**
  1924. * One of the addresses of this peer.
  1925. */
  1926. struct AddressListEntry
  1927. {
  1928. /**
  1929. * Kept in a DLL.
  1930. */
  1931. struct AddressListEntry *next;
  1932. /**
  1933. * Kept in a DLL.
  1934. */
  1935. struct AddressListEntry *prev;
  1936. /**
  1937. * Which communicator provides this address?
  1938. */
  1939. struct TransportClient *tc;
  1940. /**
  1941. * The actual address.
  1942. */
  1943. const char *address;
  1944. /**
  1945. * Current context for storing this address in the peerstore.
  1946. */
  1947. struct GNUNET_PEERSTORE_StoreContext *sc;
  1948. /**
  1949. * Task to periodically do @e st operation.
  1950. */
  1951. struct GNUNET_SCHEDULER_Task *st;
  1952. /**
  1953. * What is a typical lifetime the communicator expects this
  1954. * address to have? (Always from now.)
  1955. */
  1956. struct GNUNET_TIME_Relative expiration;
  1957. /**
  1958. * Address identifier used by the communicator.
  1959. */
  1960. uint32_t aid;
  1961. /**
  1962. * Network type offered by this address.
  1963. */
  1964. enum GNUNET_NetworkType nt;
  1965. };
  1966. /**
  1967. * Client connected to the transport service.
  1968. */
  1969. struct TransportClient
  1970. {
  1971. /**
  1972. * Kept in a DLL.
  1973. */
  1974. struct TransportClient *next;
  1975. /**
  1976. * Kept in a DLL.
  1977. */
  1978. struct TransportClient *prev;
  1979. /**
  1980. * Handle to the client.
  1981. */
  1982. struct GNUNET_SERVICE_Client *client;
  1983. /**
  1984. * Message queue to the client.
  1985. */
  1986. struct GNUNET_MQ_Handle *mq;
  1987. /**
  1988. * What type of client is this?
  1989. */
  1990. enum ClientType type;
  1991. union
  1992. {
  1993. /**
  1994. * Information for @e type #CT_CORE.
  1995. */
  1996. struct
  1997. {
  1998. /**
  1999. * Head of list of messages pending for this client, sorted by
  2000. * transmission time ("next_attempt" + possibly internal prioritization).
  2001. */
  2002. struct PendingMessage *pending_msg_head;
  2003. /**
  2004. * Tail of list of messages pending for this client.
  2005. */
  2006. struct PendingMessage *pending_msg_tail;
  2007. } core;
  2008. /**
  2009. * Information for @e type #CT_MONITOR.
  2010. */
  2011. struct
  2012. {
  2013. /**
  2014. * Peer identity to monitor the addresses of.
  2015. * Zero to monitor all neighbours. Valid if
  2016. * @e type is #CT_MONITOR.
  2017. */
  2018. struct GNUNET_PeerIdentity peer;
  2019. /**
  2020. * Is this a one-shot monitor?
  2021. */
  2022. int one_shot;
  2023. } monitor;
  2024. /**
  2025. * Information for @e type #CT_COMMUNICATOR.
  2026. */
  2027. struct
  2028. {
  2029. /**
  2030. * If @e type is #CT_COMMUNICATOR, this communicator
  2031. * supports communicating using these addresses.
  2032. */
  2033. char *address_prefix;
  2034. /**
  2035. * Head of DLL of queues offered by this communicator.
  2036. */
  2037. struct Queue *queue_head;
  2038. /**
  2039. * Tail of DLL of queues offered by this communicator.
  2040. */
  2041. struct Queue *queue_tail;
  2042. /**
  2043. * Head of list of the addresses of this peer offered by this
  2044. * communicator.
  2045. */
  2046. struct AddressListEntry *addr_head;
  2047. /**
  2048. * Tail of list of the addresses of this peer offered by this
  2049. * communicator.
  2050. */
  2051. struct AddressListEntry *addr_tail;
  2052. /**
  2053. * Number of queue entries in all queues to this communicator. Used
  2054. * throttle sending to a communicator if we see that the communicator
  2055. * is globally unable to keep up.
  2056. */
  2057. unsigned int total_queue_length;
  2058. /**
  2059. * Characteristics of this communicator.
  2060. */
  2061. enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
  2062. } communicator;
  2063. /**
  2064. * Information for @e type #CT_APPLICATION
  2065. */
  2066. struct
  2067. {
  2068. /**
  2069. * Map of requests for peers the given client application would like to
  2070. * see connections for. Maps from PIDs to `struct PeerRequest`.
  2071. */
  2072. struct GNUNET_CONTAINER_MultiPeerMap *requests;
  2073. } application;
  2074. } details;
  2075. };
  2076. /**
  2077. * State we keep for validation activities. Each of these
  2078. * is both in the #validation_heap and the #validation_map.
  2079. */
  2080. struct ValidationState
  2081. {
  2082. /**
  2083. * For which peer is @a address to be validated (or possibly valid)?
  2084. * Serves as key in the #validation_map.
  2085. */
  2086. struct GNUNET_PeerIdentity pid;
  2087. /**
  2088. * How long did the peer claim this @e address to be valid? Capped at
  2089. * minimum of #MAX_ADDRESS_VALID_UNTIL relative to the time where we last
  2090. * were told about the address and the value claimed by the other peer at
  2091. * that time. May be updated similarly when validation succeeds.
  2092. */
  2093. struct GNUNET_TIME_Absolute valid_until;
  2094. /**
  2095. * How long do *we* consider this @e address to be valid?
  2096. * In the past or zero if we have not yet validated it.
  2097. */
  2098. struct GNUNET_TIME_Absolute validated_until;
  2099. /**
  2100. * When did we FIRST use the current @e challenge in a message?
  2101. * Used to sanity-check @code{origin_time} in the response when
  2102. * calculating the RTT. If the @code{origin_time} is not in
  2103. * the expected range, the response is discarded as malicious.
  2104. */
  2105. struct GNUNET_TIME_Absolute first_challenge_use;
  2106. /**
  2107. * When did we LAST use the current @e challenge in a message?
  2108. * Used to sanity-check @code{origin_time} in the response when
  2109. * calculating the RTT. If the @code{origin_time} is not in
  2110. * the expected range, the response is discarded as malicious.
  2111. */
  2112. struct GNUNET_TIME_Absolute last_challenge_use;
  2113. /**
  2114. * Next time we will send the @e challenge to the peer, if this time is past
  2115. * @e valid_until, this validation state is released at this time. If the
  2116. * address is valid, @e next_challenge is set to @e validated_until MINUS @e
  2117. * validation_delay * #VALIDATION_RTT_BUFFER_FACTOR, such that we will try
  2118. * to re-validate before the validity actually expires.
  2119. */
  2120. struct GNUNET_TIME_Absolute next_challenge;
  2121. /**
  2122. * Current backoff factor we're applying for sending the @a challenge.
  2123. * Reset to 0 if the @a challenge is confirmed upon validation.
  2124. * Reduced to minimum of #FAST_VALIDATION_CHALLENGE_FREQ and half of the
  2125. * existing value if we receive an unvalidated address again over
  2126. * another channel (and thus should consider the information "fresh").
  2127. * Maximum is #MAX_VALIDATION_CHALLENGE_FREQ.
  2128. */
  2129. struct GNUNET_TIME_Relative challenge_backoff;
  2130. /**
  2131. * Initially set to "forever". Once @e validated_until is set, this value is
  2132. * set to the RTT that tells us how long it took to receive the validation.
  2133. */
  2134. struct GNUNET_TIME_Relative validation_rtt;
  2135. /**
  2136. * The challenge we sent to the peer to get it to validate the address. Note
  2137. * that we rotate the challenge whenever we update @e validated_until to
  2138. * avoid attacks where a peer simply replays an old challenge in the future.
  2139. * (We must not rotate more often as otherwise we may discard valid answers
  2140. * due to packet losses, latency and reorderings on the network).
  2141. */
  2142. struct ChallengeNonceP challenge;
  2143. /**
  2144. * Claimed address of the peer.
  2145. */
  2146. char *address;
  2147. /**
  2148. * Entry in the #validation_heap, which is sorted by @e next_challenge. The
  2149. * heap is used to figure out when the next validation activity should be
  2150. * run.
  2151. */
  2152. struct GNUNET_CONTAINER_HeapNode *hn;
  2153. /**
  2154. * Handle to a PEERSTORE store operation for this @e address. NULL if
  2155. * no PEERSTORE operation is pending.
  2156. */
  2157. struct GNUNET_PEERSTORE_StoreContext *sc;
  2158. /**
  2159. * Self-imposed limit on the previous flow control window. (May be zero,
  2160. * if we never used data from the previous window or are establishing the
  2161. * connection for the first time).
  2162. */
  2163. uint32_t last_window_consum_limit;
  2164. /**
  2165. * We are technically ready to send the challenge, but we are waiting for
  2166. * the respective queue to become available for transmission.
  2167. */
  2168. int awaiting_queue;
  2169. };
  2170. /**
  2171. * A Backtalker is a peer sending us backchannel messages. We use this
  2172. * struct to detect monotonic time violations, cache ephemeral key
  2173. * material (to avoid repeatedly checking signatures), and to synchronize
  2174. * monotonic time with the PEERSTORE.
  2175. */
  2176. struct Backtalker
  2177. {
  2178. /**
  2179. * Peer this is about.
  2180. */
  2181. struct GNUNET_PeerIdentity pid;
  2182. /**
  2183. * Last (valid) monotonic time received from this sender.
  2184. */
  2185. struct GNUNET_TIME_Absolute monotonic_time;
  2186. /**
  2187. * When will this entry time out?
  2188. */
  2189. struct GNUNET_TIME_Absolute timeout;
  2190. /**
  2191. * Last (valid) ephemeral key received from this sender.
  2192. */
  2193. struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral;
  2194. /**
  2195. * Task associated with this backtalker. Can be for timeout,
  2196. * or other asynchronous operations.
  2197. */
  2198. struct GNUNET_SCHEDULER_Task *task;
  2199. /**
  2200. * Communicator context waiting on this backchannel's @e get, or NULL.
  2201. */
  2202. struct CommunicatorMessageContext *cmc;
  2203. /**
  2204. * Handle for an operation to fetch @e monotonic_time information from the
  2205. * PEERSTORE, or NULL.
  2206. */
  2207. struct GNUNET_PEERSTORE_IterateContext *get;
  2208. /**
  2209. * Handle to a PEERSTORE store operation for this @e pid's @e
  2210. * monotonic_time. NULL if no PEERSTORE operation is pending.
  2211. */
  2212. struct GNUNET_PEERSTORE_StoreContext *sc;
  2213. /**
  2214. * Number of bytes of the original message body that follows after this
  2215. * struct.
  2216. */
  2217. size_t body_size;
  2218. };
  2219. /**
  2220. * Head of linked list of all clients to this service.
  2221. */
  2222. static struct TransportClient *clients_head;
  2223. /**
  2224. * Tail of linked list of all clients to this service.
  2225. */
  2226. static struct TransportClient *clients_tail;
  2227. /**
  2228. * Statistics handle.
  2229. */
  2230. static struct GNUNET_STATISTICS_Handle *GST_stats;
  2231. /**
  2232. * Configuration handle.
  2233. */
  2234. static const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
  2235. /**
  2236. * Our public key.
  2237. */
  2238. static struct GNUNET_PeerIdentity GST_my_identity;
  2239. /**
  2240. * Our private key.
  2241. */
  2242. static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
  2243. /**
  2244. * Map from PIDs to `struct Neighbour` entries. A peer is
  2245. * a neighbour if we have an MQ to it from some communicator.
  2246. */
  2247. static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
  2248. /**
  2249. * Map from PIDs to `struct Backtalker` entries. A peer is
  2250. * a backtalker if it recently send us backchannel messages.
  2251. */
  2252. static struct GNUNET_CONTAINER_MultiPeerMap *backtalkers;
  2253. /**
  2254. * Map from PIDs to `struct AcknowledgementCummulator`s.
  2255. * Here we track the cummulative ACKs for transmission.
  2256. */
  2257. static struct GNUNET_CONTAINER_MultiPeerMap *ack_cummulators;
  2258. /**
  2259. * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to
  2260. * a `struct PendingAcknowledgement`.
  2261. */
  2262. static struct GNUNET_CONTAINER_MultiUuidmap *pending_acks;
  2263. /**
  2264. * Map from PIDs to `struct DistanceVector` entries describing
  2265. * known paths to the peer.
  2266. */
  2267. static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes;
  2268. /**
  2269. * Map from PIDs to `struct ValidationState` entries describing
  2270. * addresses we are aware of and their validity state.
  2271. */
  2272. static struct GNUNET_CONTAINER_MultiPeerMap *validation_map;
  2273. /**
  2274. * Map from PIDs to `struct VirtualLink` entries describing
  2275. * links CORE knows to exist.
  2276. */
  2277. static struct GNUNET_CONTAINER_MultiPeerMap *links;
  2278. /**
  2279. * Map from challenges to `struct LearnLaunchEntry` values.
  2280. */
  2281. static struct GNUNET_CONTAINER_MultiShortmap *dvlearn_map;
  2282. /**
  2283. * Head of a DLL sorted by launch time.
  2284. */
  2285. static struct LearnLaunchEntry *lle_head;
  2286. /**
  2287. * Tail of a DLL sorted by launch time.
  2288. */
  2289. static struct LearnLaunchEntry *lle_tail;
  2290. /**
  2291. * MIN Heap sorted by "next_challenge" to `struct ValidationState` entries
  2292. * sorting addresses we are aware of by when we should next try to (re)validate
  2293. * (or expire) them.
  2294. */
  2295. static struct GNUNET_CONTAINER_Heap *validation_heap;
  2296. /**
  2297. * Database for peer's HELLOs.
  2298. */
  2299. static struct GNUNET_PEERSTORE_Handle *peerstore;
  2300. /**
  2301. * Task run to initiate DV learning.
  2302. */
  2303. static struct GNUNET_SCHEDULER_Task *dvlearn_task;
  2304. /**
  2305. * Task to run address validation.
  2306. */
  2307. static struct GNUNET_SCHEDULER_Task *validation_task;
  2308. /**
  2309. * The most recent PA we have created, head of DLL.
  2310. * The length of the DLL is kept in #pa_count.
  2311. */
  2312. static struct PendingAcknowledgement *pa_head;
  2313. /**
  2314. * The oldest PA we have created, tail of DLL.
  2315. * The length of the DLL is kept in #pa_count.
  2316. */
  2317. static struct PendingAcknowledgement *pa_tail;
  2318. /**
  2319. * List of incomming connections where we are trying
  2320. * to get a connection back established. Length
  2321. * kept in #ir_total.
  2322. */
  2323. static struct IncomingRequest *ir_head;
  2324. /**
  2325. * Tail of DLL starting at #ir_head.
  2326. */
  2327. static struct IncomingRequest *ir_tail;
  2328. /**
  2329. * Length of the DLL starting at #ir_head.
  2330. */
  2331. static unsigned int ir_total;
  2332. /**
  2333. * Generator of `logging_uuid` in `struct PendingMessage`.
  2334. */
  2335. static unsigned long long logging_uuid_gen;
  2336. /**
  2337. * Number of entries in the #pa_head/#pa_tail DLL. Used to
  2338. * limit the size of the data structure.
  2339. */
  2340. static unsigned int pa_count;
  2341. /**
  2342. * Monotonic time we use for HELLOs generated at this time. TODO: we
  2343. * should increase this value from time to time (i.e. whenever a
  2344. * `struct AddressListEntry` actually expires), but IF we do this, we
  2345. * must also update *all* (remaining) addresses in the PEERSTORE at
  2346. * that time! (So for now only increased when the peer is restarted,
  2347. * which hopefully roughly matches whenever our addresses change.)
  2348. */
  2349. static struct GNUNET_TIME_Absolute hello_mono_time;
  2350. /**
  2351. * Get an offset into the transmission history buffer for `struct
  2352. * PerformanceData`. Note that the caller must perform the required
  2353. * modulo #GOODPUT_AGING_SLOTS operation before indexing into the
  2354. * array!
  2355. *
  2356. * An 'age' lasts 15 minute slots.
  2357. *
  2358. * @return current age of the world
  2359. */
  2360. static unsigned int
  2361. get_age ()
  2362. {
  2363. struct GNUNET_TIME_Absolute now;
  2364. now = GNUNET_TIME_absolute_get ();
  2365. return now.abs_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us / 15;
  2366. }
  2367. /**
  2368. * Release @a ir data structure.
  2369. *
  2370. * @param ir data structure to release
  2371. */
  2372. static void
  2373. free_incoming_request (struct IncomingRequest *ir)
  2374. {
  2375. GNUNET_CONTAINER_DLL_remove (ir_head, ir_tail, ir);
  2376. GNUNET_assert (ir_total > 0);
  2377. ir_total--;
  2378. GNUNET_PEERSTORE_watch_cancel (ir->wc);
  2379. GNUNET_free (ir);
  2380. }
  2381. /**
  2382. * Release @a pa data structure.
  2383. *
  2384. * @param pa data structure to release
  2385. */
  2386. static void
  2387. free_pending_acknowledgement (struct PendingAcknowledgement *pa)
  2388. {
  2389. struct Queue *q = pa->queue;
  2390. struct PendingMessage *pm = pa->pm;
  2391. struct DistanceVectorHop *dvh = pa->dvh;
  2392. GNUNET_CONTAINER_MDLL_remove (pa, pa_head, pa_tail, pa);
  2393. pa_count--;
  2394. if (NULL != q)
  2395. {
  2396. GNUNET_CONTAINER_MDLL_remove (queue, q->pa_head, q->pa_tail, pa);
  2397. pa->queue = NULL;
  2398. }
  2399. if (NULL != pm)
  2400. {
  2401. GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa);
  2402. pa->pm = NULL;
  2403. }
  2404. if (NULL != dvh)
  2405. {
  2406. GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa);
  2407. pa->queue = NULL;
  2408. }
  2409. GNUNET_assert (GNUNET_YES ==
  2410. GNUNET_CONTAINER_multiuuidmap_remove (pending_acks,
  2411. &pa->ack_uuid.value,
  2412. pa));
  2413. GNUNET_free (pa);
  2414. }
  2415. /**
  2416. * Free fragment tree below @e root, excluding @e root itself.
  2417. * FIXME: this does NOT seem to have the intended semantics
  2418. * based on how this is called. Seems we generally DO expect
  2419. * @a root to be free'ed itself as well!
  2420. *
  2421. * @param root root of the tree to free
  2422. */
  2423. static void
  2424. free_fragment_tree (struct PendingMessage *root)
  2425. {
  2426. struct PendingMessage *frag;
  2427. while (NULL != (frag = root->head_frag))
  2428. {
  2429. struct PendingAcknowledgement *pa;
  2430. free_fragment_tree (frag);
  2431. while (NULL != (pa = frag->pa_head))
  2432. {
  2433. GNUNET_CONTAINER_MDLL_remove (pm, frag->pa_head, frag->pa_tail, pa);
  2434. pa->pm = NULL;
  2435. }
  2436. GNUNET_CONTAINER_MDLL_remove (frag, root->head_frag, root->tail_frag, frag);
  2437. GNUNET_free (frag);
  2438. }
  2439. }
  2440. /**
  2441. * Release memory associated with @a pm and remove @a pm from associated
  2442. * data structures. @a pm must be a top-level pending message and not
  2443. * a fragment in the tree. The entire tree is freed (if applicable).
  2444. *
  2445. * @param pm the pending message to free
  2446. */
  2447. static void
  2448. free_pending_message (struct PendingMessage *pm)
  2449. {
  2450. struct TransportClient *tc = pm->client;
  2451. struct VirtualLink *vl = pm->vl;
  2452. struct PendingAcknowledgement *pa;
  2453. if (NULL != tc)
  2454. {
  2455. GNUNET_CONTAINER_MDLL_remove (client,
  2456. tc->details.core.pending_msg_head,
  2457. tc->details.core.pending_msg_tail,
  2458. pm);
  2459. }
  2460. if (NULL != vl)
  2461. {
  2462. GNUNET_CONTAINER_MDLL_remove (vl,
  2463. vl->pending_msg_head,
  2464. vl->pending_msg_tail,
  2465. pm);
  2466. }
  2467. while (NULL != (pa = pm->pa_head))
  2468. {
  2469. GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa);
  2470. pa->pm = NULL;
  2471. }
  2472. free_fragment_tree (pm);
  2473. if (NULL != pm->qe)
  2474. {
  2475. GNUNET_assert (pm == pm->qe->pm);
  2476. pm->qe->pm = NULL;
  2477. }
  2478. if (NULL != pm->bpm)
  2479. {
  2480. free_fragment_tree (pm->bpm);
  2481. GNUNET_free (pm->bpm);
  2482. }
  2483. GNUNET_free (pm);
  2484. }
  2485. /**
  2486. * Free virtual link.
  2487. *
  2488. * @param vl link data to free
  2489. */
  2490. static void
  2491. free_virtual_link (struct VirtualLink *vl)
  2492. {
  2493. struct PendingMessage *pm;
  2494. struct CoreSentContext *csc;
  2495. while (NULL != (pm = vl->pending_msg_head))
  2496. free_pending_message (pm);
  2497. GNUNET_assert (GNUNET_YES ==
  2498. GNUNET_CONTAINER_multipeermap_remove (links, &vl->target, vl));
  2499. if (NULL != vl->visibility_task)
  2500. {
  2501. GNUNET_SCHEDULER_cancel (vl->visibility_task);
  2502. vl->visibility_task = NULL;
  2503. }
  2504. if (NULL != vl->fc_retransmit_task)
  2505. {
  2506. GNUNET_SCHEDULER_cancel (vl->fc_retransmit_task);
  2507. vl->fc_retransmit_task = NULL;
  2508. }
  2509. while (NULL != (csc = vl->csc_head))
  2510. {
  2511. GNUNET_CONTAINER_DLL_remove (vl->csc_head, vl->csc_tail, csc);
  2512. GNUNET_assert (vl == csc->vl);
  2513. csc->vl = NULL;
  2514. }
  2515. GNUNET_break (NULL == vl->n);
  2516. GNUNET_break (NULL == vl->dv);
  2517. GNUNET_free (vl);
  2518. }
  2519. /**
  2520. * Free validation state.
  2521. *
  2522. * @param vs validation state to free
  2523. */
  2524. static void
  2525. free_validation_state (struct ValidationState *vs)
  2526. {
  2527. GNUNET_assert (
  2528. GNUNET_YES ==
  2529. GNUNET_CONTAINER_multipeermap_remove (validation_map, &vs->pid, vs));
  2530. GNUNET_CONTAINER_heap_remove_node (vs->hn);
  2531. vs->hn = NULL;
  2532. if (NULL != vs->sc)
  2533. {
  2534. GNUNET_PEERSTORE_store_cancel (vs->sc);
  2535. vs->sc = NULL;
  2536. }
  2537. GNUNET_free (vs->address);
  2538. GNUNET_free (vs);
  2539. }
  2540. /**
  2541. * Lookup neighbour for peer @a pid.
  2542. *
  2543. * @param pid neighbour to look for
  2544. * @return NULL if we do not have this peer as a neighbour
  2545. */
  2546. static struct Neighbour *
  2547. lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
  2548. {
  2549. return GNUNET_CONTAINER_multipeermap_get (neighbours, pid);
  2550. }
  2551. /**
  2552. * Lookup virtual link for peer @a pid.
  2553. *
  2554. * @param pid virtual link to look for
  2555. * @return NULL if we do not have this peer as a virtual link
  2556. */
  2557. static struct VirtualLink *
  2558. lookup_virtual_link (const struct GNUNET_PeerIdentity *pid)
  2559. {
  2560. return GNUNET_CONTAINER_multipeermap_get (links, pid);
  2561. }
  2562. /**
  2563. * Details about what to notify monitors about.
  2564. */
  2565. struct MonitorEvent
  2566. {
  2567. /**
  2568. * @deprecated To be discussed if we keep these...
  2569. */
  2570. struct GNUNET_TIME_Absolute last_validation;
  2571. struct GNUNET_TIME_Absolute valid_until;
  2572. struct GNUNET_TIME_Absolute next_validation;
  2573. /**
  2574. * Current round-trip time estimate.
  2575. */
  2576. struct GNUNET_TIME_Relative rtt;
  2577. /**
  2578. * Connection status.
  2579. */
  2580. enum GNUNET_TRANSPORT_ConnectionStatus cs;
  2581. /**
  2582. * Messages pending.
  2583. */
  2584. uint32_t num_msg_pending;
  2585. /**
  2586. * Bytes pending.
  2587. */
  2588. uint32_t num_bytes_pending;
  2589. };
  2590. /**
  2591. * Free a @dvh. Callers MAY want to check if this was the last path to the
  2592. * `target`, and if so call #free_dv_route to also free the associated DV
  2593. * entry in #dv_routes (if not, the associated scheduler job should eventually
  2594. * take care of it).
  2595. *
  2596. * @param dvh hop to free
  2597. */
  2598. static void
  2599. free_distance_vector_hop (struct DistanceVectorHop *dvh)
  2600. {
  2601. struct Neighbour *n = dvh->next_hop;
  2602. struct DistanceVector *dv = dvh->dv;
  2603. struct PendingAcknowledgement *pa;
  2604. while (NULL != (pa = dvh->pa_head))
  2605. {
  2606. GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa);
  2607. pa->dvh = NULL;
  2608. }
  2609. GNUNET_CONTAINER_MDLL_remove (neighbour, n->dv_head, n->dv_tail, dvh);
  2610. GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, dvh);
  2611. GNUNET_free (dvh);
  2612. }
  2613. /**
  2614. * Task run to check whether the hops of the @a cls still
  2615. * are validated, or if we need to core about disconnection.
  2616. *
  2617. * @param cls a `struct VirtualLink`
  2618. */
  2619. static void
  2620. check_link_down (void *cls);
  2621. /**
  2622. * Send message to CORE clients that we lost a connection.
  2623. *
  2624. * @param pid peer the connection was for
  2625. */
  2626. static void
  2627. cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid)
  2628. {
  2629. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2630. "Informing CORE clients about disconnect from %s\n",
  2631. GNUNET_i2s (pid));
  2632. for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
  2633. {
  2634. struct GNUNET_MQ_Envelope *env;
  2635. struct DisconnectInfoMessage *dim;
  2636. if (CT_CORE != tc->type)
  2637. continue;
  2638. env = GNUNET_MQ_msg (dim, GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
  2639. dim->peer = *pid;
  2640. GNUNET_MQ_send (tc->mq, env);
  2641. }
  2642. }
  2643. /**
  2644. * Free entry in #dv_routes. First frees all hops to the target, and
  2645. * if there are no entries left, frees @a dv as well.
  2646. *
  2647. * @param dv route to free
  2648. */
  2649. static void
  2650. free_dv_route (struct DistanceVector *dv)
  2651. {
  2652. struct DistanceVectorHop *dvh;
  2653. while (NULL != (dvh = dv->dv_head))
  2654. free_distance_vector_hop (dvh);
  2655. if (NULL == dv->dv_head)
  2656. {
  2657. struct VirtualLink *vl;
  2658. GNUNET_assert (
  2659. GNUNET_YES ==
  2660. GNUNET_CONTAINER_multipeermap_remove (dv_routes, &dv->target, dv));
  2661. if (NULL != (vl = dv->vl))
  2662. {
  2663. GNUNET_assert (dv == vl->dv);
  2664. vl->dv = NULL;
  2665. if (NULL == vl->n)
  2666. {
  2667. cores_send_disconnect_info (&dv->target);
  2668. free_virtual_link (vl);
  2669. }
  2670. else
  2671. {
  2672. GNUNET_SCHEDULER_cancel (vl->visibility_task);
  2673. vl->visibility_task = GNUNET_SCHEDULER_add_now (&check_link_down, vl);
  2674. }
  2675. dv->vl = NULL;
  2676. }
  2677. if (NULL != dv->timeout_task)
  2678. {
  2679. GNUNET_SCHEDULER_cancel (dv->timeout_task);
  2680. dv->timeout_task = NULL;
  2681. }
  2682. GNUNET_free (dv);
  2683. }
  2684. }
  2685. /**
  2686. * Notify monitor @a tc about an event. That @a tc
  2687. * cares about the event has already been checked.
  2688. *
  2689. * Send @a tc information in @a me about a @a peer's status with
  2690. * respect to some @a address to all monitors that care.
  2691. *
  2692. * @param tc monitor to inform
  2693. * @param peer peer the information is about
  2694. * @param address address the information is about
  2695. * @param nt network type associated with @a address
  2696. * @param me detailed information to transmit
  2697. */
  2698. static void
  2699. notify_monitor (struct TransportClient *tc,
  2700. const struct GNUNET_PeerIdentity *peer,
  2701. const char *address,
  2702. enum GNUNET_NetworkType nt,
  2703. const struct MonitorEvent *me)
  2704. {
  2705. struct GNUNET_MQ_Envelope *env;
  2706. struct GNUNET_TRANSPORT_MonitorData *md;
  2707. size_t addr_len = strlen (address) + 1;
  2708. env = GNUNET_MQ_msg_extra (md,
  2709. addr_len,
  2710. GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_DATA);
  2711. md->nt = htonl ((uint32_t) nt);
  2712. md->peer = *peer;
  2713. md->last_validation = GNUNET_TIME_absolute_hton (me->last_validation);
  2714. md->valid_until = GNUNET_TIME_absolute_hton (me->valid_until);
  2715. md->next_validation = GNUNET_TIME_absolute_hton (me->next_validation);
  2716. md->rtt = GNUNET_TIME_relative_hton (me->rtt);
  2717. md->cs = htonl ((uint32_t) me->cs);
  2718. md->num_msg_pending = htonl (me->num_msg_pending);
  2719. md->num_bytes_pending = htonl (me->num_bytes_pending);
  2720. memcpy (&md[1], address, addr_len);
  2721. GNUNET_MQ_send (tc->mq, env);
  2722. }
  2723. /**
  2724. * Send information in @a me about a @a peer's status with respect
  2725. * to some @a address to all monitors that care.
  2726. *
  2727. * @param peer peer the information is about
  2728. * @param address address the information is about
  2729. * @param nt network type associated with @a address
  2730. * @param me detailed information to transmit
  2731. */
  2732. static void
  2733. notify_monitors (const struct GNUNET_PeerIdentity *peer,
  2734. const char *address,
  2735. enum GNUNET_NetworkType nt,
  2736. const struct MonitorEvent *me)
  2737. {
  2738. for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
  2739. {
  2740. if (CT_MONITOR != tc->type)
  2741. continue;
  2742. if (tc->details.monitor.one_shot)
  2743. continue;
  2744. if ((0 != GNUNET_is_zero (&tc->details.monitor.peer)) &&
  2745. (0 != GNUNET_memcmp (&tc->details.monitor.peer, peer)))
  2746. continue;
  2747. notify_monitor (tc, peer, address, nt, me);
  2748. }
  2749. }
  2750. /**
  2751. * Called whenever a client connects. Allocates our
  2752. * data structures associated with that client.
  2753. *
  2754. * @param cls closure, NULL
  2755. * @param client identification of the client
  2756. * @param mq message queue for the client
  2757. * @return our `struct TransportClient`
  2758. */
  2759. static void *
  2760. client_connect_cb (void *cls,
  2761. struct GNUNET_SERVICE_Client *client,
  2762. struct GNUNET_MQ_Handle *mq)
  2763. {
  2764. struct TransportClient *tc;
  2765. (void) cls;
  2766. tc = GNUNET_new (struct TransportClient);
  2767. tc->client = client;
  2768. tc->mq = mq;
  2769. GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
  2770. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", tc);
  2771. return tc;
  2772. }
  2773. /**
  2774. * Free @a rc
  2775. *
  2776. * @param rc data structure to free
  2777. */
  2778. static void
  2779. free_reassembly_context (struct ReassemblyContext *rc)
  2780. {
  2781. struct Neighbour *n = rc->neighbour;
  2782. GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
  2783. GNUNET_assert (GNUNET_OK ==
  2784. GNUNET_CONTAINER_multihashmap32_remove (n->reassembly_map,
  2785. rc->msg_uuid.uuid,
  2786. rc));
  2787. GNUNET_free (rc);
  2788. }
  2789. /**
  2790. * Task run to clean up reassembly context of a neighbour that have expired.
  2791. *
  2792. * @param cls a `struct Neighbour`
  2793. */
  2794. static void
  2795. reassembly_cleanup_task (void *cls)
  2796. {
  2797. struct Neighbour *n = cls;
  2798. struct ReassemblyContext *rc;
  2799. n->reassembly_timeout_task = NULL;
  2800. while (NULL != (rc = GNUNET_CONTAINER_heap_peek (n->reassembly_heap)))
  2801. {
  2802. if (0 == GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)
  2803. .rel_value_us)
  2804. {
  2805. free_reassembly_context (rc);
  2806. continue;
  2807. }
  2808. GNUNET_assert (NULL == n->reassembly_timeout_task);
  2809. n->reassembly_timeout_task =
  2810. GNUNET_SCHEDULER_add_at (rc->reassembly_timeout,
  2811. &reassembly_cleanup_task,
  2812. n);
  2813. return;
  2814. }
  2815. }
  2816. /**
  2817. * function called to #free_reassembly_context().
  2818. *
  2819. * @param cls NULL
  2820. * @param key unused
  2821. * @param value a `struct ReassemblyContext` to free
  2822. * @return #GNUNET_OK (continue iteration)
  2823. */
  2824. static int
  2825. free_reassembly_cb (void *cls, uint32_t key, void *value)
  2826. {
  2827. struct ReassemblyContext *rc = value;
  2828. (void) cls;
  2829. (void) key;
  2830. free_reassembly_context (rc);
  2831. return GNUNET_OK;
  2832. }
  2833. /**
  2834. * Release memory used by @a neighbour.
  2835. *
  2836. * @param neighbour neighbour entry to free
  2837. */
  2838. static void
  2839. free_neighbour (struct Neighbour *neighbour)
  2840. {
  2841. struct DistanceVectorHop *dvh;
  2842. struct VirtualLink *vl;
  2843. GNUNET_assert (NULL == neighbour->queue_head);
  2844. GNUNET_assert (GNUNET_YES ==
  2845. GNUNET_CONTAINER_multipeermap_remove (neighbours,
  2846. &neighbour->pid,
  2847. neighbour));
  2848. if (NULL != neighbour->reassembly_map)
  2849. {
  2850. GNUNET_CONTAINER_multihashmap32_iterate (neighbour->reassembly_map,
  2851. &free_reassembly_cb,
  2852. NULL);
  2853. GNUNET_CONTAINER_multihashmap32_destroy (neighbour->reassembly_map);
  2854. neighbour->reassembly_map = NULL;
  2855. GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap);
  2856. neighbour->reassembly_heap = NULL;
  2857. }
  2858. while (NULL != (dvh = neighbour->dv_head))
  2859. {
  2860. struct DistanceVector *dv = dvh->dv;
  2861. free_distance_vector_hop (dvh);
  2862. if (NULL == dv->dv_head)
  2863. free_dv_route (dv);
  2864. }
  2865. if (NULL != neighbour->reassembly_timeout_task)
  2866. {
  2867. GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task);
  2868. neighbour->reassembly_timeout_task = NULL;
  2869. }
  2870. if (NULL != neighbour->get)
  2871. {
  2872. GNUNET_PEERSTORE_iterate_cancel (neighbour->get);
  2873. neighbour->get = NULL;
  2874. }
  2875. if (NULL != neighbour->sc)
  2876. {
  2877. GNUNET_PEERSTORE_store_cancel (neighbour->sc);
  2878. neighbour->sc = NULL;
  2879. }
  2880. if (NULL != (vl = neighbour->vl))
  2881. {
  2882. GNUNET_assert (neighbour == vl->n);
  2883. vl->n = NULL;
  2884. if (NULL == vl->dv)
  2885. {
  2886. cores_send_disconnect_info (&vl->target);
  2887. free_virtual_link (vl);
  2888. }
  2889. else
  2890. {
  2891. GNUNET_SCHEDULER_cancel (vl->visibility_task);
  2892. vl->visibility_task = GNUNET_SCHEDULER_add_now (&check_link_down, vl);
  2893. }
  2894. neighbour->vl = NULL;
  2895. }
  2896. GNUNET_free (neighbour);
  2897. }
  2898. /**
  2899. * Send message to CORE clients that we lost a connection.
  2900. *
  2901. * @param tc client to inform (must be CORE client)
  2902. * @param pid peer the connection is for
  2903. */
  2904. static void
  2905. core_send_connect_info (struct TransportClient *tc,
  2906. const struct GNUNET_PeerIdentity *pid)
  2907. {
  2908. struct GNUNET_MQ_Envelope *env;
  2909. struct ConnectInfoMessage *cim;
  2910. GNUNET_assert (CT_CORE == tc->type);
  2911. env = GNUNET_MQ_msg (cim, GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
  2912. cim->id = *pid;
  2913. GNUNET_MQ_send (tc->mq, env);
  2914. }
  2915. /**
  2916. * Send message to CORE clients that we gained a connection
  2917. *
  2918. * @param pid peer the queue was for
  2919. */
  2920. static void
  2921. cores_send_connect_info (const struct GNUNET_PeerIdentity *pid)
  2922. {
  2923. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2924. "Informing CORE clients about connection to %s\n",
  2925. GNUNET_i2s (pid));
  2926. for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
  2927. {
  2928. if (CT_CORE != tc->type)
  2929. continue;
  2930. core_send_connect_info (tc, pid);
  2931. }
  2932. }
  2933. /**
  2934. * We believe we are ready to transmit a message on a queue. Gives the
  2935. * message to the communicator for transmission (updating the tracker,
  2936. * and re-scheduling itself if applicable).
  2937. *
  2938. * @param cls the `struct Queue` to process transmissions for
  2939. */
  2940. static void
  2941. transmit_on_queue (void *cls);
  2942. /**
  2943. * Called whenever something changed that might effect when we
  2944. * try to do the next transmission on @a queue using #transmit_on_queue().
  2945. *
  2946. * @param queue the queue to do scheduling for
  2947. * @param p task priority to use, if @a queue is scheduled
  2948. */
  2949. static void
  2950. schedule_transmit_on_queue (struct Queue *queue,
  2951. enum GNUNET_SCHEDULER_Priority p)
  2952. {
  2953. if (queue->tc->details.communicator.total_queue_length >=
  2954. COMMUNICATOR_TOTAL_QUEUE_LIMIT)
  2955. {
  2956. GNUNET_STATISTICS_update (
  2957. GST_stats,
  2958. "# Transmission throttled due to communicator queue limit",
  2959. 1,
  2960. GNUNET_NO);
  2961. queue->idle = GNUNET_NO;
  2962. return;
  2963. }
  2964. if (queue->queue_length >= QUEUE_LENGTH_LIMIT)
  2965. {
  2966. GNUNET_STATISTICS_update (GST_stats,
  2967. "# Transmission throttled due to queue queue limit",
  2968. 1,
  2969. GNUNET_NO);
  2970. queue->idle = GNUNET_NO;
  2971. return;
  2972. }
  2973. /* queue might indeed be ready, schedule it */
  2974. if (NULL != queue->transmit_task)
  2975. GNUNET_SCHEDULER_cancel (queue->transmit_task);
  2976. queue->transmit_task =
  2977. GNUNET_SCHEDULER_add_with_priority (p, &transmit_on_queue, queue);
  2978. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  2979. "Considering transmission on queue `%s' to %s\n",
  2980. queue->address,
  2981. GNUNET_i2s (&queue->neighbour->pid));
  2982. }
  2983. /**
  2984. * Task run to check whether the hops of the @a cls still
  2985. * are validated, or if we need to core about disconnection.
  2986. *
  2987. * @param cls a `struct VirtualLink`
  2988. */
  2989. static void
  2990. check_link_down (void *cls)
  2991. {
  2992. struct VirtualLink *vl = cls;
  2993. struct DistanceVector *dv = vl->dv;
  2994. struct Neighbour *n = vl->n;
  2995. struct GNUNET_TIME_Absolute dvh_timeout;
  2996. struct GNUNET_TIME_Absolute q_timeout;
  2997. vl->visibility_task = NULL;
  2998. dvh_timeout = GNUNET_TIME_UNIT_ZERO_ABS;
  2999. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  3000. pos = pos->next_dv)
  3001. dvh_timeout = GNUNET_TIME_absolute_max (dvh_timeout, pos->path_valid_until);
  3002. if (0 == GNUNET_TIME_absolute_get_remaining (dvh_timeout).rel_value_us)
  3003. {
  3004. vl->dv->vl = NULL;
  3005. vl->dv = NULL;
  3006. }
  3007. q_timeout = GNUNET_TIME_UNIT_ZERO_ABS;
  3008. for (struct Queue *q = n->queue_head; NULL != q; q = q->next_neighbour)
  3009. q_timeout = GNUNET_TIME_absolute_max (q_timeout, q->validated_until);
  3010. if (0 == GNUNET_TIME_absolute_get_remaining (q_timeout).rel_value_us)
  3011. {
  3012. vl->n->vl = NULL;
  3013. vl->n = NULL;
  3014. }
  3015. if ((NULL == vl->n) && (NULL == vl->dv))
  3016. {
  3017. cores_send_disconnect_info (&vl->target);
  3018. free_virtual_link (vl);
  3019. return;
  3020. }
  3021. vl->visibility_task =
  3022. GNUNET_SCHEDULER_add_at (GNUNET_TIME_absolute_max (q_timeout, dvh_timeout),
  3023. &check_link_down,
  3024. vl);
  3025. }
  3026. /**
  3027. * Free @a queue.
  3028. *
  3029. * @param queue the queue to free
  3030. */
  3031. static void
  3032. free_queue (struct Queue *queue)
  3033. {
  3034. struct Neighbour *neighbour = queue->neighbour;
  3035. struct TransportClient *tc = queue->tc;
  3036. struct MonitorEvent me = { .cs = GNUNET_TRANSPORT_CS_DOWN,
  3037. .rtt = GNUNET_TIME_UNIT_FOREVER_REL };
  3038. struct QueueEntry *qe;
  3039. int maxxed;
  3040. struct PendingAcknowledgement *pa;
  3041. struct VirtualLink *vl;
  3042. if (NULL != queue->transmit_task)
  3043. {
  3044. GNUNET_SCHEDULER_cancel (queue->transmit_task);
  3045. queue->transmit_task = NULL;
  3046. }
  3047. while (NULL != (pa = queue->pa_head))
  3048. {
  3049. GNUNET_CONTAINER_MDLL_remove (queue, queue->pa_head, queue->pa_tail, pa);
  3050. pa->queue = NULL;
  3051. }
  3052. GNUNET_CONTAINER_MDLL_remove (neighbour,
  3053. neighbour->queue_head,
  3054. neighbour->queue_tail,
  3055. queue);
  3056. GNUNET_CONTAINER_MDLL_remove (client,
  3057. tc->details.communicator.queue_head,
  3058. tc->details.communicator.queue_tail,
  3059. queue);
  3060. maxxed = (COMMUNICATOR_TOTAL_QUEUE_LIMIT >=
  3061. tc->details.communicator.total_queue_length);
  3062. while (NULL != (qe = queue->queue_head))
  3063. {
  3064. GNUNET_CONTAINER_DLL_remove (queue->queue_head, queue->queue_tail, qe);
  3065. queue->queue_length--;
  3066. tc->details.communicator.total_queue_length--;
  3067. if (NULL != qe->pm)
  3068. {
  3069. GNUNET_assert (qe == qe->pm->qe);
  3070. qe->pm->qe = NULL;
  3071. }
  3072. GNUNET_free (qe);
  3073. }
  3074. GNUNET_assert (0 == queue->queue_length);
  3075. if ((maxxed) && (COMMUNICATOR_TOTAL_QUEUE_LIMIT <
  3076. tc->details.communicator.total_queue_length))
  3077. {
  3078. /* Communicator dropped below threshold, resume all _other_ queues */
  3079. GNUNET_STATISTICS_update (
  3080. GST_stats,
  3081. "# Transmission throttled due to communicator queue limit",
  3082. -1,
  3083. GNUNET_NO);
  3084. for (struct Queue *s = tc->details.communicator.queue_head; NULL != s;
  3085. s = s->next_client)
  3086. schedule_transmit_on_queue (s, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  3087. }
  3088. notify_monitors (&neighbour->pid, queue->address, queue->nt, &me);
  3089. GNUNET_free (queue);
  3090. vl = lookup_virtual_link (&neighbour->pid);
  3091. if ((NULL != vl) && (neighbour == vl->n))
  3092. {
  3093. GNUNET_SCHEDULER_cancel (vl->visibility_task);
  3094. check_link_down (vl);
  3095. }
  3096. if (NULL == neighbour->queue_head)
  3097. {
  3098. free_neighbour (neighbour);
  3099. }
  3100. }
  3101. /**
  3102. * Free @a ale
  3103. *
  3104. * @param ale address list entry to free
  3105. */
  3106. static void
  3107. free_address_list_entry (struct AddressListEntry *ale)
  3108. {
  3109. struct TransportClient *tc = ale->tc;
  3110. GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
  3111. tc->details.communicator.addr_tail,
  3112. ale);
  3113. if (NULL != ale->sc)
  3114. {
  3115. GNUNET_PEERSTORE_store_cancel (ale->sc);
  3116. ale->sc = NULL;
  3117. }
  3118. if (NULL != ale->st)
  3119. {
  3120. GNUNET_SCHEDULER_cancel (ale->st);
  3121. ale->st = NULL;
  3122. }
  3123. GNUNET_free (ale);
  3124. }
  3125. /**
  3126. * Stop the peer request in @a value.
  3127. *
  3128. * @param cls a `struct TransportClient` that no longer makes the request
  3129. * @param pid the peer's identity
  3130. * @param value a `struct PeerRequest`
  3131. * @return #GNUNET_YES (always)
  3132. */
  3133. static int
  3134. stop_peer_request (void *cls,
  3135. const struct GNUNET_PeerIdentity *pid,
  3136. void *value)
  3137. {
  3138. struct TransportClient *tc = cls;
  3139. struct PeerRequest *pr = value;
  3140. GNUNET_PEERSTORE_watch_cancel (pr->wc);
  3141. GNUNET_assert (
  3142. GNUNET_YES ==
  3143. GNUNET_CONTAINER_multipeermap_remove (tc->details.application.requests,
  3144. pid,
  3145. pr));
  3146. GNUNET_free (pr);
  3147. return GNUNET_OK;
  3148. }
  3149. /**
  3150. * Called whenever a client is disconnected. Frees our
  3151. * resources associated with that client.
  3152. *
  3153. * @param cls closure, NULL
  3154. * @param client identification of the client
  3155. * @param app_ctx our `struct TransportClient`
  3156. */
  3157. static void
  3158. client_disconnect_cb (void *cls,
  3159. struct GNUNET_SERVICE_Client *client,
  3160. void *app_ctx)
  3161. {
  3162. struct TransportClient *tc = app_ctx;
  3163. (void) cls;
  3164. (void) client;
  3165. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3166. "Client %p disconnected, cleaning up.\n",
  3167. tc);
  3168. GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc);
  3169. switch (tc->type)
  3170. {
  3171. case CT_NONE:
  3172. break;
  3173. case CT_CORE: {
  3174. struct PendingMessage *pm;
  3175. while (NULL != (pm = tc->details.core.pending_msg_head))
  3176. {
  3177. GNUNET_CONTAINER_MDLL_remove (client,
  3178. tc->details.core.pending_msg_head,
  3179. tc->details.core.pending_msg_tail,
  3180. pm);
  3181. pm->client = NULL;
  3182. }
  3183. }
  3184. break;
  3185. case CT_MONITOR:
  3186. break;
  3187. case CT_COMMUNICATOR: {
  3188. struct Queue *q;
  3189. struct AddressListEntry *ale;
  3190. while (NULL != (q = tc->details.communicator.queue_head))
  3191. free_queue (q);
  3192. while (NULL != (ale = tc->details.communicator.addr_head))
  3193. free_address_list_entry (ale);
  3194. GNUNET_free (tc->details.communicator.address_prefix);
  3195. }
  3196. break;
  3197. case CT_APPLICATION:
  3198. GNUNET_CONTAINER_multipeermap_iterate (tc->details.application.requests,
  3199. &stop_peer_request,
  3200. tc);
  3201. GNUNET_CONTAINER_multipeermap_destroy (tc->details.application.requests);
  3202. break;
  3203. }
  3204. GNUNET_free (tc);
  3205. }
  3206. /**
  3207. * Iterator telling new CORE client about all existing
  3208. * connections to peers.
  3209. *
  3210. * @param cls the new `struct TransportClient`
  3211. * @param pid a connected peer
  3212. * @param value the `struct Neighbour` with more information
  3213. * @return #GNUNET_OK (continue to iterate)
  3214. */
  3215. static int
  3216. notify_client_connect_info (void *cls,
  3217. const struct GNUNET_PeerIdentity *pid,
  3218. void *value)
  3219. {
  3220. struct TransportClient *tc = cls;
  3221. (void) value;
  3222. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3223. "Telling new CORE client about existing connection to %s\n",
  3224. GNUNET_i2s (pid));
  3225. core_send_connect_info (tc, pid);
  3226. return GNUNET_OK;
  3227. }
  3228. /**
  3229. * Initialize a "CORE" client. We got a start message from this
  3230. * client, so add it to the list of clients for broadcasting of
  3231. * inbound messages.
  3232. *
  3233. * @param cls the client
  3234. * @param start the start message that was sent
  3235. */
  3236. static void
  3237. handle_client_start (void *cls, const struct StartMessage *start)
  3238. {
  3239. struct TransportClient *tc = cls;
  3240. uint32_t options;
  3241. options = ntohl (start->options);
  3242. if ((0 != (1 & options)) &&
  3243. (0 != GNUNET_memcmp (&start->self, &GST_my_identity)))
  3244. {
  3245. /* client thinks this is a different peer, reject */
  3246. GNUNET_break (0);
  3247. GNUNET_SERVICE_client_drop (tc->client);
  3248. return;
  3249. }
  3250. if (CT_NONE != tc->type)
  3251. {
  3252. GNUNET_break (0);
  3253. GNUNET_SERVICE_client_drop (tc->client);
  3254. return;
  3255. }
  3256. tc->type = CT_CORE;
  3257. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3258. "New CORE client with PID %s registered\n",
  3259. GNUNET_i2s (&start->self));
  3260. GNUNET_CONTAINER_multipeermap_iterate (neighbours,
  3261. &notify_client_connect_info,
  3262. tc);
  3263. GNUNET_SERVICE_client_continue (tc->client);
  3264. }
  3265. /**
  3266. * Client asked for transmission to a peer. Process the request.
  3267. *
  3268. * @param cls the client
  3269. * @param obm the send message that was sent
  3270. */
  3271. static int
  3272. check_client_send (void *cls, const struct OutboundMessage *obm)
  3273. {
  3274. struct TransportClient *tc = cls;
  3275. uint16_t size;
  3276. const struct GNUNET_MessageHeader *obmm;
  3277. if (CT_CORE != tc->type)
  3278. {
  3279. GNUNET_break (0);
  3280. return GNUNET_SYSERR;
  3281. }
  3282. size = ntohs (obm->header.size) - sizeof(struct OutboundMessage);
  3283. if (size < sizeof(struct GNUNET_MessageHeader))
  3284. {
  3285. GNUNET_break (0);
  3286. return GNUNET_SYSERR;
  3287. }
  3288. obmm = (const struct GNUNET_MessageHeader *) &obm[1];
  3289. if (size != ntohs (obmm->size))
  3290. {
  3291. GNUNET_break (0);
  3292. return GNUNET_SYSERR;
  3293. }
  3294. return GNUNET_OK;
  3295. }
  3296. /**
  3297. * Send a response to the @a pm that we have processed a "send"
  3298. * request. Sends a confirmation to the "core" client responsible for
  3299. * the original request and free's @a pm.
  3300. *
  3301. * @param pm handle to the original pending message
  3302. */
  3303. static void
  3304. client_send_response (struct PendingMessage *pm)
  3305. {
  3306. struct TransportClient *tc = pm->client;
  3307. struct VirtualLink *vl = pm->vl;
  3308. if (NULL != tc)
  3309. {
  3310. struct GNUNET_MQ_Envelope *env;
  3311. struct SendOkMessage *som;
  3312. env = GNUNET_MQ_msg (som, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
  3313. som->peer = vl->target;
  3314. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3315. "Confirming transmission of <%llu> to %s\n",
  3316. pm->logging_uuid,
  3317. GNUNET_i2s (&vl->target));
  3318. GNUNET_MQ_send (tc->mq, env);
  3319. }
  3320. free_pending_message (pm);
  3321. }
  3322. /**
  3323. * Pick @a hops_array_length random DV paths satisfying @a options
  3324. *
  3325. * @param dv data structure to pick paths from
  3326. * @param options constraints to satisfy
  3327. * @param hops_array[out] set to the result
  3328. * @param hops_array_length length of the @a hops_array
  3329. * @return number of entries set in @a hops_array
  3330. */
  3331. static unsigned int
  3332. pick_random_dv_hops (const struct DistanceVector *dv,
  3333. enum RouteMessageOptions options,
  3334. struct DistanceVectorHop **hops_array,
  3335. unsigned int hops_array_length)
  3336. {
  3337. uint64_t choices[hops_array_length];
  3338. uint64_t num_dv;
  3339. unsigned int dv_count;
  3340. /* Pick random vectors, but weighted by distance, giving more weight
  3341. to shorter vectors */
  3342. num_dv = 0;
  3343. dv_count = 0;
  3344. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  3345. pos = pos->next_dv)
  3346. {
  3347. if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
  3348. (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
  3349. .rel_value_us == 0))
  3350. continue; /* pos unconfirmed and confirmed required */
  3351. num_dv += MAX_DV_HOPS_ALLOWED - pos->distance;
  3352. dv_count++;
  3353. }
  3354. if (0 == dv_count)
  3355. return 0;
  3356. if (dv_count <= hops_array_length)
  3357. {
  3358. dv_count = 0;
  3359. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  3360. pos = pos->next_dv)
  3361. hops_array[dv_count++] = pos;
  3362. return dv_count;
  3363. }
  3364. for (unsigned int i = 0; i < hops_array_length; i++)
  3365. {
  3366. int ok = GNUNET_NO;
  3367. while (GNUNET_NO == ok)
  3368. {
  3369. choices[i] =
  3370. GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
  3371. ok = GNUNET_YES;
  3372. for (unsigned int j = 0; j < i; j++)
  3373. if (choices[i] == choices[j])
  3374. {
  3375. ok = GNUNET_NO;
  3376. break;
  3377. }
  3378. }
  3379. }
  3380. dv_count = 0;
  3381. num_dv = 0;
  3382. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  3383. pos = pos->next_dv)
  3384. {
  3385. uint32_t delta = MAX_DV_HOPS_ALLOWED - pos->distance;
  3386. if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
  3387. (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
  3388. .rel_value_us == 0))
  3389. continue; /* pos unconfirmed and confirmed required */
  3390. for (unsigned int i = 0; i < hops_array_length; i++)
  3391. if ((num_dv <= choices[i]) && (num_dv + delta > choices[i]))
  3392. hops_array[dv_count++] = pos;
  3393. num_dv += delta;
  3394. }
  3395. return dv_count;
  3396. }
  3397. /**
  3398. * Communicator started. Test message is well-formed.
  3399. *
  3400. * @param cls the client
  3401. * @param cam the send message that was sent
  3402. */
  3403. static int
  3404. check_communicator_available (
  3405. void *cls,
  3406. const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
  3407. {
  3408. struct TransportClient *tc = cls;
  3409. uint16_t size;
  3410. if (CT_NONE != tc->type)
  3411. {
  3412. GNUNET_break (0);
  3413. return GNUNET_SYSERR;
  3414. }
  3415. tc->type = CT_COMMUNICATOR;
  3416. size = ntohs (cam->header.size) - sizeof(*cam);
  3417. if (0 == size)
  3418. return GNUNET_OK; /* receive-only communicator */
  3419. GNUNET_MQ_check_zero_termination (cam);
  3420. return GNUNET_OK;
  3421. }
  3422. /**
  3423. * Send ACK to communicator (if requested) and free @a cmc.
  3424. *
  3425. * @param cmc context for which we are done handling the message
  3426. */
  3427. static void
  3428. finish_cmc_handling (struct CommunicatorMessageContext *cmc)
  3429. {
  3430. if (0 != ntohl (cmc->im.fc_on))
  3431. {
  3432. /* send ACK when done to communicator for flow control! */
  3433. struct GNUNET_MQ_Envelope *env;
  3434. struct GNUNET_TRANSPORT_IncomingMessageAck *ack;
  3435. env = GNUNET_MQ_msg (ack, GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK);
  3436. ack->reserved = htonl (0);
  3437. ack->fc_id = cmc->im.fc_id;
  3438. ack->sender = cmc->im.sender;
  3439. GNUNET_MQ_send (cmc->tc->mq, env);
  3440. }
  3441. GNUNET_SERVICE_client_continue (cmc->tc->client);
  3442. GNUNET_free (cmc);
  3443. }
  3444. /**
  3445. * Client confirms that it is done handling message(s) to a particular
  3446. * peer. We may now provide more messages to CORE for this peer.
  3447. *
  3448. * Notifies the respective queues that more messages can now be received.
  3449. *
  3450. * @param cls the client
  3451. * @param rom the message that was sent
  3452. */
  3453. static void
  3454. handle_client_recv_ok (void *cls, const struct RecvOkMessage *rom)
  3455. {
  3456. struct TransportClient *tc = cls;
  3457. struct VirtualLink *vl;
  3458. uint32_t delta;
  3459. struct CommunicatorMessageContext *cmc;
  3460. if (CT_CORE != tc->type)
  3461. {
  3462. GNUNET_break (0);
  3463. GNUNET_SERVICE_client_drop (tc->client);
  3464. return;
  3465. }
  3466. vl = lookup_virtual_link (&rom->peer);
  3467. if (NULL == vl)
  3468. {
  3469. GNUNET_STATISTICS_update (GST_stats,
  3470. "# RECV_OK dropped: virtual link unknown",
  3471. 1,
  3472. GNUNET_NO);
  3473. GNUNET_SERVICE_client_continue (tc->client);
  3474. return;
  3475. }
  3476. delta = ntohl (rom->increase_window_delta);
  3477. vl->core_recv_window += delta;
  3478. if (vl->core_recv_window <= 0)
  3479. return;
  3480. /* resume communicators */
  3481. while (NULL != (cmc = vl->cmc_tail))
  3482. {
  3483. GNUNET_CONTAINER_DLL_remove (vl->cmc_head, vl->cmc_tail, cmc);
  3484. finish_cmc_handling (cmc);
  3485. }
  3486. }
  3487. /**
  3488. * Communicator started. Process the request.
  3489. *
  3490. * @param cls the client
  3491. * @param cam the send message that was sent
  3492. */
  3493. static void
  3494. handle_communicator_available (
  3495. void *cls,
  3496. const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
  3497. {
  3498. struct TransportClient *tc = cls;
  3499. uint16_t size;
  3500. size = ntohs (cam->header.size) - sizeof(*cam);
  3501. if (0 == size)
  3502. {
  3503. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3504. "Receive-only communicator connected\n");
  3505. return; /* receive-only communicator */
  3506. }
  3507. tc->details.communicator.address_prefix =
  3508. GNUNET_strdup ((const char *) &cam[1]);
  3509. tc->details.communicator.cc =
  3510. (enum GNUNET_TRANSPORT_CommunicatorCharacteristics) ntohl (cam->cc);
  3511. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3512. "Communicator with prefix `%s' connected\n",
  3513. tc->details.communicator.address_prefix);
  3514. GNUNET_SERVICE_client_continue (tc->client);
  3515. }
  3516. /**
  3517. * Communicator requests backchannel transmission. Check the request.
  3518. *
  3519. * @param cls the client
  3520. * @param cb the send message that was sent
  3521. * @return #GNUNET_OK if message is well-formed
  3522. */
  3523. static int
  3524. check_communicator_backchannel (
  3525. void *cls,
  3526. const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
  3527. {
  3528. const struct GNUNET_MessageHeader *inbox;
  3529. const char *is;
  3530. uint16_t msize;
  3531. uint16_t isize;
  3532. (void) cls;
  3533. msize = ntohs (cb->header.size) - sizeof(*cb);
  3534. inbox = (const struct GNUNET_MessageHeader *) &cb[1];
  3535. isize = ntohs (inbox->size);
  3536. if (isize >= msize)
  3537. {
  3538. GNUNET_break (0);
  3539. return GNUNET_SYSERR;
  3540. }
  3541. is = (const char *) inbox;
  3542. is += isize;
  3543. msize -= isize;
  3544. GNUNET_assert (0 < msize);
  3545. if ('\0' != is[msize - 1])
  3546. {
  3547. GNUNET_break (0);
  3548. return GNUNET_SYSERR;
  3549. }
  3550. return GNUNET_OK;
  3551. }
  3552. /**
  3553. * Ensure ephemeral keys in our @a dv are current. If no current one exists,
  3554. * set it up.
  3555. *
  3556. * @param dv[in,out] virtual link to update ephemeral for
  3557. */
  3558. static void
  3559. update_ephemeral (struct DistanceVector *dv)
  3560. {
  3561. struct EphemeralConfirmationPS ec;
  3562. if (0 !=
  3563. GNUNET_TIME_absolute_get_remaining (dv->ephemeral_validity).rel_value_us)
  3564. return;
  3565. dv->monotime = GNUNET_TIME_absolute_get_monotonic (GST_cfg);
  3566. dv->ephemeral_validity =
  3567. GNUNET_TIME_absolute_add (dv->monotime, EPHEMERAL_VALIDITY);
  3568. GNUNET_CRYPTO_ecdhe_key_create (&dv->private_key);
  3569. GNUNET_CRYPTO_ecdhe_key_get_public (&dv->private_key, &dv->ephemeral_key);
  3570. ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
  3571. ec.purpose.size = htonl (sizeof(ec));
  3572. ec.target = dv->target;
  3573. ec.ephemeral_key = dv->ephemeral_key;
  3574. GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
  3575. &ec,
  3576. &dv->sender_sig);
  3577. }
  3578. /**
  3579. * Send the message @a payload on @a queue.
  3580. *
  3581. * @param queue the queue to use for transmission
  3582. * @param pm pending message to update once transmission is done, may be NULL!
  3583. * @param payload the payload to send (encapsulated in a
  3584. * #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG).
  3585. * @param payload_size number of bytes in @a payload
  3586. */
  3587. static void
  3588. queue_send_msg (struct Queue *queue,
  3589. struct PendingMessage *pm,
  3590. const void *payload,
  3591. size_t payload_size)
  3592. {
  3593. struct Neighbour *n = queue->neighbour;
  3594. struct GNUNET_TRANSPORT_SendMessageTo *smt;
  3595. struct GNUNET_MQ_Envelope *env;
  3596. queue->idle = GNUNET_NO;
  3597. GNUNET_log (
  3598. GNUNET_ERROR_TYPE_DEBUG,
  3599. "Queueing %u bytes of payload for transmission <%llu> on queue %llu to %s\n",
  3600. (unsigned int) payload_size,
  3601. (NULL == pm) ? 0 : pm->logging_uuid,
  3602. (unsigned long long) queue->qid,
  3603. GNUNET_i2s (&queue->neighbour->pid));
  3604. env = GNUNET_MQ_msg_extra (smt,
  3605. payload_size,
  3606. GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG);
  3607. smt->qid = queue->qid;
  3608. smt->mid = queue->mid_gen;
  3609. smt->receiver = n->pid;
  3610. memcpy (&smt[1], payload, payload_size);
  3611. {
  3612. /* Pass the env to the communicator of queue for transmission. */
  3613. struct QueueEntry *qe;
  3614. qe = GNUNET_new (struct QueueEntry);
  3615. qe->mid = queue->mid_gen++;
  3616. qe->queue = queue;
  3617. if (NULL != pm)
  3618. {
  3619. qe->pm = pm;
  3620. GNUNET_assert (NULL == pm->qe);
  3621. pm->qe = qe;
  3622. }
  3623. GNUNET_CONTAINER_DLL_insert (queue->queue_head, queue->queue_tail, qe);
  3624. GNUNET_assert (CT_COMMUNICATOR == queue->tc->type);
  3625. queue->queue_length++;
  3626. queue->tc->details.communicator.total_queue_length++;
  3627. if (COMMUNICATOR_TOTAL_QUEUE_LIMIT ==
  3628. queue->tc->details.communicator.total_queue_length)
  3629. queue->idle = GNUNET_NO;
  3630. if (QUEUE_LENGTH_LIMIT == queue->queue_length)
  3631. queue->idle = GNUNET_NO;
  3632. GNUNET_MQ_send (queue->tc->mq, env);
  3633. }
  3634. }
  3635. /**
  3636. * Pick a queue of @a n under constraints @a options and schedule
  3637. * transmission of @a hdr.
  3638. *
  3639. * @param n neighbour to send to
  3640. * @param hdr message to send as payload
  3641. * @param options whether queues must be confirmed or not,
  3642. * and whether we may pick multiple (2) queues
  3643. * @return expected RTT for transmission, #GNUNET_TIME_UNIT_FOREVER_REL if sending failed
  3644. */
  3645. static struct GNUNET_TIME_Relative
  3646. route_via_neighbour (const struct Neighbour *n,
  3647. const struct GNUNET_MessageHeader *hdr,
  3648. enum RouteMessageOptions options)
  3649. {
  3650. struct GNUNET_TIME_Absolute now;
  3651. unsigned int candidates;
  3652. unsigned int sel1;
  3653. unsigned int sel2;
  3654. struct GNUNET_TIME_Relative rtt;
  3655. /* Pick one or two 'random' queues from n (under constraints of options) */
  3656. now = GNUNET_TIME_absolute_get ();
  3657. /* FIXME-OPTIMIZE: give queues 'weights' and pick proportional to
  3658. weight in the future; weight could be assigned by observed
  3659. bandwidth (note: not sure if we should do this for this type
  3660. of control traffic though). */
  3661. candidates = 0;
  3662. for (struct Queue *pos = n->queue_head; NULL != pos;
  3663. pos = pos->next_neighbour)
  3664. {
  3665. if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) ||
  3666. (pos->validated_until.abs_value_us > now.abs_value_us))
  3667. candidates++;
  3668. }
  3669. if (0 == candidates)
  3670. {
  3671. /* This can happen rarely if the last confirmed queue timed
  3672. out just as we were beginning to process this message. */
  3673. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  3674. "Could not route message of type %u to %s: no valid queue\n",
  3675. ntohs (hdr->type),
  3676. GNUNET_i2s (&n->pid));
  3677. GNUNET_STATISTICS_update (GST_stats,
  3678. "# route selection failed (all no valid queue)",
  3679. 1,
  3680. GNUNET_NO);
  3681. return GNUNET_TIME_UNIT_FOREVER_REL;
  3682. }
  3683. rtt = GNUNET_TIME_UNIT_FOREVER_REL;
  3684. sel1 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
  3685. if (0 == (options & RMO_REDUNDANT))
  3686. sel2 = candidates; /* picks none! */
  3687. else
  3688. sel2 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
  3689. candidates = 0;
  3690. for (struct Queue *pos = n->queue_head; NULL != pos;
  3691. pos = pos->next_neighbour)
  3692. {
  3693. if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) ||
  3694. (pos->validated_until.abs_value_us > now.abs_value_us))
  3695. {
  3696. if ((sel1 == candidates) || (sel2 == candidates))
  3697. {
  3698. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3699. "Routing message of type %u to %s using %s (#%u)\n",
  3700. ntohs (hdr->type),
  3701. GNUNET_i2s (&n->pid),
  3702. pos->address,
  3703. (sel1 == candidates) ? 1 : 2);
  3704. rtt = GNUNET_TIME_relative_min (rtt, pos->pd.aged_rtt);
  3705. queue_send_msg (pos, NULL, hdr, ntohs (hdr->size));
  3706. }
  3707. candidates++;
  3708. }
  3709. }
  3710. return rtt;
  3711. }
  3712. /**
  3713. * Structure of the key material used to encrypt backchannel messages.
  3714. */
  3715. struct DVKeyState
  3716. {
  3717. /**
  3718. * State of our block cipher.
  3719. */
  3720. gcry_cipher_hd_t cipher;
  3721. /**
  3722. * Actual key material.
  3723. */
  3724. struct
  3725. {
  3726. /**
  3727. * Key used for HMAC calculations (via #GNUNET_CRYPTO_hmac()).
  3728. */
  3729. struct GNUNET_CRYPTO_AuthKey hmac_key;
  3730. /**
  3731. * Symmetric key to use for encryption.
  3732. */
  3733. char aes_key[256 / 8];
  3734. /**
  3735. * Counter value to use during setup.
  3736. */
  3737. char aes_ctr[128 / 8];
  3738. } material;
  3739. };
  3740. /**
  3741. * Given the key material in @a km and the initialization vector
  3742. * @a iv, setup the key material for the backchannel in @a key.
  3743. *
  3744. * @param km raw master secret
  3745. * @param iv initialization vector
  3746. * @param key[out] symmetric cipher and HMAC state to generate
  3747. */
  3748. static void
  3749. dv_setup_key_state_from_km (const struct GNUNET_HashCode *km,
  3750. const struct GNUNET_ShortHashCode *iv,
  3751. struct DVKeyState *key)
  3752. {
  3753. /* must match #dh_key_derive_eph_pub */
  3754. GNUNET_assert (GNUNET_YES ==
  3755. GNUNET_CRYPTO_kdf (&key->material,
  3756. sizeof(key->material),
  3757. "transport-backchannel-key",
  3758. strlen ("transport-backchannel-key"),
  3759. &km,
  3760. sizeof(km),
  3761. iv,
  3762. sizeof(*iv)));
  3763. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3764. "Deriving backchannel key based on KM %s and IV %s\n",
  3765. GNUNET_h2s (km),
  3766. GNUNET_sh2s (iv));
  3767. gcry_cipher_open (&key->cipher,
  3768. GCRY_CIPHER_AES256 /* low level: go for speed */,
  3769. GCRY_CIPHER_MODE_CTR,
  3770. 0 /* flags */);
  3771. gcry_cipher_setkey (key->cipher,
  3772. &key->material.aes_key,
  3773. sizeof(key->material.aes_key));
  3774. gcry_cipher_setctr (key->cipher,
  3775. &key->material.aes_ctr,
  3776. sizeof(key->material.aes_ctr));
  3777. }
  3778. /**
  3779. * Derive backchannel encryption key material from @a priv_ephemeral
  3780. * and @a target and @a iv.
  3781. *
  3782. * @param priv_ephemeral ephemeral private key to use
  3783. * @param target the target peer to encrypt to
  3784. * @param iv unique IV to use
  3785. * @param key[out] set to the key material
  3786. */
  3787. static void
  3788. dh_key_derive_eph_pid (
  3789. const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ephemeral,
  3790. const struct GNUNET_PeerIdentity *target,
  3791. const struct GNUNET_ShortHashCode *iv,
  3792. struct DVKeyState *key)
  3793. {
  3794. struct GNUNET_HashCode km;
  3795. GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_ecdh_eddsa (priv_ephemeral,
  3796. &target->public_key,
  3797. &km));
  3798. dv_setup_key_state_from_km (&km, iv, key);
  3799. }
  3800. /**
  3801. * Derive backchannel encryption key material from #GST_my_private_key
  3802. * and @a pub_ephemeral and @a iv.
  3803. *
  3804. * @param priv_ephemeral ephemeral private key to use
  3805. * @param target the target peer to encrypt to
  3806. * @param iv unique IV to use
  3807. * @param key[out] set to the key material
  3808. */
  3809. static void
  3810. dh_key_derive_eph_pub (const struct GNUNET_CRYPTO_EcdhePublicKey *pub_ephemeral,
  3811. const struct GNUNET_ShortHashCode *iv,
  3812. struct DVKeyState *key)
  3813. {
  3814. struct GNUNET_HashCode km;
  3815. GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_eddsa_ecdh (GST_my_private_key,
  3816. pub_ephemeral,
  3817. &km));
  3818. dv_setup_key_state_from_km (&km, iv, key);
  3819. }
  3820. /**
  3821. * Do HMAC calculation for backchannel messages over @a data using key
  3822. * material from @a key.
  3823. *
  3824. * @param key key material (from DH)
  3825. * @param hmac[out] set to the HMAC
  3826. * @param data data to perform HMAC calculation over
  3827. * @param data_size number of bytes in @a data
  3828. */
  3829. static void
  3830. dv_hmac (const struct DVKeyState *key,
  3831. struct GNUNET_HashCode *hmac,
  3832. const void *data,
  3833. size_t data_size)
  3834. {
  3835. GNUNET_CRYPTO_hmac (&key->material.hmac_key, data, data_size, hmac);
  3836. }
  3837. /**
  3838. * Perform backchannel encryption using symmetric secret in @a key
  3839. * to encrypt data from @a in to @a dst.
  3840. *
  3841. * @param key[in,out] key material to use
  3842. * @param dst where to write the result
  3843. * @param in input data to encrypt (plaintext)
  3844. * @param in_size number of bytes of input in @a in and available at @a dst
  3845. */
  3846. static void
  3847. dv_encrypt (struct DVKeyState *key, const void *in, void *dst, size_t in_size)
  3848. {
  3849. GNUNET_assert (0 ==
  3850. gcry_cipher_encrypt (key->cipher, dst, in_size, in, in_size));
  3851. }
  3852. /**
  3853. * Perform backchannel encryption using symmetric secret in @a key
  3854. * to encrypt data from @a in to @a dst.
  3855. *
  3856. * @param key[in,out] key material to use
  3857. * @param ciph cipher text to decrypt
  3858. * @param out[out] output data to generate (plaintext)
  3859. * @param out_size number of bytes of input in @a ciph and available in @a out
  3860. */
  3861. static void
  3862. dv_decrypt (struct DVKeyState *key,
  3863. void *out,
  3864. const void *ciph,
  3865. size_t out_size)
  3866. {
  3867. GNUNET_assert (
  3868. 0 == gcry_cipher_decrypt (key->cipher, out, out_size, ciph, out_size));
  3869. }
  3870. /**
  3871. * Clean up key material in @a key.
  3872. *
  3873. * @param key key material to clean up (memory must not be free'd!)
  3874. */
  3875. static void
  3876. dv_key_clean (struct DVKeyState *key)
  3877. {
  3878. gcry_cipher_close (key->cipher);
  3879. GNUNET_CRYPTO_zero_keys (&key->material, sizeof(key->material));
  3880. }
  3881. /**
  3882. * Function to call to further operate on the now DV encapsulated
  3883. * message @a hdr, forwarding it via @a next_hop under respect of
  3884. * @a options.
  3885. *
  3886. * @param cls closure
  3887. * @param next_hop next hop of the DV path
  3888. * @param hdr encapsulated message, technically a `struct TransportDFBoxMessage`
  3889. * @param options options of the original message
  3890. */
  3891. typedef void (*DVMessageHandler) (void *cls,
  3892. struct Neighbour *next_hop,
  3893. const struct GNUNET_MessageHeader *hdr,
  3894. enum RouteMessageOptions options);
  3895. /**
  3896. * Pick a path of @a dv under constraints @a options and schedule
  3897. * transmission of @a hdr.
  3898. *
  3899. * @param target neighbour to ultimately send to
  3900. * @param num_dvhs length of the @a dvhs array
  3901. * @param dvhs array of hops to send the message to
  3902. * @param hdr message to send as payload
  3903. * @param use function to call with the encapsulated message
  3904. * @param use_cls closure for @a use
  3905. * @param options whether path must be confirmed or not, to be passed to @a use
  3906. * @return expected RTT for transmission, #GNUNET_TIME_UNIT_FOREVER_REL if sending failed
  3907. */
  3908. static struct GNUNET_TIME_Relative
  3909. encapsulate_for_dv (struct DistanceVector *dv,
  3910. unsigned int num_dvhs,
  3911. struct DistanceVectorHop **dvhs,
  3912. const struct GNUNET_MessageHeader *hdr,
  3913. DVMessageHandler use,
  3914. void *use_cls,
  3915. enum RouteMessageOptions options)
  3916. {
  3917. struct TransportDVBoxMessage box_hdr;
  3918. struct TransportDVBoxPayloadP payload_hdr;
  3919. uint16_t enc_body_size = ntohs (hdr->size);
  3920. char enc[sizeof(struct TransportDVBoxPayloadP) + enc_body_size] GNUNET_ALIGN;
  3921. struct TransportDVBoxPayloadP *enc_payload_hdr =
  3922. (struct TransportDVBoxPayloadP *) enc;
  3923. struct DVKeyState key;
  3924. struct GNUNET_TIME_Relative rtt;
  3925. /* Encrypt payload */
  3926. box_hdr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
  3927. box_hdr.total_hops = htons (0);
  3928. update_ephemeral (dv);
  3929. box_hdr.ephemeral_key = dv->ephemeral_key;
  3930. payload_hdr.sender_sig = dv->sender_sig;
  3931. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
  3932. &box_hdr.iv,
  3933. sizeof(box_hdr.iv));
  3934. dh_key_derive_eph_pid (&dv->private_key, &dv->target, &box_hdr.iv, &key);
  3935. payload_hdr.sender = GST_my_identity;
  3936. payload_hdr.monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime);
  3937. dv_encrypt (&key, &payload_hdr, enc_payload_hdr, sizeof(payload_hdr));
  3938. dv_encrypt (&key,
  3939. hdr,
  3940. &enc[sizeof(struct TransportDVBoxPayloadP)],
  3941. enc_body_size);
  3942. dv_hmac (&key, &box_hdr.hmac, enc, sizeof(enc));
  3943. dv_key_clean (&key);
  3944. rtt = GNUNET_TIME_UNIT_FOREVER_REL;
  3945. /* For each selected path, take the pre-computed header and body
  3946. and add the path in the middle of the message; then send it. */
  3947. for (unsigned int i = 0; i < num_dvhs; i++)
  3948. {
  3949. struct DistanceVectorHop *dvh = dvhs[i];
  3950. unsigned int num_hops = dvh->distance + 1;
  3951. char buf[sizeof(struct TransportDVBoxMessage)
  3952. + sizeof(struct GNUNET_PeerIdentity) * num_hops
  3953. + sizeof(struct TransportDVBoxPayloadP)
  3954. + enc_body_size] GNUNET_ALIGN;
  3955. struct GNUNET_PeerIdentity *dhops;
  3956. box_hdr.header.size = htons (sizeof(buf));
  3957. box_hdr.num_hops = htons (num_hops);
  3958. memcpy (buf, &box_hdr, sizeof(box_hdr));
  3959. dhops = (struct GNUNET_PeerIdentity *) &buf[sizeof(box_hdr)];
  3960. memcpy (dhops,
  3961. dvh->path,
  3962. dvh->distance * sizeof(struct GNUNET_PeerIdentity));
  3963. dhops[dvh->distance] = dv->target;
  3964. if (GNUNET_EXTRA_LOGGING > 0)
  3965. {
  3966. char *path;
  3967. path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity));
  3968. for (unsigned int j = 0; j <= num_hops; j++)
  3969. {
  3970. char *tmp;
  3971. GNUNET_asprintf (&tmp, "%s-%s", path, GNUNET_i2s (&dhops[j]));
  3972. GNUNET_free (path);
  3973. path = tmp;
  3974. }
  3975. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  3976. "Routing message of type %u to %s using DV (#%u/%u) via %s\n",
  3977. ntohs (hdr->type),
  3978. GNUNET_i2s (&dv->target),
  3979. i + 1,
  3980. num_dvhs + 1,
  3981. path);
  3982. GNUNET_free (path);
  3983. }
  3984. rtt = GNUNET_TIME_relative_min (rtt, dvh->pd.aged_rtt);
  3985. memcpy (&dhops[num_hops], enc, sizeof(enc));
  3986. use (use_cls,
  3987. dvh->next_hop,
  3988. (const struct GNUNET_MessageHeader *) buf,
  3989. options);
  3990. }
  3991. return rtt;
  3992. }
  3993. /**
  3994. * Wrapper around #route_via_neighbour() that matches the
  3995. * #DVMessageHandler structure.
  3996. *
  3997. * @param cls unused
  3998. * @param next_hop where to send next
  3999. * @param hdr header of the message to send
  4000. * @param options message options for queue selection
  4001. */
  4002. static void
  4003. send_dv_to_neighbour (void *cls,
  4004. struct Neighbour *next_hop,
  4005. const struct GNUNET_MessageHeader *hdr,
  4006. enum RouteMessageOptions options)
  4007. {
  4008. (void) cls;
  4009. (void) route_via_neighbour (next_hop, hdr, options);
  4010. }
  4011. /**
  4012. * We need to transmit @a hdr to @a target. If necessary, this may
  4013. * involve DV routing. This function routes without applying flow
  4014. * control or congestion control and should only be used for control
  4015. * traffic.
  4016. *
  4017. * @param target peer to receive @a hdr
  4018. * @param hdr header of the message to route and #GNUNET_free()
  4019. * @param options which transmission channels are allowed
  4020. * @return expected RTT for transmission, #GNUNET_TIME_UNIT_FOREVER_REL if sending failed
  4021. */
  4022. static struct GNUNET_TIME_Relative
  4023. route_control_message_without_fc (const struct GNUNET_PeerIdentity *target,
  4024. const struct GNUNET_MessageHeader *hdr,
  4025. enum RouteMessageOptions options)
  4026. {
  4027. struct VirtualLink *vl;
  4028. struct Neighbour *n;
  4029. struct DistanceVector *dv;
  4030. struct GNUNET_TIME_Relative rtt1;
  4031. struct GNUNET_TIME_Relative rtt2;
  4032. vl = lookup_virtual_link (target);
  4033. GNUNET_assert (NULL != vl);
  4034. n = vl->n;
  4035. dv = (0 != (options & RMO_DV_ALLOWED)) ? vl->dv : NULL;
  4036. if (0 == (options & RMO_UNCONFIRMED_ALLOWED))
  4037. {
  4038. /* if confirmed is required, and we do not have anything
  4039. confirmed, drop respective options */
  4040. if (NULL == n)
  4041. n = lookup_neighbour (target);
  4042. if ((NULL == dv) && (0 != (options & RMO_DV_ALLOWED)))
  4043. dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, target);
  4044. }
  4045. if ((NULL == n) && (NULL == dv))
  4046. {
  4047. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  4048. "Cannot route message of type %u to %s: no route\n",
  4049. ntohs (hdr->type),
  4050. GNUNET_i2s (target));
  4051. GNUNET_STATISTICS_update (GST_stats,
  4052. "# Messages dropped in routing: no acceptable method",
  4053. 1,
  4054. GNUNET_NO);
  4055. return GNUNET_TIME_UNIT_FOREVER_REL;
  4056. }
  4057. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4058. "Routing message of type %u to %s with options %X\n",
  4059. ntohs (hdr->type),
  4060. GNUNET_i2s (target),
  4061. (unsigned int) options);
  4062. /* If both dv and n are possible and we must choose:
  4063. flip a coin for the choice between the two; for now 50/50 */
  4064. if ((NULL != n) && (NULL != dv) && (0 == (options & RMO_REDUNDANT)))
  4065. {
  4066. if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2))
  4067. n = NULL;
  4068. else
  4069. dv = NULL;
  4070. }
  4071. if ((NULL != n) && (NULL != dv))
  4072. options &= ~RMO_REDUNDANT; /* We will do one DV and one direct, that's
  4073. enough for redunancy, so clear the flag. */
  4074. rtt1 = GNUNET_TIME_UNIT_FOREVER_REL;
  4075. rtt2 = GNUNET_TIME_UNIT_FOREVER_REL;
  4076. if (NULL != n)
  4077. {
  4078. rtt1 = route_via_neighbour (n, hdr, options);
  4079. }
  4080. if (NULL != dv)
  4081. {
  4082. struct DistanceVectorHop *hops[2];
  4083. unsigned int res;
  4084. res = pick_random_dv_hops (dv,
  4085. options,
  4086. hops,
  4087. (0 == (options & RMO_REDUNDANT)) ? 1 : 2);
  4088. if (0 == res)
  4089. {
  4090. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  4091. "Failed to route message, could not determine DV path\n");
  4092. return rtt1;
  4093. }
  4094. rtt2 = encapsulate_for_dv (dv,
  4095. res,
  4096. hops,
  4097. hdr,
  4098. &send_dv_to_neighbour,
  4099. NULL,
  4100. options & (~RMO_REDUNDANT));
  4101. }
  4102. return GNUNET_TIME_relative_min (rtt1, rtt2);
  4103. }
  4104. /**
  4105. * Something changed on the virtual link with respect to flow
  4106. * control. Consider retransmitting the FC window size.
  4107. *
  4108. * @param cls a `struct VirtualLink` to work with
  4109. */
  4110. static void
  4111. consider_sending_fc (void *cls)
  4112. {
  4113. struct VirtualLink *vl = cls;
  4114. struct GNUNET_TIME_Absolute monotime;
  4115. struct TransportFlowControlMessage fc;
  4116. struct GNUNET_TIME_Relative duration;
  4117. struct GNUNET_TIME_Relative rtt;
  4118. duration = GNUNET_TIME_absolute_get_duration (vl->last_fc_transmission);
  4119. /* OPTIMIZE-FC-BDP: decide sane criteria on when to do this, instead of doing
  4120. it always! */
  4121. /* For example, we should probably ONLY do this if a bit more than
  4122. an RTT has passed, or if the window changed "significantly" since
  4123. then. See vl->last_fc_rtt! NOTE: to do this properly, we also
  4124. need an estimate for the bandwidth-delay-product for the entire
  4125. VL, as that determines "significantly". We have the delay, but
  4126. the bandwidth statistics need to be added for the VL!*/(void) duration;
  4127. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4128. "Sending FC seq %u to %s with new window %llu\n",
  4129. (unsigned int) vl->fc_seq_gen,
  4130. GNUNET_i2s (&vl->target),
  4131. (unsigned long long) vl->incoming_fc_window_size);
  4132. monotime = GNUNET_TIME_absolute_get_monotonic (GST_cfg);
  4133. vl->last_fc_transmission = monotime;
  4134. fc.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL);
  4135. fc.header.size = htons (sizeof(fc));
  4136. fc.seq = htonl (vl->fc_seq_gen++);
  4137. fc.inbound_window_size = GNUNET_htonll (vl->incoming_fc_window_size);
  4138. fc.outbound_sent = GNUNET_htonll (vl->outbound_fc_window_size_used);
  4139. fc.outbound_window_size = GNUNET_htonll (vl->outbound_fc_window_size);
  4140. fc.sender_time = GNUNET_TIME_absolute_hton (monotime);
  4141. rtt = route_control_message_without_fc (&vl->target, &fc.header, RMO_NONE);
  4142. if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == rtt.rel_value_us)
  4143. {
  4144. rtt = GNUNET_TIME_UNIT_SECONDS;
  4145. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4146. "FC retransmission to %s failed, will retry in %s\n",
  4147. GNUNET_i2s (&vl->target),
  4148. GNUNET_STRINGS_relative_time_to_string (rtt, GNUNET_YES));
  4149. vl->last_fc_rtt = GNUNET_TIME_UNIT_ZERO;
  4150. }
  4151. else
  4152. {
  4153. /* OPTIMIZE-FC-BDP: rtt is not ideal, we can do better! */
  4154. vl->last_fc_rtt = rtt;
  4155. }
  4156. if (NULL != vl->fc_retransmit_task)
  4157. GNUNET_SCHEDULER_cancel (vl->fc_retransmit_task);
  4158. vl->fc_retransmit_task =
  4159. GNUNET_SCHEDULER_add_delayed (rtt, &consider_sending_fc, vl);
  4160. }
  4161. /**
  4162. * There is a message at the head of the pending messages for @a vl
  4163. * which may be ready for transmission. Check if a queue is ready to
  4164. * take it.
  4165. *
  4166. * This function must (1) check for flow control to ensure that we can
  4167. * right now send to @a vl, (2) check that the pending message in the
  4168. * queue is actually eligible, (3) determine if any applicable queue
  4169. * (direct neighbour or DVH path) is ready to accept messages, and
  4170. * (4) prioritize based on the preferences associated with the
  4171. * pending message.
  4172. *
  4173. * So yeah, easy.
  4174. *
  4175. * @param vl virtual link where we should check for transmission
  4176. */
  4177. static void
  4178. check_vl_transmission (struct VirtualLink *vl)
  4179. {
  4180. struct Neighbour *n = vl->n;
  4181. struct DistanceVector *dv = vl->dv;
  4182. struct GNUNET_TIME_Absolute now;
  4183. int elig;
  4184. /* Check that we have an eligible pending message!
  4185. (cheaper than having #transmit_on_queue() find out!) */
  4186. elig = GNUNET_NO;
  4187. for (struct PendingMessage *pm = vl->pending_msg_head; NULL != pm;
  4188. pm = pm->next_vl)
  4189. {
  4190. if (NULL != pm->qe)
  4191. continue; /* not eligible, is in a queue! */
  4192. if (pm->bytes_msg + vl->outbound_fc_window_size_used >
  4193. vl->outbound_fc_window_size)
  4194. {
  4195. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4196. "Stalled transmision on VL %s due to flow control: %llu < %llu\n",
  4197. GNUNET_i2s (&vl->target),
  4198. (unsigned long long) vl->outbound_fc_window_size,
  4199. (unsigned long long) (pm->bytes_msg
  4200. + vl->outbound_fc_window_size_used));
  4201. consider_sending_fc (vl);
  4202. return; /* We have a message, but flow control says "nope" */
  4203. }
  4204. elig = GNUNET_YES;
  4205. break;
  4206. }
  4207. if (GNUNET_NO == elig)
  4208. return;
  4209. /* Notify queues at direct neighbours that we are interested */
  4210. now = GNUNET_TIME_absolute_get ();
  4211. if (NULL != n)
  4212. {
  4213. for (struct Queue *queue = n->queue_head; NULL != queue;
  4214. queue = queue->next_neighbour)
  4215. if ((GNUNET_YES == queue->idle) &&
  4216. (queue->validated_until.abs_value_us > now.abs_value_us))
  4217. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  4218. }
  4219. /* Notify queues via DV that we are interested */
  4220. if (NULL != dv)
  4221. {
  4222. /* Do DV with lower scheduler priority, which effectively means that
  4223. IF a neighbour exists and is available, we prefer it. */
  4224. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  4225. pos = pos->next_dv)
  4226. {
  4227. struct Neighbour *nh = pos->next_hop;
  4228. if (pos->path_valid_until.abs_value_us <= now.abs_value_us)
  4229. continue; /* skip this one: path not validated */
  4230. for (struct Queue *queue = nh->queue_head; NULL != queue;
  4231. queue = queue->next_neighbour)
  4232. if ((GNUNET_YES == queue->idle) &&
  4233. (queue->validated_until.abs_value_us > now.abs_value_us))
  4234. schedule_transmit_on_queue (queue,
  4235. GNUNET_SCHEDULER_PRIORITY_BACKGROUND);
  4236. }
  4237. }
  4238. }
  4239. /**
  4240. * Client asked for transmission to a peer. Process the request.
  4241. *
  4242. * @param cls the client
  4243. * @param obm the send message that was sent
  4244. */
  4245. static void
  4246. handle_client_send (void *cls, const struct OutboundMessage *obm)
  4247. {
  4248. struct TransportClient *tc = cls;
  4249. struct PendingMessage *pm;
  4250. const struct GNUNET_MessageHeader *obmm;
  4251. uint32_t bytes_msg;
  4252. struct VirtualLink *vl;
  4253. enum GNUNET_MQ_PriorityPreferences pp;
  4254. GNUNET_assert (CT_CORE == tc->type);
  4255. obmm = (const struct GNUNET_MessageHeader *) &obm[1];
  4256. bytes_msg = ntohs (obmm->size);
  4257. pp = (enum GNUNET_MQ_PriorityPreferences) ntohl (obm->priority);
  4258. vl = lookup_virtual_link (&obm->peer);
  4259. if (NULL == vl)
  4260. {
  4261. /* Failure: don't have this peer as a neighbour (anymore).
  4262. Might have gone down asynchronously, so this is NOT
  4263. a protocol violation by CORE. Still count the event,
  4264. as this should be rare. */
  4265. GNUNET_SERVICE_client_continue (tc->client);
  4266. GNUNET_STATISTICS_update (GST_stats,
  4267. "# messages dropped (neighbour unknown)",
  4268. 1,
  4269. GNUNET_NO);
  4270. return;
  4271. }
  4272. pm = GNUNET_malloc (sizeof(struct PendingMessage) + bytes_msg);
  4273. pm->logging_uuid = logging_uuid_gen++;
  4274. pm->prefs = pp;
  4275. pm->client = tc;
  4276. pm->vl = vl;
  4277. pm->bytes_msg = bytes_msg;
  4278. memcpy (&pm[1], obmm, bytes_msg);
  4279. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4280. "Sending %u bytes as <%llu> to %s\n",
  4281. bytes_msg,
  4282. pm->logging_uuid,
  4283. GNUNET_i2s (&obm->peer));
  4284. GNUNET_CONTAINER_MDLL_insert (client,
  4285. tc->details.core.pending_msg_head,
  4286. tc->details.core.pending_msg_tail,
  4287. pm);
  4288. GNUNET_CONTAINER_MDLL_insert (vl,
  4289. vl->pending_msg_head,
  4290. vl->pending_msg_tail,
  4291. pm);
  4292. check_vl_transmission (vl);
  4293. }
  4294. /**
  4295. * Communicator requests backchannel transmission. Process the request.
  4296. * Just repacks it into our `struct TransportBackchannelEncapsulationMessage *`
  4297. * (which for now has exactly the same format, only a different message type)
  4298. * and passes it on for routing.
  4299. *
  4300. * @param cls the client
  4301. * @param cb the send message that was sent
  4302. */
  4303. static void
  4304. handle_communicator_backchannel (
  4305. void *cls,
  4306. const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
  4307. {
  4308. struct TransportClient *tc = cls;
  4309. const struct GNUNET_MessageHeader *inbox =
  4310. (const struct GNUNET_MessageHeader *) &cb[1];
  4311. uint16_t isize = ntohs (inbox->size);
  4312. const char *is = ((const char *) &cb[1]) + isize;
  4313. char
  4314. mbuf[isize
  4315. + sizeof(struct
  4316. TransportBackchannelEncapsulationMessage)] GNUNET_ALIGN;
  4317. struct TransportBackchannelEncapsulationMessage *be =
  4318. (struct TransportBackchannelEncapsulationMessage *) mbuf;
  4319. /* 0-termination of 'is' was checked already in
  4320. #check_communicator_backchannel() */
  4321. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4322. "Preparing backchannel transmission to %s:%s of type %u\n",
  4323. GNUNET_i2s (&cb->pid),
  4324. is,
  4325. ntohs (inbox->size));
  4326. /* encapsulate and encrypt message */
  4327. be->header.type =
  4328. htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION);
  4329. be->header.size = htons (sizeof(mbuf));
  4330. memcpy (&be[1], inbox, isize);
  4331. memcpy (&mbuf[sizeof(struct TransportBackchannelEncapsulationMessage)
  4332. + isize],
  4333. is,
  4334. strlen (is) + 1);
  4335. route_control_message_without_fc (&cb->pid, &be->header, RMO_DV_ALLOWED);
  4336. GNUNET_SERVICE_client_continue (tc->client);
  4337. }
  4338. /**
  4339. * Address of our peer added. Test message is well-formed.
  4340. *
  4341. * @param cls the client
  4342. * @param aam the send message that was sent
  4343. * @return #GNUNET_OK if message is well-formed
  4344. */
  4345. static int
  4346. check_add_address (void *cls,
  4347. const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
  4348. {
  4349. struct TransportClient *tc = cls;
  4350. if (CT_COMMUNICATOR != tc->type)
  4351. {
  4352. GNUNET_break (0);
  4353. return GNUNET_SYSERR;
  4354. }
  4355. GNUNET_MQ_check_zero_termination (aam);
  4356. return GNUNET_OK;
  4357. }
  4358. /**
  4359. * Ask peerstore to store our address.
  4360. *
  4361. * @param cls an `struct AddressListEntry *`
  4362. */
  4363. static void
  4364. store_pi (void *cls);
  4365. /**
  4366. * Function called when peerstore is done storing our address.
  4367. *
  4368. * @param cls a `struct AddressListEntry`
  4369. * @param success #GNUNET_YES if peerstore was successful
  4370. */
  4371. static void
  4372. peerstore_store_own_cb (void *cls, int success)
  4373. {
  4374. struct AddressListEntry *ale = cls;
  4375. ale->sc = NULL;
  4376. if (GNUNET_YES != success)
  4377. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  4378. "Failed to store our own address `%s' in peerstore!\n",
  4379. ale->address);
  4380. else
  4381. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4382. "Successfully stored our own address `%s' in peerstore!\n",
  4383. ale->address);
  4384. /* refresh period is 1/4 of expiration time, that should be plenty
  4385. without being excessive. */
  4386. ale->st =
  4387. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
  4388. 4ULL),
  4389. &store_pi,
  4390. ale);
  4391. }
  4392. /**
  4393. * Ask peerstore to store our address.
  4394. *
  4395. * @param cls an `struct AddressListEntry *`
  4396. */
  4397. static void
  4398. store_pi (void *cls)
  4399. {
  4400. struct AddressListEntry *ale = cls;
  4401. void *addr;
  4402. size_t addr_len;
  4403. struct GNUNET_TIME_Absolute expiration;
  4404. ale->st = NULL;
  4405. expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
  4406. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4407. "Storing our address `%s' in peerstore until %s!\n",
  4408. ale->address,
  4409. GNUNET_STRINGS_absolute_time_to_string (expiration));
  4410. GNUNET_HELLO_sign_address (ale->address,
  4411. ale->nt,
  4412. hello_mono_time,
  4413. GST_my_private_key,
  4414. &addr,
  4415. &addr_len);
  4416. ale->sc = GNUNET_PEERSTORE_store (peerstore,
  4417. "transport",
  4418. &GST_my_identity,
  4419. GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
  4420. addr,
  4421. addr_len,
  4422. expiration,
  4423. GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
  4424. &peerstore_store_own_cb,
  4425. ale);
  4426. GNUNET_free (addr);
  4427. if (NULL == ale->sc)
  4428. {
  4429. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  4430. "Failed to store our address `%s' with peerstore\n",
  4431. ale->address);
  4432. ale->st =
  4433. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &store_pi, ale);
  4434. }
  4435. }
  4436. /**
  4437. * Address of our peer added. Process the request.
  4438. *
  4439. * @param cls the client
  4440. * @param aam the send message that was sent
  4441. */
  4442. static void
  4443. handle_add_address (void *cls,
  4444. const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
  4445. {
  4446. struct TransportClient *tc = cls;
  4447. struct AddressListEntry *ale;
  4448. size_t slen;
  4449. /* 0-termination of &aam[1] was checked in #check_add_address */
  4450. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4451. "Communicator added address `%s'!\n",
  4452. (const char *) &aam[1]);
  4453. slen = ntohs (aam->header.size) - sizeof(*aam);
  4454. ale = GNUNET_malloc (sizeof(struct AddressListEntry) + slen);
  4455. ale->tc = tc;
  4456. ale->address = (const char *) &ale[1];
  4457. ale->expiration = GNUNET_TIME_relative_ntoh (aam->expiration);
  4458. ale->aid = aam->aid;
  4459. ale->nt = (enum GNUNET_NetworkType) ntohl (aam->nt);
  4460. memcpy (&ale[1], &aam[1], slen);
  4461. GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
  4462. tc->details.communicator.addr_tail,
  4463. ale);
  4464. ale->st = GNUNET_SCHEDULER_add_now (&store_pi, ale);
  4465. GNUNET_SERVICE_client_continue (tc->client);
  4466. }
  4467. /**
  4468. * Address of our peer deleted. Process the request.
  4469. *
  4470. * @param cls the client
  4471. * @param dam the send message that was sent
  4472. */
  4473. static void
  4474. handle_del_address (void *cls,
  4475. const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
  4476. {
  4477. struct TransportClient *tc = cls;
  4478. struct AddressListEntry *alen;
  4479. if (CT_COMMUNICATOR != tc->type)
  4480. {
  4481. GNUNET_break (0);
  4482. GNUNET_SERVICE_client_drop (tc->client);
  4483. return;
  4484. }
  4485. for (struct AddressListEntry *ale = tc->details.communicator.addr_head;
  4486. NULL != ale;
  4487. ale = alen)
  4488. {
  4489. alen = ale->next;
  4490. if (dam->aid != ale->aid)
  4491. continue;
  4492. GNUNET_assert (ale->tc == tc);
  4493. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4494. "Communicator deleted address `%s'!\n",
  4495. ale->address);
  4496. free_address_list_entry (ale);
  4497. GNUNET_SERVICE_client_continue (tc->client);
  4498. }
  4499. GNUNET_break (0);
  4500. GNUNET_SERVICE_client_drop (tc->client);
  4501. }
  4502. /**
  4503. * Given an inbound message @a msg from a communicator @a cmc,
  4504. * demultiplex it based on the type calling the right handler.
  4505. *
  4506. * @param cmc context for demultiplexing
  4507. * @param msg message to demultiplex
  4508. */
  4509. static void
  4510. demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
  4511. const struct GNUNET_MessageHeader *msg);
  4512. /**
  4513. * Function called when we are done giving a message of a certain
  4514. * size to CORE and should thus decrement the number of bytes of
  4515. * RAM reserved for that peer's MQ.
  4516. *
  4517. * @param cls a `struct CoreSentContext`
  4518. */
  4519. static void
  4520. core_env_sent_cb (void *cls)
  4521. {
  4522. struct CoreSentContext *ctx = cls;
  4523. struct VirtualLink *vl = ctx->vl;
  4524. if (NULL == vl)
  4525. {
  4526. /* lost the link in the meantime, ignore */
  4527. GNUNET_free (ctx);
  4528. return;
  4529. }
  4530. GNUNET_CONTAINER_DLL_remove (vl->csc_head, vl->csc_tail, ctx);
  4531. GNUNET_assert (vl->incoming_fc_window_size_ram >= ctx->size);
  4532. vl->incoming_fc_window_size_ram -= ctx->size;
  4533. vl->incoming_fc_window_size_used += ctx->isize;
  4534. consider_sending_fc (vl);
  4535. GNUNET_free (ctx);
  4536. }
  4537. /**
  4538. * Communicator gave us an unencapsulated message to pass as-is to
  4539. * CORE. Process the request.
  4540. *
  4541. * @param cls a `struct CommunicatorMessageContext` (must call
  4542. * #finish_cmc_handling() when done)
  4543. * @param mh the message that was received
  4544. */
  4545. static void
  4546. handle_raw_message (void *cls, const struct GNUNET_MessageHeader *mh)
  4547. {
  4548. struct CommunicatorMessageContext *cmc = cls;
  4549. struct VirtualLink *vl;
  4550. uint16_t size = ntohs (mh->size);
  4551. int have_core;
  4552. if ((size > UINT16_MAX - sizeof(struct InboundMessage)) ||
  4553. (size < sizeof(struct GNUNET_MessageHeader)))
  4554. {
  4555. struct GNUNET_SERVICE_Client *client = cmc->tc->client;
  4556. GNUNET_break (0);
  4557. finish_cmc_handling (cmc);
  4558. GNUNET_SERVICE_client_drop (client);
  4559. return;
  4560. }
  4561. vl = lookup_virtual_link (&cmc->im.sender);
  4562. if (NULL == vl)
  4563. {
  4564. /* FIXME: sender is giving us messages for CORE but we don't have
  4565. the link up yet! I *suspect* this can happen right now (i.e.
  4566. sender has verified us, but we didn't verify sender), but if
  4567. we pass this on, CORE would be confused (link down, messages
  4568. arrive). We should investigate more if this happens often,
  4569. or in a persistent manner, and possibly do "something" about
  4570. it. Thus logging as error for now. */GNUNET_break_op (0);
  4571. GNUNET_STATISTICS_update (GST_stats,
  4572. "# CORE messages droped (virtual link still down)",
  4573. 1,
  4574. GNUNET_NO);
  4575. finish_cmc_handling (cmc);
  4576. return;
  4577. }
  4578. if (vl->incoming_fc_window_size_ram > UINT_MAX - size)
  4579. {
  4580. GNUNET_STATISTICS_update (GST_stats,
  4581. "# CORE messages droped (FC arithmetic overflow)",
  4582. 1,
  4583. GNUNET_NO);
  4584. finish_cmc_handling (cmc);
  4585. return;
  4586. }
  4587. if (vl->incoming_fc_window_size_ram + size > vl->available_fc_window_size)
  4588. {
  4589. GNUNET_STATISTICS_update (GST_stats,
  4590. "# CORE messages droped (FC window overflow)",
  4591. 1,
  4592. GNUNET_NO);
  4593. finish_cmc_handling (cmc);
  4594. return;
  4595. }
  4596. /* Forward to all CORE clients */
  4597. have_core = GNUNET_NO;
  4598. for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
  4599. {
  4600. struct GNUNET_MQ_Envelope *env;
  4601. struct InboundMessage *im;
  4602. struct CoreSentContext *ctx;
  4603. if (CT_CORE != tc->type)
  4604. continue;
  4605. vl->incoming_fc_window_size_ram += size;
  4606. env = GNUNET_MQ_msg_extra (im, size, GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
  4607. ctx = GNUNET_new (struct CoreSentContext);
  4608. ctx->vl = vl;
  4609. ctx->size = size;
  4610. ctx->isize = (GNUNET_NO == have_core) ? size : 0;
  4611. have_core = GNUNET_YES;
  4612. GNUNET_CONTAINER_DLL_insert (vl->csc_head, vl->csc_tail, ctx);
  4613. GNUNET_MQ_notify_sent (env, &core_env_sent_cb, ctx);
  4614. im->peer = cmc->im.sender;
  4615. memcpy (&im[1], mh, size);
  4616. GNUNET_MQ_send (tc->mq, env);
  4617. vl->core_recv_window--;
  4618. }
  4619. if (GNUNET_NO == have_core)
  4620. {
  4621. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  4622. "Dropped message to CORE: no CORE client connected!\n");
  4623. /* Nevertheless, count window as used, as it is from the
  4624. perspective of the other peer! */
  4625. vl->incoming_fc_window_size_used += size;
  4626. /* TODO-M1 */
  4627. finish_cmc_handling (cmc);
  4628. return;
  4629. }
  4630. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4631. "Delivered message from %s of type %u to CORE\n",
  4632. GNUNET_i2s (&cmc->im.sender),
  4633. ntohs (mh->type));
  4634. if (vl->core_recv_window > 0)
  4635. {
  4636. finish_cmc_handling (cmc);
  4637. return;
  4638. }
  4639. /* Wait with calling #finish_cmc_handling(cmc) until the message
  4640. was processed by CORE MQs (for CORE flow control)! */
  4641. GNUNET_CONTAINER_DLL_insert (vl->cmc_head, vl->cmc_tail, cmc);
  4642. }
  4643. /**
  4644. * Communicator gave us a fragment box. Check the message.
  4645. *
  4646. * @param cls a `struct CommunicatorMessageContext`
  4647. * @param fb the send message that was sent
  4648. * @return #GNUNET_YES if message is well-formed
  4649. */
  4650. static int
  4651. check_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
  4652. {
  4653. uint16_t size = ntohs (fb->header.size);
  4654. uint16_t bsize = size - sizeof(*fb);
  4655. (void) cls;
  4656. if (0 == bsize)
  4657. {
  4658. GNUNET_break_op (0);
  4659. return GNUNET_SYSERR;
  4660. }
  4661. if (bsize + ntohs (fb->frag_off) > ntohs (fb->msg_size))
  4662. {
  4663. GNUNET_break_op (0);
  4664. return GNUNET_SYSERR;
  4665. }
  4666. if (ntohs (fb->frag_off) >= ntohs (fb->msg_size))
  4667. {
  4668. GNUNET_break_op (0);
  4669. return GNUNET_SYSERR;
  4670. }
  4671. return GNUNET_YES;
  4672. }
  4673. /**
  4674. * Clean up an idle cummulative acknowledgement data structure.
  4675. *
  4676. * @param cls a `struct AcknowledgementCummulator *`
  4677. */
  4678. static void
  4679. destroy_ack_cummulator (void *cls)
  4680. {
  4681. struct AcknowledgementCummulator *ac = cls;
  4682. ac->task = NULL;
  4683. GNUNET_assert (0 == ac->num_acks);
  4684. GNUNET_assert (
  4685. GNUNET_YES ==
  4686. GNUNET_CONTAINER_multipeermap_remove (ack_cummulators, &ac->target, ac));
  4687. GNUNET_free (ac);
  4688. }
  4689. /**
  4690. * Do the transmission of a cummulative acknowledgement now.
  4691. *
  4692. * @param cls a `struct AcknowledgementCummulator *`
  4693. */
  4694. static void
  4695. transmit_cummulative_ack_cb (void *cls)
  4696. {
  4697. struct AcknowledgementCummulator *ac = cls;
  4698. char buf[sizeof(struct TransportReliabilityAckMessage)
  4699. + ac->ack_counter
  4700. * sizeof(struct TransportCummulativeAckPayloadP)] GNUNET_ALIGN;
  4701. struct TransportReliabilityAckMessage *ack =
  4702. (struct TransportReliabilityAckMessage *) buf;
  4703. struct TransportCummulativeAckPayloadP *ap;
  4704. ac->task = NULL;
  4705. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4706. "Sending ACK with %u components to %s\n",
  4707. ac->ack_counter,
  4708. GNUNET_i2s (&ac->target));
  4709. GNUNET_assert (0 < ac->ack_counter);
  4710. ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
  4711. ack->header.size =
  4712. htons (sizeof(*ack)
  4713. + ac->ack_counter * sizeof(struct TransportCummulativeAckPayloadP));
  4714. ack->ack_counter = htonl (ac->ack_counter++);
  4715. ap = (struct TransportCummulativeAckPayloadP *) &ack[1];
  4716. for (unsigned int i = 0; i < ac->ack_counter; i++)
  4717. {
  4718. ap[i].ack_uuid = ac->ack_uuids[i].ack_uuid;
  4719. ap[i].ack_delay = GNUNET_TIME_relative_hton (
  4720. GNUNET_TIME_absolute_get_duration (ac->ack_uuids[i].receive_time));
  4721. }
  4722. route_control_message_without_fc (&ac->target, &ack->header, RMO_DV_ALLOWED);
  4723. ac->num_acks = 0;
  4724. ac->task = GNUNET_SCHEDULER_add_delayed (ACK_CUMMULATOR_TIMEOUT,
  4725. &destroy_ack_cummulator,
  4726. ac);
  4727. }
  4728. /**
  4729. * Transmit an acknowledgement for @a ack_uuid to @a pid delaying
  4730. * transmission by at most @a ack_delay.
  4731. *
  4732. * @param pid target peer
  4733. * @param ack_uuid UUID to ack
  4734. * @param max_delay how long can the ACK wait
  4735. */
  4736. static void
  4737. cummulative_ack (const struct GNUNET_PeerIdentity *pid,
  4738. const struct AcknowledgementUUIDP *ack_uuid,
  4739. struct GNUNET_TIME_Absolute max_delay)
  4740. {
  4741. struct AcknowledgementCummulator *ac;
  4742. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4743. "Scheduling ACK %s for transmission to %s\n",
  4744. GNUNET_uuid2s (&ack_uuid->value),
  4745. GNUNET_i2s (pid));
  4746. ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid);
  4747. if (NULL == ac)
  4748. {
  4749. ac = GNUNET_new (struct AcknowledgementCummulator);
  4750. ac->target = *pid;
  4751. ac->min_transmission_time = max_delay;
  4752. GNUNET_assert (GNUNET_YES ==
  4753. GNUNET_CONTAINER_multipeermap_put (
  4754. ack_cummulators,
  4755. &ac->target,
  4756. ac,
  4757. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  4758. }
  4759. else
  4760. {
  4761. if (MAX_CUMMULATIVE_ACKS == ac->num_acks)
  4762. {
  4763. /* must run immediately, ack buffer full! */
  4764. GNUNET_SCHEDULER_cancel (ac->task);
  4765. transmit_cummulative_ack_cb (ac);
  4766. }
  4767. GNUNET_SCHEDULER_cancel (ac->task);
  4768. ac->min_transmission_time =
  4769. GNUNET_TIME_absolute_min (ac->min_transmission_time, max_delay);
  4770. }
  4771. GNUNET_assert (ac->num_acks < MAX_CUMMULATIVE_ACKS);
  4772. ac->ack_uuids[ac->num_acks].receive_time = GNUNET_TIME_absolute_get ();
  4773. ac->ack_uuids[ac->num_acks].ack_uuid = *ack_uuid;
  4774. ac->num_acks++;
  4775. ac->task = GNUNET_SCHEDULER_add_at (ac->min_transmission_time,
  4776. &transmit_cummulative_ack_cb,
  4777. ac);
  4778. }
  4779. /**
  4780. * Closure for #find_by_message_uuid.
  4781. */
  4782. struct FindByMessageUuidContext
  4783. {
  4784. /**
  4785. * UUID to look for.
  4786. */
  4787. struct MessageUUIDP message_uuid;
  4788. /**
  4789. * Set to the reassembly context if found.
  4790. */
  4791. struct ReassemblyContext *rc;
  4792. };
  4793. /**
  4794. * Iterator called to find a reassembly context by the message UUID in the
  4795. * multihashmap32.
  4796. *
  4797. * @param cls a `struct FindByMessageUuidContext`
  4798. * @param key a key (unused)
  4799. * @param value a `struct ReassemblyContext`
  4800. * @return #GNUNET_YES if not found, #GNUNET_NO if found
  4801. */
  4802. static int
  4803. find_by_message_uuid (void *cls, uint32_t key, void *value)
  4804. {
  4805. struct FindByMessageUuidContext *fc = cls;
  4806. struct ReassemblyContext *rc = value;
  4807. (void) key;
  4808. if (0 == GNUNET_memcmp (&fc->message_uuid, &rc->msg_uuid))
  4809. {
  4810. fc->rc = rc;
  4811. return GNUNET_NO;
  4812. }
  4813. return GNUNET_YES;
  4814. }
  4815. /**
  4816. * Communicator gave us a fragment. Process the request.
  4817. *
  4818. * @param cls a `struct CommunicatorMessageContext` (must call
  4819. * #finish_cmc_handling() when done)
  4820. * @param fb the message that was received
  4821. */
  4822. static void
  4823. handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
  4824. {
  4825. struct CommunicatorMessageContext *cmc = cls;
  4826. struct Neighbour *n;
  4827. struct ReassemblyContext *rc;
  4828. const struct GNUNET_MessageHeader *msg;
  4829. uint16_t msize;
  4830. uint16_t fsize;
  4831. uint16_t frag_off;
  4832. char *target;
  4833. struct GNUNET_TIME_Relative cdelay;
  4834. struct FindByMessageUuidContext fc;
  4835. n = lookup_neighbour (&cmc->im.sender);
  4836. if (NULL == n)
  4837. {
  4838. struct GNUNET_SERVICE_Client *client = cmc->tc->client;
  4839. GNUNET_break (0);
  4840. finish_cmc_handling (cmc);
  4841. GNUNET_SERVICE_client_drop (client);
  4842. return;
  4843. }
  4844. if (NULL == n->reassembly_map)
  4845. {
  4846. n->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8);
  4847. n->reassembly_heap =
  4848. GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
  4849. n->reassembly_timeout_task =
  4850. GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION,
  4851. &reassembly_cleanup_task,
  4852. n);
  4853. }
  4854. msize = ntohs (fb->msg_size);
  4855. fc.message_uuid = fb->msg_uuid;
  4856. fc.rc = NULL;
  4857. (void) GNUNET_CONTAINER_multihashmap32_get_multiple (n->reassembly_map,
  4858. fb->msg_uuid.uuid,
  4859. &find_by_message_uuid,
  4860. &fc);
  4861. if (NULL == (rc = fc.rc))
  4862. {
  4863. rc = GNUNET_malloc (sizeof(*rc) + msize /* reassembly payload buffer */
  4864. + (msize + 7) / 8 * sizeof(uint8_t) /* bitfield */);
  4865. rc->msg_uuid = fb->msg_uuid;
  4866. rc->neighbour = n;
  4867. rc->msg_size = msize;
  4868. rc->reassembly_timeout =
  4869. GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION);
  4870. rc->last_frag = GNUNET_TIME_absolute_get ();
  4871. rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap,
  4872. rc,
  4873. rc->reassembly_timeout.abs_value_us);
  4874. GNUNET_assert (GNUNET_OK ==
  4875. GNUNET_CONTAINER_multihashmap32_put (
  4876. n->reassembly_map,
  4877. rc->msg_uuid.uuid,
  4878. rc,
  4879. GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  4880. target = (char *) &rc[1];
  4881. rc->bitfield = (uint8_t *) (target + rc->msg_size);
  4882. rc->msg_missing = rc->msg_size;
  4883. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4884. "Received fragment at offset %u/%u from %s for NEW message %u\n",
  4885. ntohs (fb->frag_off),
  4886. msize,
  4887. GNUNET_i2s (&cmc->im.sender),
  4888. (unsigned int) fb->msg_uuid.uuid);
  4889. }
  4890. else
  4891. {
  4892. target = (char *) &rc[1];
  4893. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4894. "Received fragment at offset %u/%u from %s for message %u\n",
  4895. ntohs (fb->frag_off),
  4896. msize,
  4897. GNUNET_i2s (&cmc->im.sender),
  4898. (unsigned int) fb->msg_uuid.uuid);
  4899. }
  4900. if (msize != rc->msg_size)
  4901. {
  4902. GNUNET_break (0);
  4903. finish_cmc_handling (cmc);
  4904. return;
  4905. }
  4906. /* reassemble */
  4907. fsize = ntohs (fb->header.size) - sizeof(*fb);
  4908. if (0 == fsize)
  4909. {
  4910. GNUNET_break (0);
  4911. finish_cmc_handling (cmc);
  4912. return;
  4913. }
  4914. frag_off = ntohs (fb->frag_off);
  4915. if (frag_off + fsize > msize)
  4916. {
  4917. /* Fragment (plus fragment size) exceeds message size! */
  4918. GNUNET_break_op (0);
  4919. finish_cmc_handling (cmc);
  4920. return;
  4921. }
  4922. memcpy (&target[frag_off], &fb[1], fsize);
  4923. /* update bitfield and msg_missing */
  4924. for (unsigned int i = frag_off; i < frag_off + fsize; i++)
  4925. {
  4926. if (0 == (rc->bitfield[i / 8] & (1 << (i % 8))))
  4927. {
  4928. rc->bitfield[i / 8] |= (1 << (i % 8));
  4929. rc->msg_missing--;
  4930. }
  4931. }
  4932. /* Compute cummulative ACK */
  4933. cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag);
  4934. cdelay = GNUNET_TIME_relative_multiply (cdelay, rc->msg_missing / fsize);
  4935. if (0 == rc->msg_missing)
  4936. cdelay = GNUNET_TIME_UNIT_ZERO;
  4937. cummulative_ack (&cmc->im.sender,
  4938. &fb->ack_uuid,
  4939. GNUNET_TIME_relative_to_absolute (cdelay));
  4940. rc->last_frag = GNUNET_TIME_absolute_get ();
  4941. /* is reassembly complete? */
  4942. if (0 != rc->msg_missing)
  4943. {
  4944. finish_cmc_handling (cmc);
  4945. return;
  4946. }
  4947. /* reassembly is complete, verify result */
  4948. msg = (const struct GNUNET_MessageHeader *) &rc[1];
  4949. if (ntohs (msg->size) != rc->msg_size)
  4950. {
  4951. GNUNET_break (0);
  4952. free_reassembly_context (rc);
  4953. finish_cmc_handling (cmc);
  4954. return;
  4955. }
  4956. /* successful reassembly */
  4957. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  4958. "Fragment reassembly complete for message %u\n",
  4959. (unsigned int) fb->msg_uuid.uuid);
  4960. /* FIXME: check that the resulting msg is NOT a
  4961. DV Box or Reliability Box, as that is NOT allowed! */
  4962. demultiplex_with_cmc (cmc, msg);
  4963. /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still
  4964. en-route and we forget that we finished this reassembly immediately!
  4965. -> keep around until timeout?
  4966. -> shorten timeout based on ACK? */
  4967. free_reassembly_context (rc);
  4968. }
  4969. /**
  4970. * Communicator gave us a reliability box. Check the message.
  4971. *
  4972. * @param cls a `struct CommunicatorMessageContext`
  4973. * @param rb the send message that was sent
  4974. * @return #GNUNET_YES if message is well-formed
  4975. */
  4976. static int
  4977. check_reliability_box (void *cls,
  4978. const struct TransportReliabilityBoxMessage *rb)
  4979. {
  4980. (void) cls;
  4981. GNUNET_MQ_check_boxed_message (rb);
  4982. return GNUNET_YES;
  4983. }
  4984. /**
  4985. * Communicator gave us a reliability box. Process the request.
  4986. *
  4987. * @param cls a `struct CommunicatorMessageContext` (must call
  4988. * #finish_cmc_handling() when done)
  4989. * @param rb the message that was received
  4990. */
  4991. static void
  4992. handle_reliability_box (void *cls,
  4993. const struct TransportReliabilityBoxMessage *rb)
  4994. {
  4995. struct CommunicatorMessageContext *cmc = cls;
  4996. const struct GNUNET_MessageHeader *inbox =
  4997. (const struct GNUNET_MessageHeader *) &rb[1];
  4998. struct GNUNET_TIME_Relative rtt;
  4999. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5000. "Received reliability box from %s with UUID %s of type %u\n",
  5001. GNUNET_i2s (&cmc->im.sender),
  5002. GNUNET_uuid2s (&rb->ack_uuid.value),
  5003. (unsigned int) ntohs (inbox->type));
  5004. rtt = GNUNET_TIME_UNIT_SECONDS; /* FIXME: should base this on "RTT", but we
  5005. do not really have an RTT for the
  5006. * incoming* queue (should we have
  5007. the sender add it to the rb message?) */
  5008. cummulative_ack (
  5009. &cmc->im.sender,
  5010. &rb->ack_uuid,
  5011. (0 == ntohl (rb->ack_countdown))
  5012. ? GNUNET_TIME_UNIT_ZERO_ABS
  5013. : GNUNET_TIME_relative_to_absolute (
  5014. GNUNET_TIME_relative_divide (rtt, 8 /* FIXME: magic constant */)));
  5015. /* continue with inner message */
  5016. /* FIXME: check that inbox is NOT a DV Box, fragment or another
  5017. reliability box (not allowed!) */
  5018. demultiplex_with_cmc (cmc, inbox);
  5019. }
  5020. /**
  5021. * Check if we have advanced to another age since the last time. If
  5022. * so, purge ancient statistics (more than GOODPUT_AGING_SLOTS before
  5023. * the current age)
  5024. *
  5025. * @param pd[in,out] data to update
  5026. * @param age current age
  5027. */
  5028. static void
  5029. update_pd_age (struct PerformanceData *pd, unsigned int age)
  5030. {
  5031. unsigned int sage;
  5032. if (age == pd->last_age)
  5033. return; /* nothing to do */
  5034. sage = GNUNET_MAX (pd->last_age, age - 2 * GOODPUT_AGING_SLOTS);
  5035. for (unsigned int i = sage; i <= age - GOODPUT_AGING_SLOTS; i++)
  5036. {
  5037. struct TransmissionHistoryEntry *the = &pd->the[i % GOODPUT_AGING_SLOTS];
  5038. the->bytes_sent = 0;
  5039. the->bytes_received = 0;
  5040. }
  5041. pd->last_age = age;
  5042. }
  5043. /**
  5044. * Update @a pd based on the latest @a rtt and the number of bytes
  5045. * that were confirmed to be successfully transmitted.
  5046. *
  5047. * @param pd[in,out] data to update
  5048. * @param rtt latest round-trip time
  5049. * @param bytes_transmitted_ok number of bytes receiver confirmed as received
  5050. */
  5051. static void
  5052. update_performance_data (struct PerformanceData *pd,
  5053. struct GNUNET_TIME_Relative rtt,
  5054. uint16_t bytes_transmitted_ok)
  5055. {
  5056. uint64_t nval = rtt.rel_value_us;
  5057. uint64_t oval = pd->aged_rtt.rel_value_us;
  5058. unsigned int age = get_age ();
  5059. struct TransmissionHistoryEntry *the = &pd->the[age % GOODPUT_AGING_SLOTS];
  5060. if (oval == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
  5061. pd->aged_rtt = rtt;
  5062. else
  5063. pd->aged_rtt.rel_value_us = (nval + 7 * oval) / 8;
  5064. update_pd_age (pd, age);
  5065. the->bytes_received += bytes_transmitted_ok;
  5066. }
  5067. /**
  5068. * We have successfully transmitted data via @a q, update metrics.
  5069. *
  5070. * @param q queue to update
  5071. * @param rtt round trip time observed
  5072. * @param bytes_transmitted_ok number of bytes successfully transmitted
  5073. */
  5074. static void
  5075. update_queue_performance (struct Queue *q,
  5076. struct GNUNET_TIME_Relative rtt,
  5077. uint16_t bytes_transmitted_ok)
  5078. {
  5079. update_performance_data (&q->pd, rtt, bytes_transmitted_ok);
  5080. }
  5081. /**
  5082. * We have successfully transmitted data via @a dvh, update metrics.
  5083. *
  5084. * @param dvh distance vector path data to update
  5085. * @param rtt round trip time observed
  5086. * @param bytes_transmitted_ok number of bytes successfully transmitted
  5087. */
  5088. static void
  5089. update_dvh_performance (struct DistanceVectorHop *dvh,
  5090. struct GNUNET_TIME_Relative rtt,
  5091. uint16_t bytes_transmitted_ok)
  5092. {
  5093. update_performance_data (&dvh->pd, rtt, bytes_transmitted_ok);
  5094. }
  5095. /**
  5096. * We have completed transmission of @a pm, remove it from
  5097. * the transmission queues (and if it is a fragment, continue
  5098. * up the tree as necessary).
  5099. *
  5100. * @param pm pending message that was transmitted
  5101. */
  5102. static void
  5103. completed_pending_message (struct PendingMessage *pm)
  5104. {
  5105. struct PendingMessage *pos;
  5106. switch (pm->pmt)
  5107. {
  5108. case PMT_CORE:
  5109. case PMT_RELIABILITY_BOX:
  5110. /* Full message sent, we are done */
  5111. client_send_response (pm);
  5112. return;
  5113. case PMT_FRAGMENT_BOX:
  5114. /* Fragment sent over reliabile channel */
  5115. free_fragment_tree (pm);
  5116. pos = pm->frag_parent;
  5117. GNUNET_CONTAINER_MDLL_remove (frag, pos->head_frag, pos->tail_frag, pm);
  5118. GNUNET_free (pm);
  5119. /* check if subtree is done */
  5120. while ((NULL == pos->head_frag) && (pos->frag_off == pos->bytes_msg) &&
  5121. (pos != pm))
  5122. {
  5123. pm = pos;
  5124. pos = pm->frag_parent;
  5125. GNUNET_CONTAINER_MDLL_remove (frag, pos->head_frag, pos->tail_frag, pm);
  5126. GNUNET_free (pm);
  5127. }
  5128. /* Was this the last applicable fragmment? */
  5129. if ((NULL == pos->head_frag) && (NULL == pos->frag_parent) &&
  5130. (pos->frag_off == pos->bytes_msg))
  5131. client_send_response (pos);
  5132. return;
  5133. case PMT_DV_BOX:
  5134. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5135. "Completed transmission of message %llu (DV Box)\n",
  5136. pm->logging_uuid);
  5137. free_pending_message (pm);
  5138. return;
  5139. }
  5140. }
  5141. /**
  5142. * The @a pa was acknowledged, process the acknowledgement.
  5143. *
  5144. * @param pa the pending acknowledgement that was satisfied
  5145. * @param ack_delay artificial delay from cummulative acks created by the
  5146. * other peer
  5147. */
  5148. static void
  5149. handle_acknowledged (struct PendingAcknowledgement *pa,
  5150. struct GNUNET_TIME_Relative ack_delay)
  5151. {
  5152. struct GNUNET_TIME_Relative delay;
  5153. delay = GNUNET_TIME_absolute_get_duration (pa->transmission_time);
  5154. if (delay.rel_value_us > ack_delay.rel_value_us)
  5155. delay = GNUNET_TIME_UNIT_ZERO;
  5156. else
  5157. delay = GNUNET_TIME_relative_subtract (delay, ack_delay);
  5158. if (NULL != pa->queue)
  5159. update_queue_performance (pa->queue, delay, pa->message_size);
  5160. if (NULL != pa->dvh)
  5161. update_dvh_performance (pa->dvh, delay, pa->message_size);
  5162. if (NULL != pa->pm)
  5163. completed_pending_message (pa->pm);
  5164. free_pending_acknowledgement (pa);
  5165. }
  5166. /**
  5167. * Communicator gave us a reliability ack. Check it is well-formed.
  5168. *
  5169. * @param cls a `struct CommunicatorMessageContext` (unused)
  5170. * @param ra the message that was received
  5171. * @return #GNUNET_Ok if @a ra is well-formed
  5172. */
  5173. static int
  5174. check_reliability_ack (void *cls,
  5175. const struct TransportReliabilityAckMessage *ra)
  5176. {
  5177. unsigned int n_acks;
  5178. (void) cls;
  5179. n_acks = (ntohs (ra->header.size) - sizeof(*ra))
  5180. / sizeof(struct TransportCummulativeAckPayloadP);
  5181. if (0 == n_acks)
  5182. {
  5183. GNUNET_break_op (0);
  5184. return GNUNET_SYSERR;
  5185. }
  5186. if ((ntohs (ra->header.size) - sizeof(*ra)) !=
  5187. n_acks * sizeof(struct TransportCummulativeAckPayloadP))
  5188. {
  5189. GNUNET_break_op (0);
  5190. return GNUNET_SYSERR;
  5191. }
  5192. return GNUNET_OK;
  5193. }
  5194. /**
  5195. * Communicator gave us a reliability ack. Process the request.
  5196. *
  5197. * @param cls a `struct CommunicatorMessageContext` (must call
  5198. * #finish_cmc_handling() when done)
  5199. * @param ra the message that was received
  5200. */
  5201. static void
  5202. handle_reliability_ack (void *cls,
  5203. const struct TransportReliabilityAckMessage *ra)
  5204. {
  5205. struct CommunicatorMessageContext *cmc = cls;
  5206. const struct TransportCummulativeAckPayloadP *ack;
  5207. unsigned int n_acks;
  5208. uint32_t ack_counter;
  5209. n_acks = (ntohs (ra->header.size) - sizeof(*ra))
  5210. / sizeof(struct TransportCummulativeAckPayloadP);
  5211. ack = (const struct TransportCummulativeAckPayloadP *) &ra[1];
  5212. for (unsigned int i = 0; i < n_acks; i++)
  5213. {
  5214. struct PendingAcknowledgement *pa =
  5215. GNUNET_CONTAINER_multiuuidmap_get (pending_acks, &ack[i].ack_uuid.value);
  5216. if (NULL == pa)
  5217. {
  5218. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  5219. "Received ACK from %s with UUID %s which is unknown to us!\n",
  5220. GNUNET_i2s (&cmc->im.sender),
  5221. GNUNET_uuid2s (&ack[i].ack_uuid.value));
  5222. GNUNET_STATISTICS_update (
  5223. GST_stats,
  5224. "# FRAGMENT_ACKS dropped, no matching pending message",
  5225. 1,
  5226. GNUNET_NO);
  5227. continue;
  5228. }
  5229. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5230. "Received ACK from %s with UUID %s\n",
  5231. GNUNET_i2s (&cmc->im.sender),
  5232. GNUNET_uuid2s (&ack[i].ack_uuid.value));
  5233. handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay));
  5234. }
  5235. ack_counter = htonl (ra->ack_counter);
  5236. (void) ack_counter; /* silence compiler warning for now */
  5237. // FIXME-OPTIMIZE: track ACK losses based on ack_counter somewhere!
  5238. // (DV and/or Neighbour?)
  5239. finish_cmc_handling (cmc);
  5240. }
  5241. /**
  5242. * Communicator gave us a backchannel encapsulation. Check the message.
  5243. *
  5244. * @param cls a `struct CommunicatorMessageContext`
  5245. * @param be the send message that was sent
  5246. * @return #GNUNET_YES if message is well-formed
  5247. */
  5248. static int
  5249. check_backchannel_encapsulation (
  5250. void *cls,
  5251. const struct TransportBackchannelEncapsulationMessage *be)
  5252. {
  5253. uint16_t size = ntohs (be->header.size) - sizeof(*be);
  5254. const struct GNUNET_MessageHeader *inbox =
  5255. (const struct GNUNET_MessageHeader *) &be[1];
  5256. const char *is;
  5257. uint16_t isize;
  5258. (void) cls;
  5259. if (ntohs (inbox->size) >= size)
  5260. {
  5261. GNUNET_break_op (0);
  5262. return GNUNET_SYSERR;
  5263. }
  5264. isize = ntohs (inbox->size);
  5265. is = ((const char *) inbox) + isize;
  5266. size -= isize;
  5267. if ('\0' != is[size - 1])
  5268. {
  5269. GNUNET_break_op (0);
  5270. return GNUNET_SYSERR;
  5271. }
  5272. return GNUNET_YES;
  5273. }
  5274. /**
  5275. * Communicator gave us a backchannel encapsulation. Process the request.
  5276. * (We are the destination of the backchannel here.)
  5277. *
  5278. * @param cls a `struct CommunicatorMessageContext` (must call
  5279. * #finish_cmc_handling() when done)
  5280. * @param be the message that was received
  5281. */
  5282. static void
  5283. handle_backchannel_encapsulation (
  5284. void *cls,
  5285. const struct TransportBackchannelEncapsulationMessage *be)
  5286. {
  5287. struct CommunicatorMessageContext *cmc = cls;
  5288. struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *cbi;
  5289. struct GNUNET_MQ_Envelope *env;
  5290. struct TransportClient *tc;
  5291. const struct GNUNET_MessageHeader *inbox =
  5292. (const struct GNUNET_MessageHeader *) &be[1];
  5293. uint16_t isize = ntohs (inbox->size);
  5294. const char *target_communicator = ((const char *) inbox) + isize;
  5295. /* Find client providing this communicator */
  5296. for (tc = clients_head; NULL != tc; tc = tc->next)
  5297. if ((CT_COMMUNICATOR == tc->type) &&
  5298. (0 ==
  5299. strcmp (tc->details.communicator.address_prefix, target_communicator)))
  5300. break;
  5301. if (NULL == tc)
  5302. {
  5303. char *stastr;
  5304. GNUNET_asprintf (
  5305. &stastr,
  5306. "# Backchannel message dropped: target communicator `%s' unknown",
  5307. target_communicator);
  5308. GNUNET_STATISTICS_update (GST_stats, stastr, 1, GNUNET_NO);
  5309. GNUNET_free (stastr);
  5310. return;
  5311. }
  5312. /* Finally, deliver backchannel message to communicator */
  5313. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5314. "Delivering backchannel message from %s of type %u to %s\n",
  5315. GNUNET_i2s (&cmc->im.sender),
  5316. ntohs (inbox->type),
  5317. target_communicator);
  5318. env = GNUNET_MQ_msg_extra (
  5319. cbi,
  5320. isize,
  5321. GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING);
  5322. cbi->pid = cmc->im.sender;
  5323. memcpy (&cbi[1], inbox, isize);
  5324. GNUNET_MQ_send (tc->mq, env);
  5325. }
  5326. /**
  5327. * Task called when we should check if any of the DV paths
  5328. * we have learned to a target are due for garbage collection.
  5329. *
  5330. * Collects stale paths, and possibly frees the entire DV
  5331. * entry if no paths are left. Otherwise re-schedules itself.
  5332. *
  5333. * @param cls a `struct DistanceVector`
  5334. */
  5335. static void
  5336. path_cleanup_cb (void *cls)
  5337. {
  5338. struct DistanceVector *dv = cls;
  5339. struct DistanceVectorHop *pos;
  5340. dv->timeout_task = NULL;
  5341. while (NULL != (pos = dv->dv_head))
  5342. {
  5343. GNUNET_assert (dv == pos->dv);
  5344. if (GNUNET_TIME_absolute_get_remaining (pos->timeout).rel_value_us > 0)
  5345. break;
  5346. free_distance_vector_hop (pos);
  5347. }
  5348. if (NULL == pos)
  5349. {
  5350. free_dv_route (dv);
  5351. return;
  5352. }
  5353. dv->timeout_task =
  5354. GNUNET_SCHEDULER_add_at (pos->timeout, &path_cleanup_cb, dv);
  5355. }
  5356. /**
  5357. * The @a hop is a validated path to the respective target
  5358. * peer and we should tell core about it -- and schedule
  5359. * a job to revoke the state.
  5360. *
  5361. * @param hop a path to some peer that is the reason for activation
  5362. */
  5363. static void
  5364. activate_core_visible_dv_path (struct DistanceVectorHop *hop)
  5365. {
  5366. struct DistanceVector *dv = hop->dv;
  5367. struct VirtualLink *vl;
  5368. vl = lookup_virtual_link (&dv->target);
  5369. if (NULL != vl)
  5370. {
  5371. /* Link was already up, remember dv is also now available and we are done */
  5372. vl->dv = dv;
  5373. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5374. "Virtual link to %s could now also use DV!\n",
  5375. GNUNET_i2s (&dv->target));
  5376. return;
  5377. }
  5378. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5379. "Creating new virtual link to %s using DV!\n",
  5380. GNUNET_i2s (&dv->target));
  5381. vl = GNUNET_new (struct VirtualLink);
  5382. vl->message_uuid_ctr =
  5383. GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
  5384. vl->target = dv->target;
  5385. vl->dv = dv;
  5386. dv->vl = vl;
  5387. vl->core_recv_window = RECV_WINDOW_SIZE;
  5388. vl->available_fc_window_size = DEFAULT_WINDOW_SIZE;
  5389. vl->visibility_task =
  5390. GNUNET_SCHEDULER_add_at (hop->path_valid_until, &check_link_down, vl);
  5391. GNUNET_break (GNUNET_YES ==
  5392. GNUNET_CONTAINER_multipeermap_put (
  5393. links,
  5394. &vl->target,
  5395. vl,
  5396. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  5397. consider_sending_fc (vl);
  5398. /* We lacked a confirmed connection to the target
  5399. before, so tell CORE about it (finally!) */
  5400. cores_send_connect_info (&dv->target);
  5401. }
  5402. /**
  5403. * We have learned a @a path through the network to some other peer, add it to
  5404. * our DV data structure (returning #GNUNET_YES on success).
  5405. *
  5406. * We do not add paths if we have a sufficient number of shorter
  5407. * paths to this target already (returning #GNUNET_NO).
  5408. *
  5409. * We also do not add problematic paths, like those where we lack the first
  5410. * hop in our neighbour list (i.e. due to a topology change) or where some
  5411. * non-first hop is in our neighbour list (returning #GNUNET_SYSERR).
  5412. *
  5413. * @param path the path we learned, path[0] should be us,
  5414. * and then path contains a valid path from us to
  5415. * `path[path_len-1]` path[1] should be a direct neighbour (we should check!)
  5416. * @param path_len number of entries on the @a path, at least three!
  5417. * @param network_latency how long does the message take from us to
  5418. * `path[path_len-1]`? set to "forever" if unknown
  5419. * @param path_valid_until how long is this path considered validated? Maybe
  5420. * be zero.
  5421. * @return #GNUNET_YES on success,
  5422. * #GNUNET_NO if we have better path(s) to the target
  5423. * #GNUNET_SYSERR if the path is useless and/or invalid
  5424. * (i.e. path[1] not a direct neighbour
  5425. * or path[i+1] is a direct neighbour for i>0)
  5426. */
  5427. static int
  5428. learn_dv_path (const struct GNUNET_PeerIdentity *path,
  5429. unsigned int path_len,
  5430. struct GNUNET_TIME_Relative network_latency,
  5431. struct GNUNET_TIME_Absolute path_valid_until)
  5432. {
  5433. struct DistanceVectorHop *hop;
  5434. struct DistanceVector *dv;
  5435. struct Neighbour *next_hop;
  5436. unsigned int shorter_distance;
  5437. if (path_len < 3)
  5438. {
  5439. /* what a boring path! not allowed! */
  5440. GNUNET_break (0);
  5441. return GNUNET_SYSERR;
  5442. }
  5443. GNUNET_assert (0 == GNUNET_memcmp (&GST_my_identity, &path[0]));
  5444. next_hop = lookup_neighbour (&path[1]);
  5445. if (NULL == next_hop)
  5446. {
  5447. /* next hop must be a neighbour, otherwise this whole thing is useless! */
  5448. GNUNET_break (0);
  5449. return GNUNET_SYSERR;
  5450. }
  5451. for (unsigned int i = 2; i < path_len; i++)
  5452. if (NULL != lookup_neighbour (&path[i]))
  5453. {
  5454. /* Useless path: we have a direct connection to some hop
  5455. in the middle of the path, so this one is not even
  5456. terribly useful for redundancy */
  5457. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  5458. "Path of %u hops useless: directly link to hop %u (%s)\n",
  5459. path_len,
  5460. i,
  5461. GNUNET_i2s (&path[i]));
  5462. GNUNET_STATISTICS_update (GST_stats,
  5463. "# Useless DV path ignored: hop is neighbour",
  5464. 1,
  5465. GNUNET_NO);
  5466. return GNUNET_SYSERR;
  5467. }
  5468. dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, &path[path_len - 1]);
  5469. if (NULL == dv)
  5470. {
  5471. dv = GNUNET_new (struct DistanceVector);
  5472. dv->target = path[path_len - 1];
  5473. dv->timeout_task = GNUNET_SCHEDULER_add_delayed (DV_PATH_VALIDITY_TIMEOUT,
  5474. &path_cleanup_cb,
  5475. dv);
  5476. GNUNET_assert (GNUNET_OK ==
  5477. GNUNET_CONTAINER_multipeermap_put (
  5478. dv_routes,
  5479. &dv->target,
  5480. dv,
  5481. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  5482. }
  5483. /* Check if we have this path already! */
  5484. shorter_distance = 0;
  5485. for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
  5486. pos = pos->next_dv)
  5487. {
  5488. if (pos->distance < path_len - 2)
  5489. shorter_distance++;
  5490. /* Note that the distances in 'pos' excludes us (path[0]) and
  5491. the next_hop (path[1]), so we need to subtract two
  5492. and check next_hop explicitly */
  5493. if ((pos->distance == path_len - 2) && (pos->next_hop == next_hop))
  5494. {
  5495. int match = GNUNET_YES;
  5496. for (unsigned int i = 0; i < pos->distance; i++)
  5497. {
  5498. if (0 != GNUNET_memcmp (&pos->path[i], &path[i + 2]))
  5499. {
  5500. match = GNUNET_NO;
  5501. break;
  5502. }
  5503. }
  5504. if (GNUNET_YES == match)
  5505. {
  5506. struct GNUNET_TIME_Relative last_timeout;
  5507. /* Re-discovered known path, update timeout */
  5508. GNUNET_STATISTICS_update (GST_stats,
  5509. "# Known DV path refreshed",
  5510. 1,
  5511. GNUNET_NO);
  5512. last_timeout = GNUNET_TIME_absolute_get_remaining (pos->timeout);
  5513. pos->timeout =
  5514. GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
  5515. pos->path_valid_until =
  5516. GNUNET_TIME_absolute_max (pos->path_valid_until, path_valid_until);
  5517. GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, pos);
  5518. GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, pos);
  5519. if (0 <
  5520. GNUNET_TIME_absolute_get_remaining (path_valid_until).rel_value_us)
  5521. activate_core_visible_dv_path (pos);
  5522. if (last_timeout.rel_value_us <
  5523. GNUNET_TIME_relative_subtract (DV_PATH_VALIDITY_TIMEOUT,
  5524. DV_PATH_DISCOVERY_FREQUENCY)
  5525. .rel_value_us)
  5526. {
  5527. /* Some peer send DV learn messages too often, we are learning
  5528. the same path faster than it would be useful; do not forward! */
  5529. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  5530. "Rediscovered path too quickly, not forwarding further\n");
  5531. return GNUNET_NO;
  5532. }
  5533. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5534. "Refreshed known path to %s, forwarding further\n",
  5535. GNUNET_i2s (&dv->target));
  5536. return GNUNET_YES;
  5537. }
  5538. }
  5539. }
  5540. /* Count how many shorter paths we have (incl. direct
  5541. neighbours) before simply giving up on this one! */
  5542. if (shorter_distance >= MAX_DV_PATHS_TO_TARGET)
  5543. {
  5544. /* We have a shorter path already! */
  5545. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5546. "Have many shorter DV paths %s, not forwarding further\n",
  5547. GNUNET_i2s (&dv->target));
  5548. return GNUNET_NO;
  5549. }
  5550. /* create new DV path entry */
  5551. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5552. "Discovered new DV path to %s\n",
  5553. GNUNET_i2s (&dv->target));
  5554. hop = GNUNET_malloc (sizeof(struct DistanceVectorHop)
  5555. + sizeof(struct GNUNET_PeerIdentity) * (path_len - 2));
  5556. hop->next_hop = next_hop;
  5557. hop->dv = dv;
  5558. hop->path = (const struct GNUNET_PeerIdentity *) &hop[1];
  5559. memcpy (&hop[1],
  5560. &path[2],
  5561. sizeof(struct GNUNET_PeerIdentity) * (path_len - 2));
  5562. hop->timeout = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
  5563. hop->path_valid_until = path_valid_until;
  5564. hop->distance = path_len - 2;
  5565. hop->pd.aged_rtt = network_latency;
  5566. GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, hop);
  5567. GNUNET_CONTAINER_MDLL_insert (neighbour,
  5568. next_hop->dv_head,
  5569. next_hop->dv_tail,
  5570. hop);
  5571. if (0 < GNUNET_TIME_absolute_get_remaining (path_valid_until).rel_value_us)
  5572. activate_core_visible_dv_path (hop);
  5573. return GNUNET_YES;
  5574. }
  5575. /**
  5576. * Communicator gave us a DV learn message. Check the message.
  5577. *
  5578. * @param cls a `struct CommunicatorMessageContext`
  5579. * @param dvl the send message that was sent
  5580. * @return #GNUNET_YES if message is well-formed
  5581. */
  5582. static int
  5583. check_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
  5584. {
  5585. uint16_t size = ntohs (dvl->header.size);
  5586. uint16_t num_hops = ntohs (dvl->num_hops);
  5587. const struct DVPathEntryP *hops = (const struct DVPathEntryP *) &dvl[1];
  5588. (void) cls;
  5589. if (size != sizeof(*dvl) + num_hops * sizeof(struct DVPathEntryP))
  5590. {
  5591. GNUNET_break_op (0);
  5592. return GNUNET_SYSERR;
  5593. }
  5594. if (num_hops > MAX_DV_HOPS_ALLOWED)
  5595. {
  5596. GNUNET_break_op (0);
  5597. return GNUNET_SYSERR;
  5598. }
  5599. for (unsigned int i = 0; i < num_hops; i++)
  5600. {
  5601. if (0 == GNUNET_memcmp (&dvl->initiator, &hops[i].hop))
  5602. {
  5603. GNUNET_break_op (0);
  5604. return GNUNET_SYSERR;
  5605. }
  5606. if (0 == GNUNET_memcmp (&GST_my_identity, &hops[i].hop))
  5607. {
  5608. GNUNET_break_op (0);
  5609. return GNUNET_SYSERR;
  5610. }
  5611. }
  5612. return GNUNET_YES;
  5613. }
  5614. /**
  5615. * Build and forward a DV learn message to @a next_hop.
  5616. *
  5617. * @param next_hop peer to send the message to
  5618. * @param msg message received
  5619. * @param bi_history bitmask specifying hops on path that were bidirectional
  5620. * @param nhops length of the @a hops array
  5621. * @param hops path the message traversed so far
  5622. * @param in_time when did we receive the message, used to calculate network
  5623. * delay
  5624. */
  5625. static void
  5626. forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
  5627. const struct TransportDVLearnMessage *msg,
  5628. uint16_t bi_history,
  5629. uint16_t nhops,
  5630. const struct DVPathEntryP *hops,
  5631. struct GNUNET_TIME_Absolute in_time)
  5632. {
  5633. struct DVPathEntryP *dhops;
  5634. char buf[sizeof(struct TransportDVLearnMessage)
  5635. + (nhops + 1) * sizeof(struct DVPathEntryP)] GNUNET_ALIGN;
  5636. struct TransportDVLearnMessage *fwd = (struct TransportDVLearnMessage *) buf;
  5637. struct GNUNET_TIME_Relative nnd;
  5638. /* compute message for forwarding */
  5639. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5640. "Forwarding DV learn message originating from %s to %s\n",
  5641. GNUNET_i2s (&msg->initiator),
  5642. GNUNET_i2s2 (next_hop));
  5643. GNUNET_assert (nhops < MAX_DV_HOPS_ALLOWED);
  5644. fwd->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
  5645. fwd->header.size = htons (sizeof(struct TransportDVLearnMessage)
  5646. + (nhops + 1) * sizeof(struct DVPathEntryP));
  5647. fwd->num_hops = htons (nhops + 1);
  5648. fwd->bidirectional = htons (bi_history);
  5649. nnd = GNUNET_TIME_relative_add (GNUNET_TIME_absolute_get_duration (in_time),
  5650. GNUNET_TIME_relative_ntoh (
  5651. msg->non_network_delay));
  5652. fwd->non_network_delay = GNUNET_TIME_relative_hton (nnd);
  5653. fwd->init_sig = msg->init_sig;
  5654. fwd->initiator = msg->initiator;
  5655. fwd->challenge = msg->challenge;
  5656. dhops = (struct DVPathEntryP *) &fwd[1];
  5657. GNUNET_memcpy (dhops, hops, sizeof(struct DVPathEntryP) * nhops);
  5658. dhops[nhops].hop = GST_my_identity;
  5659. {
  5660. struct DvHopPS dhp = {
  5661. .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP),
  5662. .purpose.size = htonl (sizeof(dhp)),
  5663. .pred = dhops[nhops - 1].hop,
  5664. .succ = *next_hop,
  5665. .challenge = msg->challenge
  5666. };
  5667. GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
  5668. &dhp,
  5669. &dhops[nhops].hop_sig);
  5670. }
  5671. route_control_message_without_fc (next_hop,
  5672. &fwd->header,
  5673. RMO_UNCONFIRMED_ALLOWED);
  5674. }
  5675. /**
  5676. * Check signature of type #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
  5677. *
  5678. * @param sender_monotonic_time monotonic time of the initiator
  5679. * @param init the signer
  5680. * @param challenge the challenge that was signed
  5681. * @param init_sig signature presumably by @a init
  5682. * @return #GNUNET_OK if the signature is valid
  5683. */
  5684. static int
  5685. validate_dv_initiator_signature (
  5686. struct GNUNET_TIME_AbsoluteNBO sender_monotonic_time,
  5687. const struct GNUNET_PeerIdentity *init,
  5688. const struct ChallengeNonceP *challenge,
  5689. const struct GNUNET_CRYPTO_EddsaSignature *init_sig)
  5690. {
  5691. struct DvInitPS ip = { .purpose.purpose = htonl (
  5692. GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
  5693. .purpose.size = htonl (sizeof(ip)),
  5694. .monotonic_time = sender_monotonic_time,
  5695. .challenge = *challenge };
  5696. if (
  5697. GNUNET_OK !=
  5698. GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR,
  5699. &ip,
  5700. init_sig,
  5701. &init->public_key))
  5702. {
  5703. GNUNET_break_op (0);
  5704. return GNUNET_SYSERR;
  5705. }
  5706. return GNUNET_OK;
  5707. }
  5708. /**
  5709. * Closure for #dv_neighbour_selection and #dv_neighbour_transmission.
  5710. */
  5711. struct NeighbourSelectionContext
  5712. {
  5713. /**
  5714. * Original message we received.
  5715. */
  5716. const struct TransportDVLearnMessage *dvl;
  5717. /**
  5718. * The hops taken.
  5719. */
  5720. const struct DVPathEntryP *hops;
  5721. /**
  5722. * Time we received the message.
  5723. */
  5724. struct GNUNET_TIME_Absolute in_time;
  5725. /**
  5726. * Offsets of the selected peers.
  5727. */
  5728. uint32_t selections[MAX_DV_DISCOVERY_SELECTION];
  5729. /**
  5730. * Number of peers eligible for selection.
  5731. */
  5732. unsigned int num_eligible;
  5733. /**
  5734. * Number of peers that were selected for forwarding.
  5735. */
  5736. unsigned int num_selections;
  5737. /**
  5738. * Number of hops in @e hops
  5739. */
  5740. uint16_t nhops;
  5741. /**
  5742. * Bitmap of bidirectional connections encountered.
  5743. */
  5744. uint16_t bi_history;
  5745. };
  5746. /**
  5747. * Function called for each neighbour during #handle_dv_learn.
  5748. *
  5749. * @param cls a `struct NeighbourSelectionContext *`
  5750. * @param pid identity of the peer
  5751. * @param value a `struct Neighbour`
  5752. * @return #GNUNET_YES (always)
  5753. */
  5754. static int
  5755. dv_neighbour_selection (void *cls,
  5756. const struct GNUNET_PeerIdentity *pid,
  5757. void *value)
  5758. {
  5759. struct NeighbourSelectionContext *nsc = cls;
  5760. (void) value;
  5761. if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator))
  5762. return GNUNET_YES; /* skip initiator */
  5763. for (unsigned int i = 0; i < nsc->nhops; i++)
  5764. if (0 == GNUNET_memcmp (pid, &nsc->hops[i].hop))
  5765. return GNUNET_YES;
  5766. /* skip peers on path */
  5767. nsc->num_eligible++;
  5768. return GNUNET_YES;
  5769. }
  5770. /**
  5771. * Function called for each neighbour during #handle_dv_learn.
  5772. * We call #forward_dv_learn() on the neighbour(s) selected
  5773. * during #dv_neighbour_selection().
  5774. *
  5775. * @param cls a `struct NeighbourSelectionContext *`
  5776. * @param pid identity of the peer
  5777. * @param value a `struct Neighbour`
  5778. * @return #GNUNET_YES (always)
  5779. */
  5780. static int
  5781. dv_neighbour_transmission (void *cls,
  5782. const struct GNUNET_PeerIdentity *pid,
  5783. void *value)
  5784. {
  5785. struct NeighbourSelectionContext *nsc = cls;
  5786. (void) value;
  5787. if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator))
  5788. return GNUNET_YES; /* skip initiator */
  5789. for (unsigned int i = 0; i < nsc->nhops; i++)
  5790. if (0 == GNUNET_memcmp (pid, &nsc->hops[i].hop))
  5791. return GNUNET_YES;
  5792. /* skip peers on path */
  5793. for (unsigned int i = 0; i < nsc->num_selections; i++)
  5794. {
  5795. if (nsc->selections[i] == nsc->num_eligible)
  5796. {
  5797. forward_dv_learn (pid,
  5798. nsc->dvl,
  5799. nsc->bi_history,
  5800. nsc->nhops,
  5801. nsc->hops,
  5802. nsc->in_time);
  5803. break;
  5804. }
  5805. }
  5806. nsc->num_eligible++;
  5807. return GNUNET_YES;
  5808. }
  5809. /**
  5810. * Computes the number of neighbours we should forward a DVInit
  5811. * message to given that it has so far taken @a hops_taken hops
  5812. * though the network and that the number of neighbours we have
  5813. * in total is @a neighbour_count, out of which @a eligible_count
  5814. * are not yet on the path.
  5815. *
  5816. * NOTE: technically we might want to include NSE in the formula to
  5817. * get a better grip on the overall network size. However, for now
  5818. * using NSE here would create a dependency issue in the build system.
  5819. * => Left for later, hardcoded to 50 for now.
  5820. *
  5821. * The goal of the fomula is that we want to reach a total of LOG(NSE)
  5822. * peers via DV (`target_total`). We want the reach to be spread out
  5823. * over various distances to the origin, with a bias towards shorter
  5824. * distances.
  5825. *
  5826. * We make the strong assumption that the network topology looks
  5827. * "similar" at other hops, in particular the @a neighbour_count
  5828. * should be comparable at other hops.
  5829. *
  5830. * If the local neighbourhood is densely connected, we expect that @a
  5831. * eligible_count is close to @a neighbour_count minus @a hops_taken
  5832. * as a lot of the path is already known. In that case, we should
  5833. * forward to few(er) peers to try to find a path out of the
  5834. * neighbourhood. OTOH, if @a eligible_count is close to @a
  5835. * neighbour_count, we should forward to many peers as we are either
  5836. * still close to the origin (i.e. @a hops_taken is small) or because
  5837. * we managed to get beyond a local cluster. We express this as
  5838. * the `boost_factor` using the square of the fraction of eligible
  5839. * neighbours (so if only 50% are eligible, we boost by 1/4, but if
  5840. * 99% are eligible, the 'boost' will be almost 1).
  5841. *
  5842. * Second, the more hops we have taken, the larger the problem of an
  5843. * exponential traffic explosion gets. So we take the `target_total`,
  5844. * and compute our degree such that at each distance d 2^{-d} peers
  5845. * are selected (corrected by the `boost_factor`).
  5846. *
  5847. * @param hops_taken number of hops DVInit has travelled so far
  5848. * @param neighbour_count number of neighbours we have in total
  5849. * @param eligible_count number of neighbours we could in
  5850. * theory forward to
  5851. */
  5852. static unsigned int
  5853. calculate_fork_degree (unsigned int hops_taken,
  5854. unsigned int neighbour_count,
  5855. unsigned int eligible_count)
  5856. {
  5857. double target_total = 50.0; /* FIXME: use LOG(NSE)? */
  5858. double eligible_ratio =
  5859. ((double) eligible_count) / ((double) neighbour_count);
  5860. double boost_factor = eligible_ratio * eligible_ratio;
  5861. unsigned int rnd;
  5862. double left;
  5863. if (hops_taken >= 64)
  5864. {
  5865. GNUNET_break (0);
  5866. return 0; /* precaution given bitshift below */
  5867. }
  5868. for (unsigned int i = 1; i < hops_taken; i++)
  5869. {
  5870. /* For each hop, subtract the expected number of targets
  5871. reached at distance d (so what remains divided by 2^d) */
  5872. target_total -= (target_total * boost_factor / (1LLU << i));
  5873. }
  5874. rnd =
  5875. (unsigned int) floor (target_total * boost_factor / (1LLU << hops_taken));
  5876. /* round up or down probabilistically depending on how close we were
  5877. when floor()ing to rnd */
  5878. left = target_total - (double) rnd;
  5879. if (UINT32_MAX * left >
  5880. GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX))
  5881. rnd++; /* round up */
  5882. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  5883. "Forwarding DV learn message of %u hops %u(/%u/%u) times\n",
  5884. hops_taken,
  5885. rnd,
  5886. eligible_count,
  5887. neighbour_count);
  5888. return rnd;
  5889. }
  5890. /**
  5891. * Function called when peerstore is done storing a DV monotonic time.
  5892. *
  5893. * @param cls a `struct Neighbour`
  5894. * @param success #GNUNET_YES if peerstore was successful
  5895. */
  5896. static void
  5897. neighbour_store_dvmono_cb (void *cls, int success)
  5898. {
  5899. struct Neighbour *n = cls;
  5900. n->sc = NULL;
  5901. if (GNUNET_YES != success)
  5902. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  5903. "Failed to store other peer's monotonic time in peerstore!\n");
  5904. }
  5905. /**
  5906. * Communicator gave us a DV learn message. Process the request.
  5907. *
  5908. * @param cls a `struct CommunicatorMessageContext` (must call
  5909. * #finish_cmc_handling() when done)
  5910. * @param dvl the message that was received
  5911. */
  5912. static void
  5913. handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
  5914. {
  5915. struct CommunicatorMessageContext *cmc = cls;
  5916. enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
  5917. int bi_hop;
  5918. uint16_t nhops;
  5919. uint16_t bi_history;
  5920. const struct DVPathEntryP *hops;
  5921. int do_fwd;
  5922. int did_initiator;
  5923. struct GNUNET_TIME_Absolute in_time;
  5924. struct Neighbour *n;
  5925. nhops = ntohs (dvl->bidirectional); /* 0 = sender is initiator */
  5926. bi_history = ntohs (dvl->bidirectional);
  5927. hops = (const struct DVPathEntryP *) &dvl[1];
  5928. if (0 == nhops)
  5929. {
  5930. /* sanity check */
  5931. if (0 != GNUNET_memcmp (&dvl->initiator, &cmc->im.sender))
  5932. {
  5933. GNUNET_break (0);
  5934. finish_cmc_handling (cmc);
  5935. return;
  5936. }
  5937. }
  5938. else
  5939. {
  5940. /* sanity check */
  5941. if (0 != GNUNET_memcmp (&hops[nhops - 1].hop, &cmc->im.sender))
  5942. {
  5943. GNUNET_break (0);
  5944. finish_cmc_handling (cmc);
  5945. return;
  5946. }
  5947. }
  5948. GNUNET_assert (CT_COMMUNICATOR == cmc->tc->type);
  5949. cc = cmc->tc->details.communicator.cc;
  5950. bi_hop = (GNUNET_TRANSPORT_CC_RELIABLE ==
  5951. cc); // FIXME: add bi-directional flag to cc?
  5952. in_time = GNUNET_TIME_absolute_get ();
  5953. /* continue communicator here, everything else can happen asynchronous! */
  5954. finish_cmc_handling (cmc);
  5955. n = lookup_neighbour (&dvl->initiator);
  5956. if (NULL != n)
  5957. {
  5958. if ((n->dv_monotime_available == GNUNET_YES) &&
  5959. (GNUNET_TIME_absolute_ntoh (dvl->monotonic_time).abs_value_us <
  5960. n->last_dv_learn_monotime.abs_value_us))
  5961. {
  5962. GNUNET_STATISTICS_update (GST_stats,
  5963. "# DV learn discarded due to time travel",
  5964. 1,
  5965. GNUNET_NO);
  5966. return;
  5967. }
  5968. if (GNUNET_OK != validate_dv_initiator_signature (dvl->monotonic_time,
  5969. &dvl->initiator,
  5970. &dvl->challenge,
  5971. &dvl->init_sig))
  5972. {
  5973. GNUNET_break_op (0);
  5974. return;
  5975. }
  5976. n->last_dv_learn_monotime = GNUNET_TIME_absolute_ntoh (dvl->monotonic_time);
  5977. if (GNUNET_YES == n->dv_monotime_available)
  5978. {
  5979. if (NULL != n->sc)
  5980. GNUNET_PEERSTORE_store_cancel (n->sc);
  5981. n->sc =
  5982. GNUNET_PEERSTORE_store (peerstore,
  5983. "transport",
  5984. &dvl->initiator,
  5985. GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME,
  5986. &dvl->monotonic_time,
  5987. sizeof(dvl->monotonic_time),
  5988. GNUNET_TIME_UNIT_FOREVER_ABS,
  5989. GNUNET_PEERSTORE_STOREOPTION_REPLACE,
  5990. &neighbour_store_dvmono_cb,
  5991. n);
  5992. }
  5993. }
  5994. /* OPTIMIZE-FIXME: asynchronously (!) verify signatures!,
  5995. If signature verification load too high, implement random drop strategy */
  5996. for (unsigned int i = 0; i < nhops; i++)
  5997. {
  5998. struct DvHopPS dhp = { .purpose.purpose =
  5999. htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP),
  6000. .purpose.size = htonl (sizeof(dhp)),
  6001. .pred = (0 == i) ? dvl->initiator : hops[i - 1].hop,
  6002. .succ = (nhops == i + 1) ? GST_my_identity
  6003. : hops[i + 1].hop,
  6004. .challenge = dvl->challenge };
  6005. if (GNUNET_OK !=
  6006. GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP,
  6007. &dhp,
  6008. &hops[i].hop_sig,
  6009. &hops[i].hop.public_key))
  6010. {
  6011. GNUNET_break_op (0);
  6012. return;
  6013. }
  6014. }
  6015. if (GNUNET_EXTRA_LOGGING > 0)
  6016. {
  6017. char *path;
  6018. path = GNUNET_strdup (GNUNET_i2s (&dvl->initiator));
  6019. for (unsigned int i = 0; i < nhops; i++)
  6020. {
  6021. char *tmp;
  6022. GNUNET_asprintf (&tmp,
  6023. "%s%s%s",
  6024. path,
  6025. (bi_history & (1 << (nhops - i))) ? "<->" : "-->",
  6026. GNUNET_i2s (&hops[i].hop));
  6027. GNUNET_free (path);
  6028. path = tmp;
  6029. }
  6030. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6031. "Received DVInit via %s%s%s\n",
  6032. path,
  6033. bi_hop ? "<->" : "-->",
  6034. GNUNET_i2s (&GST_my_identity));
  6035. GNUNET_free (path);
  6036. }
  6037. do_fwd = GNUNET_YES;
  6038. if (0 == GNUNET_memcmp (&GST_my_identity, &dvl->initiator))
  6039. {
  6040. struct GNUNET_PeerIdentity path[nhops + 1];
  6041. struct GNUNET_TIME_Relative host_latency_sum;
  6042. struct GNUNET_TIME_Relative latency;
  6043. struct GNUNET_TIME_Relative network_latency;
  6044. /* We initiated this, learn the forward path! */
  6045. path[0] = GST_my_identity;
  6046. path[1] = hops[0].hop;
  6047. host_latency_sum = GNUNET_TIME_relative_ntoh (dvl->non_network_delay);
  6048. // Need also something to lookup initiation time
  6049. // to compute RTT! -> add RTT argument here?
  6050. latency = GNUNET_TIME_UNIT_FOREVER_REL; // FIXME: initialize properly
  6051. // (based on dvl->challenge, we can identify time of origin!)
  6052. network_latency = GNUNET_TIME_relative_subtract (latency, host_latency_sum);
  6053. /* assumption: latency on all links is the same */
  6054. network_latency = GNUNET_TIME_relative_divide (network_latency, nhops);
  6055. for (unsigned int i = 2; i <= nhops; i++)
  6056. {
  6057. struct GNUNET_TIME_Relative ilat;
  6058. /* assumption: linear latency increase per hop */
  6059. ilat = GNUNET_TIME_relative_multiply (network_latency, i);
  6060. path[i] = hops[i - 1].hop;
  6061. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6062. "Learned path with %u hops to %s with latency %s\n",
  6063. i,
  6064. GNUNET_i2s (&path[i]),
  6065. GNUNET_STRINGS_relative_time_to_string (ilat, GNUNET_YES));
  6066. learn_dv_path (path,
  6067. i,
  6068. ilat,
  6069. GNUNET_TIME_relative_to_absolute (
  6070. ADDRESS_VALIDATION_LIFETIME));
  6071. }
  6072. /* as we initiated, do not forward again (would be circular!) */
  6073. do_fwd = GNUNET_NO;
  6074. return;
  6075. }
  6076. if (bi_hop)
  6077. {
  6078. /* last hop was bi-directional, we could learn something here! */
  6079. struct GNUNET_PeerIdentity path[nhops + 2];
  6080. path[0] = GST_my_identity;
  6081. path[1] = hops[nhops - 1].hop; /* direct neighbour == predecessor! */
  6082. for (unsigned int i = 0; i < nhops; i++)
  6083. {
  6084. int iret;
  6085. if (0 == (bi_history & (1 << i)))
  6086. break; /* i-th hop not bi-directional, stop learning! */
  6087. if (i == nhops - 1)
  6088. {
  6089. path[i + 2] = dvl->initiator;
  6090. }
  6091. else
  6092. {
  6093. path[i + 2] = hops[nhops - i - 2].hop;
  6094. }
  6095. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6096. "Learned inverse path with %u hops to %s\n",
  6097. i + 1,
  6098. GNUNET_i2s (&path[i + 2]));
  6099. iret = learn_dv_path (path,
  6100. i + 2,
  6101. GNUNET_TIME_UNIT_FOREVER_REL,
  6102. GNUNET_TIME_UNIT_ZERO_ABS);
  6103. if (GNUNET_SYSERR == iret)
  6104. {
  6105. /* path invalid or too long to be interesting for US, thus should also
  6106. not be interesting to our neighbours, cut path when forwarding to
  6107. 'i' hops, except of course for the one that goes back to the
  6108. initiator */
  6109. GNUNET_STATISTICS_update (GST_stats,
  6110. "# DV learn not forwarded due invalidity of path",
  6111. 1,
  6112. GNUNET_NO);
  6113. do_fwd = GNUNET_NO;
  6114. break;
  6115. }
  6116. if ((GNUNET_NO == iret) && (nhops == i + 1))
  6117. {
  6118. /* we have better paths, and this is the longest target,
  6119. so there cannot be anything interesting later */
  6120. GNUNET_STATISTICS_update (GST_stats,
  6121. "# DV learn not forwarded, got better paths",
  6122. 1,
  6123. GNUNET_NO);
  6124. do_fwd = GNUNET_NO;
  6125. break;
  6126. }
  6127. }
  6128. }
  6129. if (MAX_DV_HOPS_ALLOWED == nhops)
  6130. {
  6131. /* At limit, we're out of here! */
  6132. finish_cmc_handling (cmc);
  6133. return;
  6134. }
  6135. /* Forward to initiator, if path non-trivial and possible */
  6136. bi_history = (bi_history << 1) | (bi_hop ? 1 : 0);
  6137. did_initiator = GNUNET_NO;
  6138. if ((1 < nhops) &&
  6139. (GNUNET_YES ==
  6140. GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator)))
  6141. {
  6142. /* send back to origin! */
  6143. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6144. "Sending DVL back to initiator %s\n",
  6145. GNUNET_i2s (&dvl->initiator));
  6146. forward_dv_learn (&dvl->initiator, dvl, bi_history, nhops, hops, in_time);
  6147. did_initiator = GNUNET_YES;
  6148. }
  6149. /* We forward under two conditions: either we still learned something
  6150. ourselves (do_fwd), or the path was darn short and thus the initiator is
  6151. likely to still be very interested in this (and we did NOT already
  6152. send it back to the initiator) */
  6153. if ((do_fwd) || ((nhops < MIN_DV_PATH_LENGTH_FOR_INITIATOR) &&
  6154. (GNUNET_NO == did_initiator)))
  6155. {
  6156. /* Pick random neighbours that are not yet on the path */
  6157. struct NeighbourSelectionContext nsc;
  6158. unsigned int n_cnt;
  6159. n_cnt = GNUNET_CONTAINER_multipeermap_size (neighbours);
  6160. nsc.nhops = nhops;
  6161. nsc.dvl = dvl;
  6162. nsc.bi_history = bi_history;
  6163. nsc.hops = hops;
  6164. nsc.in_time = in_time;
  6165. nsc.num_eligible = 0;
  6166. GNUNET_CONTAINER_multipeermap_iterate (neighbours,
  6167. &dv_neighbour_selection,
  6168. &nsc);
  6169. if (0 == nsc.num_eligible)
  6170. return; /* done here, cannot forward to anyone else */
  6171. nsc.num_selections = calculate_fork_degree (nhops, n_cnt, nsc.num_eligible);
  6172. nsc.num_selections =
  6173. GNUNET_MIN (MAX_DV_DISCOVERY_SELECTION, nsc.num_selections);
  6174. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6175. "Forwarding DVL to %u other peers\n",
  6176. nsc.num_selections);
  6177. for (unsigned int i = 0; i < nsc.num_selections; i++)
  6178. nsc.selections[i] =
  6179. (nsc.num_selections == n_cnt)
  6180. ? i /* all were selected, avoid collisions by chance */
  6181. : GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, n_cnt);
  6182. nsc.num_eligible = 0;
  6183. GNUNET_CONTAINER_multipeermap_iterate (neighbours,
  6184. &dv_neighbour_transmission,
  6185. &nsc);
  6186. }
  6187. }
  6188. /**
  6189. * Communicator gave us a DV box. Check the message.
  6190. *
  6191. * @param cls a `struct CommunicatorMessageContext`
  6192. * @param dvb the send message that was sent
  6193. * @return #GNUNET_YES if message is well-formed
  6194. */
  6195. static int
  6196. check_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
  6197. {
  6198. uint16_t size = ntohs (dvb->header.size);
  6199. uint16_t num_hops = ntohs (dvb->num_hops);
  6200. const struct GNUNET_PeerIdentity *hops =
  6201. (const struct GNUNET_PeerIdentity *) &dvb[1];
  6202. (void) cls;
  6203. if (size < sizeof(*dvb) + num_hops * sizeof(struct GNUNET_PeerIdentity)
  6204. + sizeof(struct GNUNET_MessageHeader))
  6205. {
  6206. GNUNET_break_op (0);
  6207. return GNUNET_SYSERR;
  6208. }
  6209. /* This peer must not be on the path */
  6210. for (unsigned int i = 0; i < num_hops; i++)
  6211. if (0 == GNUNET_memcmp (&hops[i], &GST_my_identity))
  6212. {
  6213. GNUNET_break_op (0);
  6214. return GNUNET_SYSERR;
  6215. }
  6216. return GNUNET_YES;
  6217. }
  6218. /**
  6219. * Create a DV Box message and queue it for transmission to
  6220. * @ea next_hop.
  6221. *
  6222. * @param next_hop peer to receive the message next
  6223. * @param total_hops how many hops did the message take so far
  6224. * @param num_hops length of the @a hops array
  6225. * @param origin origin of the message
  6226. * @param hops next peer(s) to the destination, including destination
  6227. * @param payload payload of the box
  6228. * @param payload_size number of bytes in @a payload
  6229. */
  6230. static void
  6231. forward_dv_box (struct Neighbour *next_hop,
  6232. const struct TransportDVBoxMessage *hdr,
  6233. uint16_t total_hops,
  6234. uint16_t num_hops,
  6235. const struct GNUNET_PeerIdentity *hops,
  6236. const void *enc_payload,
  6237. uint16_t enc_payload_size)
  6238. {
  6239. struct VirtualLink *vl = next_hop->vl;
  6240. struct PendingMessage *pm;
  6241. size_t msg_size;
  6242. char *buf;
  6243. struct GNUNET_PeerIdentity *dhops;
  6244. GNUNET_assert (NULL != vl);
  6245. msg_size = sizeof(struct TransportDVBoxMessage)
  6246. + num_hops * sizeof(struct GNUNET_PeerIdentity) + enc_payload_size;
  6247. pm = GNUNET_malloc (sizeof(struct PendingMessage) + msg_size);
  6248. pm->pmt = PMT_DV_BOX;
  6249. pm->vl = vl;
  6250. pm->timeout = GNUNET_TIME_relative_to_absolute (DV_FORWARD_TIMEOUT);
  6251. pm->logging_uuid = logging_uuid_gen++;
  6252. pm->prefs = GNUNET_MQ_PRIO_BACKGROUND;
  6253. pm->bytes_msg = msg_size;
  6254. buf = (char *) &pm[1];
  6255. memcpy (buf, hdr, sizeof(*hdr));
  6256. dhops =
  6257. (struct GNUNET_PeerIdentity *) &buf[sizeof(struct TransportDVBoxMessage)];
  6258. memcpy (dhops, hops, num_hops * sizeof(struct GNUNET_PeerIdentity));
  6259. memcpy (&dhops[num_hops], enc_payload, enc_payload_size);
  6260. GNUNET_CONTAINER_MDLL_insert (vl,
  6261. vl->pending_msg_head,
  6262. vl->pending_msg_tail,
  6263. pm);
  6264. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6265. "Created pending message %llu for DV Box with next hop %s (%u/%u)\n",
  6266. pm->logging_uuid,
  6267. GNUNET_i2s (&next_hop->pid),
  6268. (unsigned int) num_hops,
  6269. (unsigned int) total_hops);
  6270. check_vl_transmission (vl);
  6271. }
  6272. /**
  6273. * Free data structures associated with @a b.
  6274. *
  6275. * @param b data structure to release
  6276. */
  6277. static void
  6278. free_backtalker (struct Backtalker *b)
  6279. {
  6280. if (NULL != b->get)
  6281. {
  6282. GNUNET_PEERSTORE_iterate_cancel (b->get);
  6283. b->get = NULL;
  6284. GNUNET_assert (NULL != b->cmc);
  6285. finish_cmc_handling (b->cmc);
  6286. b->cmc = NULL;
  6287. }
  6288. if (NULL != b->task)
  6289. {
  6290. GNUNET_SCHEDULER_cancel (b->task);
  6291. b->task = NULL;
  6292. }
  6293. if (NULL != b->sc)
  6294. {
  6295. GNUNET_PEERSTORE_store_cancel (b->sc);
  6296. b->sc = NULL;
  6297. }
  6298. GNUNET_assert (
  6299. GNUNET_YES ==
  6300. GNUNET_CONTAINER_multipeermap_remove (backtalkers, &b->pid, b));
  6301. GNUNET_free (b);
  6302. }
  6303. /**
  6304. * Callback to free backtalker records.
  6305. *
  6306. * @param cls NULL
  6307. * @param pid unused
  6308. * @param value a `struct Backtalker`
  6309. * @return #GNUNET_OK (always)
  6310. */
  6311. static int
  6312. free_backtalker_cb (void *cls,
  6313. const struct GNUNET_PeerIdentity *pid,
  6314. void *value)
  6315. {
  6316. struct Backtalker *b = value;
  6317. (void) cls;
  6318. (void) pid;
  6319. free_backtalker (b);
  6320. return GNUNET_OK;
  6321. }
  6322. /**
  6323. * Function called when it is time to clean up a backtalker.
  6324. *
  6325. * @param cls a `struct Backtalker`
  6326. */
  6327. static void
  6328. backtalker_timeout_cb (void *cls)
  6329. {
  6330. struct Backtalker *b = cls;
  6331. b->task = NULL;
  6332. if (0 != GNUNET_TIME_absolute_get_remaining (b->timeout).rel_value_us)
  6333. {
  6334. b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
  6335. return;
  6336. }
  6337. GNUNET_assert (NULL == b->sc);
  6338. free_backtalker (b);
  6339. }
  6340. /**
  6341. * Function called with the monotonic time of a backtalker
  6342. * by PEERSTORE. Updates the time and continues processing.
  6343. *
  6344. * @param cls a `struct Backtalker`
  6345. * @param record the information found, NULL for the last call
  6346. * @param emsg error message
  6347. */
  6348. static void
  6349. backtalker_monotime_cb (void *cls,
  6350. const struct GNUNET_PEERSTORE_Record *record,
  6351. const char *emsg)
  6352. {
  6353. struct Backtalker *b = cls;
  6354. struct GNUNET_TIME_AbsoluteNBO *mtbe;
  6355. struct GNUNET_TIME_Absolute mt;
  6356. (void) emsg;
  6357. if (NULL == record)
  6358. {
  6359. /* we're done with #backtalker_monotime_cb() invocations,
  6360. continue normal processing */
  6361. b->get = NULL;
  6362. GNUNET_assert (NULL != b->cmc);
  6363. if (0 != b->body_size)
  6364. demultiplex_with_cmc (b->cmc,
  6365. (const struct GNUNET_MessageHeader *) &b[1]);
  6366. else
  6367. finish_cmc_handling (b->cmc);
  6368. b->cmc = NULL;
  6369. return;
  6370. }
  6371. if (sizeof(*mtbe) != record->value_size)
  6372. {
  6373. GNUNET_break (0);
  6374. return;
  6375. }
  6376. mtbe = record->value;
  6377. mt = GNUNET_TIME_absolute_ntoh (*mtbe);
  6378. if (mt.abs_value_us > b->monotonic_time.abs_value_us)
  6379. {
  6380. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6381. "Backtalker message from %s dropped, monotime in the past\n",
  6382. GNUNET_i2s (&b->pid));
  6383. GNUNET_STATISTICS_update (
  6384. GST_stats,
  6385. "# Backchannel messages dropped: monotonic time not increasing",
  6386. 1,
  6387. GNUNET_NO);
  6388. b->monotonic_time = mt;
  6389. /* Setting body_size to 0 prevents call to #forward_backchannel_payload()
  6390. */
  6391. b->body_size = 0;
  6392. return;
  6393. }
  6394. }
  6395. /**
  6396. * Function called by PEERSTORE when the store operation of
  6397. * a backtalker's monotonic time is complete.
  6398. *
  6399. * @param cls the `struct Backtalker`
  6400. * @param success #GNUNET_OK on success
  6401. */
  6402. static void
  6403. backtalker_monotime_store_cb (void *cls, int success)
  6404. {
  6405. struct Backtalker *b = cls;
  6406. if (GNUNET_OK != success)
  6407. {
  6408. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  6409. "Failed to store backtalker's monotonic time in PEERSTORE!\n");
  6410. }
  6411. b->sc = NULL;
  6412. b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
  6413. }
  6414. /**
  6415. * The backtalker @a b monotonic time changed. Update PEERSTORE.
  6416. *
  6417. * @param b a backtalker with updated monotonic time
  6418. */
  6419. static void
  6420. update_backtalker_monotime (struct Backtalker *b)
  6421. {
  6422. struct GNUNET_TIME_AbsoluteNBO mtbe;
  6423. if (NULL != b->sc)
  6424. {
  6425. GNUNET_PEERSTORE_store_cancel (b->sc);
  6426. b->sc = NULL;
  6427. }
  6428. else
  6429. {
  6430. GNUNET_SCHEDULER_cancel (b->task);
  6431. b->task = NULL;
  6432. }
  6433. mtbe = GNUNET_TIME_absolute_hton (b->monotonic_time);
  6434. b->sc =
  6435. GNUNET_PEERSTORE_store (peerstore,
  6436. "transport",
  6437. &b->pid,
  6438. GNUNET_PEERSTORE_TRANSPORT_BACKCHANNEL_MONOTIME,
  6439. &mtbe,
  6440. sizeof(mtbe),
  6441. GNUNET_TIME_UNIT_FOREVER_ABS,
  6442. GNUNET_PEERSTORE_STOREOPTION_REPLACE,
  6443. &backtalker_monotime_store_cb,
  6444. b);
  6445. }
  6446. /**
  6447. * Communicator gave us a DV box. Process the request.
  6448. *
  6449. * @param cls a `struct CommunicatorMessageContext` (must call
  6450. * #finish_cmc_handling() when done)
  6451. * @param dvb the message that was received
  6452. */
  6453. static void
  6454. handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
  6455. {
  6456. struct CommunicatorMessageContext *cmc = cls;
  6457. uint16_t size = ntohs (dvb->header.size) - sizeof(*dvb);
  6458. uint16_t num_hops = ntohs (dvb->num_hops);
  6459. const struct GNUNET_PeerIdentity *hops =
  6460. (const struct GNUNET_PeerIdentity *) &dvb[1];
  6461. const char *enc_payload = (const char *) &hops[num_hops];
  6462. uint16_t enc_payload_size =
  6463. size - (num_hops * sizeof(struct GNUNET_PeerIdentity));
  6464. struct DVKeyState key;
  6465. struct GNUNET_HashCode hmac;
  6466. const char *hdr;
  6467. size_t hdr_len;
  6468. if (GNUNET_EXTRA_LOGGING > 0)
  6469. {
  6470. char *path;
  6471. path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity));
  6472. for (unsigned int i = 0; i < num_hops; i++)
  6473. {
  6474. char *tmp;
  6475. GNUNET_asprintf (&tmp, "%s->%s", path, GNUNET_i2s (&hops[i]));
  6476. GNUNET_free (path);
  6477. path = tmp;
  6478. }
  6479. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6480. "Received DVBox with remainig path %s\n",
  6481. path);
  6482. GNUNET_free (path);
  6483. }
  6484. if (num_hops > 0)
  6485. {
  6486. /* We're trying from the end of the hops array, as we may be
  6487. able to find a shortcut unknown to the origin that way */
  6488. for (int i = num_hops - 1; i >= 0; i--)
  6489. {
  6490. struct Neighbour *n;
  6491. if (0 == GNUNET_memcmp (&hops[i], &GST_my_identity))
  6492. {
  6493. GNUNET_break_op (0);
  6494. finish_cmc_handling (cmc);
  6495. return;
  6496. }
  6497. n = lookup_neighbour (&hops[i]);
  6498. if (NULL == n)
  6499. continue;
  6500. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6501. "Skipping %u/%u hops ahead while routing DV Box\n",
  6502. i,
  6503. num_hops);
  6504. forward_dv_box (n,
  6505. dvb,
  6506. ntohs (dvb->total_hops) + 1,
  6507. num_hops - i - 1, /* number of hops left */
  6508. &hops[i + 1], /* remaining hops */
  6509. enc_payload,
  6510. enc_payload_size);
  6511. GNUNET_STATISTICS_update (GST_stats,
  6512. "# DV hops skipped routing boxes",
  6513. i,
  6514. GNUNET_NO);
  6515. GNUNET_STATISTICS_update (GST_stats,
  6516. "# DV boxes routed (total)",
  6517. 1,
  6518. GNUNET_NO);
  6519. finish_cmc_handling (cmc);
  6520. return;
  6521. }
  6522. /* Woopsie, next hop not in neighbours, drop! */
  6523. GNUNET_STATISTICS_update (GST_stats,
  6524. "# DV Boxes dropped: next hop unknown",
  6525. 1,
  6526. GNUNET_NO);
  6527. finish_cmc_handling (cmc);
  6528. return;
  6529. }
  6530. /* We are the target. Unbox and handle message. */
  6531. GNUNET_STATISTICS_update (GST_stats,
  6532. "# DV boxes opened (ultimate target)",
  6533. 1,
  6534. GNUNET_NO);
  6535. cmc->total_hops = ntohs (dvb->total_hops);
  6536. dh_key_derive_eph_pub (&dvb->ephemeral_key, &dvb->iv, &key);
  6537. hdr = (const char *) &dvb[1];
  6538. hdr_len = ntohs (dvb->header.size) - sizeof(*dvb);
  6539. dv_hmac (&key, &hmac, hdr, hdr_len);
  6540. if (0 != GNUNET_memcmp (&hmac, &dvb->hmac))
  6541. {
  6542. /* HMAC missmatch, disard! */
  6543. GNUNET_break_op (0);
  6544. finish_cmc_handling (cmc);
  6545. return;
  6546. }
  6547. /* begin actual decryption */
  6548. {
  6549. struct Backtalker *b;
  6550. struct GNUNET_TIME_Absolute monotime;
  6551. struct TransportDVBoxPayloadP ppay;
  6552. char body[hdr_len - sizeof(ppay)] GNUNET_ALIGN;
  6553. const struct GNUNET_MessageHeader *mh =
  6554. (const struct GNUNET_MessageHeader *) body;
  6555. GNUNET_assert (hdr_len >=
  6556. sizeof(ppay) + sizeof(struct GNUNET_MessageHeader));
  6557. dv_decrypt (&key, &ppay, hdr, sizeof(ppay));
  6558. dv_decrypt (&key, &body, &hdr[sizeof(ppay)], hdr_len - sizeof(ppay));
  6559. dv_key_clean (&key);
  6560. if (ntohs (mh->size) != sizeof(body))
  6561. {
  6562. GNUNET_break_op (0);
  6563. finish_cmc_handling (cmc);
  6564. return;
  6565. }
  6566. /* need to prevent box-in-a-box (and DV_LEARN) so check inbox type! */
  6567. switch (ntohs (mh->type))
  6568. {
  6569. case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX:
  6570. GNUNET_break_op (0);
  6571. finish_cmc_handling (cmc);
  6572. return;
  6573. case GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN:
  6574. GNUNET_break_op (0);
  6575. finish_cmc_handling (cmc);
  6576. return;
  6577. default:
  6578. /* permitted, continue */
  6579. break;
  6580. }
  6581. monotime = GNUNET_TIME_absolute_ntoh (ppay.monotonic_time);
  6582. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6583. "Decrypted backtalk from %s\n",
  6584. GNUNET_i2s (&ppay.sender));
  6585. b = GNUNET_CONTAINER_multipeermap_get (backtalkers, &ppay.sender);
  6586. if ((NULL != b) && (monotime.abs_value_us < b->monotonic_time.abs_value_us))
  6587. {
  6588. GNUNET_STATISTICS_update (
  6589. GST_stats,
  6590. "# Backchannel messages dropped: monotonic time not increasing",
  6591. 1,
  6592. GNUNET_NO);
  6593. finish_cmc_handling (cmc);
  6594. return;
  6595. }
  6596. if ((NULL == b) ||
  6597. (0 != GNUNET_memcmp (&b->last_ephemeral, &dvb->ephemeral_key)))
  6598. {
  6599. /* Check signature */
  6600. struct EphemeralConfirmationPS ec;
  6601. ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
  6602. ec.purpose.size = htonl (sizeof(ec));
  6603. ec.target = GST_my_identity;
  6604. ec.ephemeral_key = dvb->ephemeral_key;
  6605. if (
  6606. GNUNET_OK !=
  6607. GNUNET_CRYPTO_eddsa_verify (
  6608. GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL,
  6609. &ec,
  6610. &ppay.sender_sig,
  6611. &ppay.sender.public_key))
  6612. {
  6613. /* Signature invalid, disard! */
  6614. GNUNET_break_op (0);
  6615. finish_cmc_handling (cmc);
  6616. return;
  6617. }
  6618. }
  6619. /* Update sender, we now know the real origin! */
  6620. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6621. "DVBox received for me from %s via %s\n",
  6622. GNUNET_i2s2 (&ppay.sender),
  6623. GNUNET_i2s (&cmc->im.sender));
  6624. cmc->im.sender = ppay.sender;
  6625. if (NULL != b)
  6626. {
  6627. /* update key cache and mono time */
  6628. b->last_ephemeral = dvb->ephemeral_key;
  6629. b->monotonic_time = monotime;
  6630. update_backtalker_monotime (b);
  6631. b->timeout =
  6632. GNUNET_TIME_relative_to_absolute (BACKCHANNEL_INACTIVITY_TIMEOUT);
  6633. demultiplex_with_cmc (cmc, mh);
  6634. return;
  6635. }
  6636. /* setup data structure to cache signature AND check
  6637. monotonic time with PEERSTORE before forwarding backchannel payload */
  6638. b = GNUNET_malloc (sizeof(struct Backtalker) + sizeof(body));
  6639. b->pid = ppay.sender;
  6640. b->body_size = sizeof(body);
  6641. memcpy (&b[1], body, sizeof(body));
  6642. GNUNET_assert (GNUNET_YES ==
  6643. GNUNET_CONTAINER_multipeermap_put (
  6644. backtalkers,
  6645. &b->pid,
  6646. b,
  6647. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  6648. b->monotonic_time = monotime; /* NOTE: to be checked still! */
  6649. b->cmc = cmc;
  6650. b->timeout =
  6651. GNUNET_TIME_relative_to_absolute (BACKCHANNEL_INACTIVITY_TIMEOUT);
  6652. b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
  6653. b->get =
  6654. GNUNET_PEERSTORE_iterate (peerstore,
  6655. "transport",
  6656. &b->pid,
  6657. GNUNET_PEERSTORE_TRANSPORT_BACKCHANNEL_MONOTIME,
  6658. &backtalker_monotime_cb,
  6659. b);
  6660. } /* end actual decryption */
  6661. }
  6662. /**
  6663. * Client notified us about transmission from a peer. Process the request.
  6664. *
  6665. * @param cls a `struct TransportClient` which sent us the message
  6666. * @param obm the send message that was sent
  6667. * @return #GNUNET_YES if message is well-formed
  6668. */
  6669. static int
  6670. check_incoming_msg (void *cls,
  6671. const struct GNUNET_TRANSPORT_IncomingMessage *im)
  6672. {
  6673. struct TransportClient *tc = cls;
  6674. if (CT_COMMUNICATOR != tc->type)
  6675. {
  6676. GNUNET_break (0);
  6677. return GNUNET_SYSERR;
  6678. }
  6679. GNUNET_MQ_check_boxed_message (im);
  6680. return GNUNET_OK;
  6681. }
  6682. /**
  6683. * Closure for #check_known_address.
  6684. */
  6685. struct CheckKnownAddressContext
  6686. {
  6687. /**
  6688. * Set to the address we are looking for.
  6689. */
  6690. const char *address;
  6691. /**
  6692. * Set to a matching validation state, if one was found.
  6693. */
  6694. struct ValidationState *vs;
  6695. };
  6696. /**
  6697. * Test if the validation state in @a value matches the
  6698. * address from @a cls.
  6699. *
  6700. * @param cls a `struct CheckKnownAddressContext`
  6701. * @param pid unused (must match though)
  6702. * @param value a `struct ValidationState`
  6703. * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
  6704. */
  6705. static int
  6706. check_known_address (void *cls,
  6707. const struct GNUNET_PeerIdentity *pid,
  6708. void *value)
  6709. {
  6710. struct CheckKnownAddressContext *ckac = cls;
  6711. struct ValidationState *vs = value;
  6712. (void) pid;
  6713. if (0 != strcmp (vs->address, ckac->address))
  6714. return GNUNET_OK;
  6715. ckac->vs = vs;
  6716. return GNUNET_NO;
  6717. }
  6718. /**
  6719. * Task run periodically to validate some address based on #validation_heap.
  6720. *
  6721. * @param cls NULL
  6722. */
  6723. static void
  6724. validation_start_cb (void *cls);
  6725. /**
  6726. * Set the time for next_challenge of @a vs to @a new_time.
  6727. * Updates the heap and if necessary reschedules the job.
  6728. *
  6729. * @param vs validation state to update
  6730. * @param new_time new time for revalidation
  6731. */
  6732. static void
  6733. update_next_challenge_time (struct ValidationState *vs,
  6734. struct GNUNET_TIME_Absolute new_time)
  6735. {
  6736. struct GNUNET_TIME_Relative delta;
  6737. if (new_time.abs_value_us == vs->next_challenge.abs_value_us)
  6738. return; /* be lazy */
  6739. vs->next_challenge = new_time;
  6740. if (NULL == vs->hn)
  6741. vs->hn =
  6742. GNUNET_CONTAINER_heap_insert (validation_heap, vs, new_time.abs_value_us);
  6743. else
  6744. GNUNET_CONTAINER_heap_update_cost (vs->hn, new_time.abs_value_us);
  6745. if ((vs != GNUNET_CONTAINER_heap_peek (validation_heap)) &&
  6746. (NULL != validation_task))
  6747. return;
  6748. if (NULL != validation_task)
  6749. GNUNET_SCHEDULER_cancel (validation_task);
  6750. /* randomize a bit */
  6751. delta.rel_value_us =
  6752. GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
  6753. MIN_DELAY_ADDRESS_VALIDATION.rel_value_us);
  6754. new_time = GNUNET_TIME_absolute_add (new_time, delta);
  6755. validation_task =
  6756. GNUNET_SCHEDULER_add_at (new_time, &validation_start_cb, NULL);
  6757. }
  6758. /**
  6759. * Start address validation.
  6760. *
  6761. * @param pid peer the @a address is for
  6762. * @param address an address to reach @a pid (presumably)
  6763. */
  6764. static void
  6765. start_address_validation (const struct GNUNET_PeerIdentity *pid,
  6766. const char *address)
  6767. {
  6768. struct GNUNET_TIME_Absolute now;
  6769. struct ValidationState *vs;
  6770. struct CheckKnownAddressContext ckac = { .address = address, .vs = NULL };
  6771. (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
  6772. pid,
  6773. &check_known_address,
  6774. &ckac);
  6775. if (NULL != (vs = ckac.vs))
  6776. {
  6777. /* if 'vs' is not currently valid, we need to speed up retrying the
  6778. * validation */
  6779. if (vs->validated_until.abs_value_us < vs->next_challenge.abs_value_us)
  6780. {
  6781. /* reduce backoff as we got a fresh advertisement */
  6782. vs->challenge_backoff =
  6783. GNUNET_TIME_relative_min (FAST_VALIDATION_CHALLENGE_FREQ,
  6784. GNUNET_TIME_relative_divide (
  6785. vs->challenge_backoff,
  6786. 2));
  6787. update_next_challenge_time (vs,
  6788. GNUNET_TIME_relative_to_absolute (
  6789. vs->challenge_backoff));
  6790. }
  6791. return;
  6792. }
  6793. now = GNUNET_TIME_absolute_get ();
  6794. vs = GNUNET_new (struct ValidationState);
  6795. vs->pid = *pid;
  6796. vs->valid_until =
  6797. GNUNET_TIME_relative_to_absolute (ADDRESS_VALIDATION_LIFETIME);
  6798. vs->first_challenge_use = now;
  6799. vs->validation_rtt = GNUNET_TIME_UNIT_FOREVER_REL;
  6800. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
  6801. &vs->challenge,
  6802. sizeof(vs->challenge));
  6803. vs->address = GNUNET_strdup (address);
  6804. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6805. "Starting address validation `%s' of peer %s using challenge %s\n",
  6806. address,
  6807. GNUNET_i2s (pid),
  6808. GNUNET_sh2s (&vs->challenge.value));
  6809. GNUNET_assert (GNUNET_YES ==
  6810. GNUNET_CONTAINER_multipeermap_put (
  6811. validation_map,
  6812. &vs->pid,
  6813. vs,
  6814. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  6815. update_next_challenge_time (vs, now);
  6816. }
  6817. /**
  6818. * Function called by PEERSTORE for each matching record.
  6819. *
  6820. * @param cls closure, a `struct IncomingRequest`
  6821. * @param record peerstore record information
  6822. * @param emsg error message, or NULL if no errors
  6823. */
  6824. static void
  6825. handle_hello_for_incoming (void *cls,
  6826. const struct GNUNET_PEERSTORE_Record *record,
  6827. const char *emsg)
  6828. {
  6829. struct IncomingRequest *ir = cls;
  6830. const char *val;
  6831. if (NULL != emsg)
  6832. {
  6833. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  6834. "Got failure from PEERSTORE: %s\n",
  6835. emsg);
  6836. return;
  6837. }
  6838. val = record->value;
  6839. if ((0 == record->value_size) || ('\0' != val[record->value_size - 1]))
  6840. {
  6841. GNUNET_break (0);
  6842. return;
  6843. }
  6844. start_address_validation (&ir->pid, (const char *) record->value);
  6845. }
  6846. /**
  6847. * Communicator gave us a transport address validation challenge. Process the
  6848. * request.
  6849. *
  6850. * @param cls a `struct CommunicatorMessageContext` (must call
  6851. * #finish_cmc_handling() when done)
  6852. * @param tvc the message that was received
  6853. */
  6854. static void
  6855. handle_validation_challenge (
  6856. void *cls,
  6857. const struct TransportValidationChallengeMessage *tvc)
  6858. {
  6859. struct CommunicatorMessageContext *cmc = cls;
  6860. struct TransportValidationResponseMessage tvr;
  6861. struct VirtualLink *vl;
  6862. struct GNUNET_TIME_RelativeNBO validity_duration;
  6863. struct IncomingRequest *ir;
  6864. struct Neighbour *n;
  6865. struct GNUNET_PeerIdentity sender;
  6866. /* DV-routed messages are not allowed for validation challenges */
  6867. if (cmc->total_hops > 0)
  6868. {
  6869. GNUNET_break_op (0);
  6870. finish_cmc_handling (cmc);
  6871. return;
  6872. }
  6873. validity_duration = cmc->im.expected_address_validity;
  6874. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  6875. "Received address validation challenge %s\n",
  6876. GNUNET_sh2s (&tvc->challenge.value));
  6877. /* If we have a virtual link, we use this mechanism to signal the
  6878. size of the flow control window, and to allow the sender
  6879. to ask for increases. If for us the virtual link is still down,
  6880. we will always give a window size of zero. */
  6881. tvr.header.type =
  6882. htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE);
  6883. tvr.header.size = htons (sizeof(tvr));
  6884. tvr.reserved = htonl (0);
  6885. tvr.challenge = tvc->challenge;
  6886. tvr.origin_time = tvc->sender_time;
  6887. tvr.validity_duration = validity_duration;
  6888. {
  6889. /* create signature */
  6890. struct TransportValidationPS tvp = {
  6891. .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
  6892. .purpose.size = htonl (sizeof(tvp)),
  6893. .validity_duration = validity_duration,
  6894. .challenge = tvc->challenge
  6895. };
  6896. GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
  6897. &tvp,
  6898. &tvr.signature);
  6899. }
  6900. route_control_message_without_fc (&cmc->im.sender,
  6901. &tvr.header,
  6902. RMO_ANYTHING_GOES | RMO_REDUNDANT);
  6903. sender = cmc->im.sender;
  6904. finish_cmc_handling (cmc);
  6905. vl = lookup_virtual_link (&sender);
  6906. if (NULL != vl)
  6907. return;
  6908. /* For us, the link is still down, but we need bi-directional
  6909. connections (for flow-control and for this to be useful for
  6910. CORE), so we must try to bring the link up! */
  6911. /* (1) Check existing queues, if any, we may be lucky! */
  6912. n = lookup_neighbour (&sender);
  6913. if (NULL != n)
  6914. for (struct Queue *q = n->queue_head; NULL != q; q = q->next_neighbour)
  6915. start_address_validation (&sender, q->address);
  6916. /* (2) Also try to see if we have addresses in PEERSTORE for this peer
  6917. we could use */
  6918. for (ir = ir_head; NULL != ir; ir = ir->next)
  6919. if (0 == GNUNET_memcmp (&ir->pid, &sender))
  6920. return;
  6921. /* we are already trying */
  6922. ir = GNUNET_new (struct IncomingRequest);
  6923. ir->pid = sender;
  6924. GNUNET_CONTAINER_DLL_insert (ir_head, ir_tail, ir);
  6925. ir->wc = GNUNET_PEERSTORE_watch (peerstore,
  6926. "transport",
  6927. &ir->pid,
  6928. GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
  6929. &handle_hello_for_incoming,
  6930. ir);
  6931. ir_total++;
  6932. /* Bound attempts we do in parallel here, might otherwise get excessive */
  6933. while (ir_total > MAX_INCOMING_REQUEST)
  6934. free_incoming_request (ir_head);
  6935. }
  6936. /**
  6937. * Closure for #check_known_challenge.
  6938. */
  6939. struct CheckKnownChallengeContext
  6940. {
  6941. /**
  6942. * Set to the challenge we are looking for.
  6943. */
  6944. const struct ChallengeNonceP *challenge;
  6945. /**
  6946. * Set to a matching validation state, if one was found.
  6947. */
  6948. struct ValidationState *vs;
  6949. };
  6950. /**
  6951. * Test if the validation state in @a value matches the
  6952. * challenge from @a cls.
  6953. *
  6954. * @param cls a `struct CheckKnownChallengeContext`
  6955. * @param pid unused (must match though)
  6956. * @param value a `struct ValidationState`
  6957. * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
  6958. */
  6959. static int
  6960. check_known_challenge (void *cls,
  6961. const struct GNUNET_PeerIdentity *pid,
  6962. void *value)
  6963. {
  6964. struct CheckKnownChallengeContext *ckac = cls;
  6965. struct ValidationState *vs = value;
  6966. (void) pid;
  6967. if (0 != GNUNET_memcmp (&vs->challenge, ckac->challenge))
  6968. return GNUNET_OK;
  6969. ckac->vs = vs;
  6970. return GNUNET_NO;
  6971. }
  6972. /**
  6973. * Function called when peerstore is done storing a
  6974. * validated address.
  6975. *
  6976. * @param cls a `struct ValidationState`
  6977. * @param success #GNUNET_YES on success
  6978. */
  6979. static void
  6980. peerstore_store_validation_cb (void *cls, int success)
  6981. {
  6982. struct ValidationState *vs = cls;
  6983. vs->sc = NULL;
  6984. if (GNUNET_YES == success)
  6985. return;
  6986. GNUNET_STATISTICS_update (GST_stats,
  6987. "# Peerstore failed to store foreign address",
  6988. 1,
  6989. GNUNET_NO);
  6990. }
  6991. /**
  6992. * Find the queue matching @a pid and @a address.
  6993. *
  6994. * @param pid peer the queue must go to
  6995. * @param address address the queue must use
  6996. * @return NULL if no such queue exists
  6997. */
  6998. static struct Queue *
  6999. find_queue (const struct GNUNET_PeerIdentity *pid, const char *address)
  7000. {
  7001. struct Neighbour *n;
  7002. n = lookup_neighbour (pid);
  7003. if (NULL == n)
  7004. return NULL;
  7005. for (struct Queue *pos = n->queue_head; NULL != pos;
  7006. pos = pos->next_neighbour)
  7007. {
  7008. if (0 == strcmp (pos->address, address))
  7009. return pos;
  7010. }
  7011. return NULL;
  7012. }
  7013. /**
  7014. * Communicator gave us a transport address validation response. Process the
  7015. * request.
  7016. *
  7017. * @param cls a `struct CommunicatorMessageContext` (must call
  7018. * #finish_cmc_handling() when done)
  7019. * @param tvr the message that was received
  7020. */
  7021. static void
  7022. handle_validation_response (
  7023. void *cls,
  7024. const struct TransportValidationResponseMessage *tvr)
  7025. {
  7026. struct CommunicatorMessageContext *cmc = cls;
  7027. struct ValidationState *vs;
  7028. struct CheckKnownChallengeContext ckac = { .challenge = &tvr->challenge,
  7029. .vs = NULL };
  7030. struct GNUNET_TIME_Absolute origin_time;
  7031. struct Queue *q;
  7032. struct Neighbour *n;
  7033. struct VirtualLink *vl;
  7034. /* check this is one of our challenges */
  7035. (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
  7036. &cmc->im.sender,
  7037. &check_known_challenge,
  7038. &ckac);
  7039. if (NULL == (vs = ckac.vs))
  7040. {
  7041. /* This can happen simply if we 'forgot' the challenge by now,
  7042. i.e. because we received the validation response twice */
  7043. GNUNET_STATISTICS_update (GST_stats,
  7044. "# Validations dropped, challenge unknown",
  7045. 1,
  7046. GNUNET_NO);
  7047. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7048. "Validation response %s dropped, challenge unknown\n",
  7049. GNUNET_sh2s (&tvr->challenge.value));
  7050. finish_cmc_handling (cmc);
  7051. return;
  7052. }
  7053. /* sanity check on origin time */
  7054. origin_time = GNUNET_TIME_absolute_ntoh (tvr->origin_time);
  7055. if ((origin_time.abs_value_us < vs->first_challenge_use.abs_value_us) ||
  7056. (origin_time.abs_value_us > vs->last_challenge_use.abs_value_us))
  7057. {
  7058. GNUNET_break_op (0);
  7059. finish_cmc_handling (cmc);
  7060. return;
  7061. }
  7062. {
  7063. /* check signature */
  7064. struct TransportValidationPS tvp = {
  7065. .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
  7066. .purpose.size = htonl (sizeof(tvp)),
  7067. .validity_duration = tvr->validity_duration,
  7068. .challenge = tvr->challenge
  7069. };
  7070. if (
  7071. GNUNET_OK !=
  7072. GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE,
  7073. &tvp,
  7074. &tvr->signature,
  7075. &cmc->im.sender.public_key))
  7076. {
  7077. GNUNET_break_op (0);
  7078. finish_cmc_handling (cmc);
  7079. return;
  7080. }
  7081. }
  7082. /* validity is capped by our willingness to keep track of the
  7083. validation entry and the maximum the other peer allows */
  7084. vs->valid_until = GNUNET_TIME_relative_to_absolute (
  7085. GNUNET_TIME_relative_min (GNUNET_TIME_relative_ntoh (
  7086. tvr->validity_duration),
  7087. MAX_ADDRESS_VALID_UNTIL));
  7088. vs->validated_until =
  7089. GNUNET_TIME_absolute_min (vs->valid_until,
  7090. GNUNET_TIME_relative_to_absolute (
  7091. ADDRESS_VALIDATION_LIFETIME));
  7092. vs->validation_rtt = GNUNET_TIME_absolute_get_duration (origin_time);
  7093. vs->challenge_backoff = GNUNET_TIME_UNIT_ZERO;
  7094. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
  7095. &vs->challenge,
  7096. sizeof(vs->challenge));
  7097. vs->first_challenge_use = GNUNET_TIME_absolute_subtract (
  7098. vs->validated_until,
  7099. GNUNET_TIME_relative_multiply (vs->validation_rtt,
  7100. VALIDATION_RTT_BUFFER_FACTOR));
  7101. vs->last_challenge_use =
  7102. GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet used */
  7103. update_next_challenge_time (vs, vs->first_challenge_use);
  7104. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7105. "Validation response %s accepted, address valid until %s\n",
  7106. GNUNET_sh2s (&tvr->challenge.value),
  7107. GNUNET_STRINGS_absolute_time_to_string (vs->valid_until));
  7108. vs->sc = GNUNET_PEERSTORE_store (peerstore,
  7109. "transport",
  7110. &cmc->im.sender,
  7111. GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
  7112. vs->address,
  7113. strlen (vs->address) + 1,
  7114. vs->valid_until,
  7115. GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
  7116. &peerstore_store_validation_cb,
  7117. vs);
  7118. finish_cmc_handling (cmc);
  7119. /* Finally, we now possibly have a confirmed (!) working queue,
  7120. update queue status (if queue still is around) */
  7121. q = find_queue (&vs->pid, vs->address);
  7122. if (NULL == q)
  7123. {
  7124. GNUNET_STATISTICS_update (GST_stats,
  7125. "# Queues lost at time of successful validation",
  7126. 1,
  7127. GNUNET_NO);
  7128. return;
  7129. }
  7130. q->validated_until = vs->validated_until;
  7131. q->pd.aged_rtt = vs->validation_rtt;
  7132. n = q->neighbour;
  7133. vl = lookup_virtual_link (&vs->pid);
  7134. if (NULL != vl)
  7135. {
  7136. /* Link was already up, remember n is also now available and we are done */
  7137. if (NULL == vl->n)
  7138. {
  7139. vl->n = n;
  7140. n->vl = vl;
  7141. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7142. "Virtual link to %s could now also direct neighbour!\n",
  7143. GNUNET_i2s (&vs->pid));
  7144. }
  7145. else
  7146. {
  7147. GNUNET_assert (n == vl->n);
  7148. }
  7149. return;
  7150. }
  7151. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7152. "Creating new virtual link to %s using direct neighbour!\n",
  7153. GNUNET_i2s (&vs->pid));
  7154. vl = GNUNET_new (struct VirtualLink);
  7155. vl->target = n->pid;
  7156. vl->n = n;
  7157. n->vl = vl;
  7158. vl->core_recv_window = RECV_WINDOW_SIZE;
  7159. vl->available_fc_window_size = DEFAULT_WINDOW_SIZE;
  7160. vl->visibility_task =
  7161. GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl);
  7162. GNUNET_break (GNUNET_YES ==
  7163. GNUNET_CONTAINER_multipeermap_put (
  7164. links,
  7165. &vl->target,
  7166. vl,
  7167. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  7168. consider_sending_fc (vl);
  7169. /* We lacked a confirmed connection to the target
  7170. before, so tell CORE about it (finally!) */
  7171. cores_send_connect_info (&n->pid);
  7172. }
  7173. /**
  7174. * Incoming meessage. Process the request.
  7175. *
  7176. * @param im the send message that was received
  7177. */
  7178. static void
  7179. handle_incoming_msg (void *cls,
  7180. const struct GNUNET_TRANSPORT_IncomingMessage *im)
  7181. {
  7182. struct TransportClient *tc = cls;
  7183. struct CommunicatorMessageContext *cmc =
  7184. GNUNET_new (struct CommunicatorMessageContext);
  7185. cmc->tc = tc;
  7186. cmc->im = *im;
  7187. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7188. "Received message via communicator from peer %s\n",
  7189. GNUNET_i2s (&im->sender));
  7190. demultiplex_with_cmc (cmc, (const struct GNUNET_MessageHeader *) &im[1]);
  7191. }
  7192. /**
  7193. * Communicator gave us a transport address validation response. Process the
  7194. * request.
  7195. *
  7196. * @param cls a `struct CommunicatorMessageContext` (must call
  7197. * #finish_cmc_handling() when done)
  7198. * @param fc the message that was received
  7199. */
  7200. static void
  7201. handle_flow_control (void *cls, const struct TransportFlowControlMessage *fc)
  7202. {
  7203. struct CommunicatorMessageContext *cmc = cls;
  7204. struct VirtualLink *vl;
  7205. uint32_t seq;
  7206. struct GNUNET_TIME_Absolute st;
  7207. uint64_t os;
  7208. uint64_t wnd;
  7209. vl = lookup_virtual_link (&cmc->im.sender);
  7210. if (NULL == vl)
  7211. {
  7212. GNUNET_STATISTICS_update (GST_stats,
  7213. "# FC dropped: virtual link unknown",
  7214. 1,
  7215. GNUNET_NO);
  7216. finish_cmc_handling (cmc);
  7217. return;
  7218. }
  7219. st = GNUNET_TIME_absolute_ntoh (fc->sender_time);
  7220. if (st.abs_value_us < vl->last_fc_timestamp.abs_value_us)
  7221. {
  7222. /* out of order, drop */
  7223. GNUNET_STATISTICS_update (GST_stats,
  7224. "# FC dropped: message out of order",
  7225. 1,
  7226. GNUNET_NO);
  7227. finish_cmc_handling (cmc);
  7228. return;
  7229. }
  7230. seq = ntohl (fc->seq);
  7231. if (seq < vl->last_fc_seq)
  7232. {
  7233. /* Wrap-around/reset of other peer; start all counters from zero */
  7234. vl->outbound_fc_window_size_used = 0;
  7235. }
  7236. vl->last_fc_seq = seq;
  7237. vl->last_fc_timestamp = st;
  7238. vl->outbound_fc_window_size = GNUNET_ntohll (fc->inbound_window_size);
  7239. os = GNUNET_ntohll (fc->outbound_sent);
  7240. vl->incoming_fc_window_size_loss =
  7241. (int64_t) (os - vl->incoming_fc_window_size_used);
  7242. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7243. "Received FC from %s, seq %u, new window %llu (loss at %lld)\n",
  7244. GNUNET_i2s (&vl->target),
  7245. (unsigned int) seq,
  7246. (unsigned long long) vl->outbound_fc_window_size,
  7247. (long long) vl->incoming_fc_window_size_loss);
  7248. wnd = GNUNET_ntohll (fc->outbound_window_size);
  7249. if ((wnd < vl->incoming_fc_window_size) ||
  7250. (vl->last_outbound_window_size_received != wnd) ||
  7251. (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX)
  7252. % FC_NO_CHANGE_REPLY_PROBABILITY))
  7253. {
  7254. /* Consider re-sending our FC message, as clearly the
  7255. other peer's idea of the window is not up-to-date */
  7256. consider_sending_fc (vl);
  7257. }
  7258. if ((wnd == vl->incoming_fc_window_size) &&
  7259. (vl->last_outbound_window_size_received == wnd) &&
  7260. (NULL != vl->fc_retransmit_task))
  7261. {
  7262. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7263. "Stopping FC retransmission to %s: peer is current at window %llu\n",
  7264. GNUNET_i2s (&vl->target),
  7265. (unsigned long long) wnd);
  7266. GNUNET_SCHEDULER_cancel (vl->fc_retransmit_task);
  7267. vl->fc_retransmit_task = NULL;
  7268. }
  7269. vl->last_outbound_window_size_received = wnd;
  7270. /* FC window likely increased, check transmission possibilities! */
  7271. check_vl_transmission (vl);
  7272. finish_cmc_handling (cmc);
  7273. }
  7274. /**
  7275. * Given an inbound message @a msg from a communicator @a cmc,
  7276. * demultiplex it based on the type calling the right handler.
  7277. *
  7278. * @param cmc context for demultiplexing
  7279. * @param msg message to demultiplex
  7280. */
  7281. static void
  7282. demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
  7283. const struct GNUNET_MessageHeader *msg)
  7284. {
  7285. struct GNUNET_MQ_MessageHandler handlers[] =
  7286. { GNUNET_MQ_hd_var_size (fragment_box,
  7287. GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT,
  7288. struct TransportFragmentBoxMessage,
  7289. &cmc),
  7290. GNUNET_MQ_hd_var_size (reliability_box,
  7291. GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX,
  7292. struct TransportReliabilityBoxMessage,
  7293. &cmc),
  7294. GNUNET_MQ_hd_var_size (reliability_ack,
  7295. GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK,
  7296. struct TransportReliabilityAckMessage,
  7297. &cmc),
  7298. GNUNET_MQ_hd_var_size (backchannel_encapsulation,
  7299. GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION,
  7300. struct TransportBackchannelEncapsulationMessage,
  7301. &cmc),
  7302. GNUNET_MQ_hd_var_size (dv_learn,
  7303. GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN,
  7304. struct TransportDVLearnMessage,
  7305. &cmc),
  7306. GNUNET_MQ_hd_var_size (dv_box,
  7307. GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX,
  7308. struct TransportDVBoxMessage,
  7309. &cmc),
  7310. GNUNET_MQ_hd_fixed_size (
  7311. validation_challenge,
  7312. GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE,
  7313. struct TransportValidationChallengeMessage,
  7314. &cmc),
  7315. GNUNET_MQ_hd_fixed_size (flow_control,
  7316. GNUNET_MESSAGE_TYPE_TRANSPORT_FLOW_CONTROL,
  7317. struct TransportFlowControlMessage,
  7318. &cmc),
  7319. GNUNET_MQ_hd_fixed_size (
  7320. validation_response,
  7321. GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE,
  7322. struct TransportValidationResponseMessage,
  7323. &cmc),
  7324. GNUNET_MQ_handler_end () };
  7325. int ret;
  7326. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7327. "Handling message of type %u with %u bytes\n",
  7328. (unsigned int) ntohs (msg->type),
  7329. (unsigned int) ntohs (msg->size));
  7330. ret = GNUNET_MQ_handle_message (handlers, msg);
  7331. if (GNUNET_SYSERR == ret)
  7332. {
  7333. GNUNET_break (0);
  7334. GNUNET_SERVICE_client_drop (cmc->tc->client);
  7335. GNUNET_free (cmc);
  7336. return;
  7337. }
  7338. if (GNUNET_NO == ret)
  7339. {
  7340. /* unencapsulated 'raw' message */
  7341. handle_raw_message (&cmc, msg);
  7342. }
  7343. }
  7344. /**
  7345. * New queue became available. Check message.
  7346. *
  7347. * @param cls the client
  7348. * @param aqm the send message that was sent
  7349. */
  7350. static int
  7351. check_add_queue_message (void *cls,
  7352. const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
  7353. {
  7354. struct TransportClient *tc = cls;
  7355. if (CT_COMMUNICATOR != tc->type)
  7356. {
  7357. GNUNET_break (0);
  7358. return GNUNET_SYSERR;
  7359. }
  7360. GNUNET_MQ_check_zero_termination (aqm);
  7361. return GNUNET_OK;
  7362. }
  7363. /**
  7364. * If necessary, generates the UUID for a @a pm
  7365. *
  7366. * @param pm pending message to generate UUID for.
  7367. */
  7368. static void
  7369. set_pending_message_uuid (struct PendingMessage *pm)
  7370. {
  7371. if (pm->msg_uuid_set)
  7372. return;
  7373. pm->msg_uuid.uuid = pm->vl->message_uuid_ctr++;
  7374. pm->msg_uuid_set = GNUNET_YES;
  7375. }
  7376. /**
  7377. * Setup data structure waiting for acknowledgements.
  7378. *
  7379. * @param queue queue the @a pm will be sent over
  7380. * @param dvh path the message will take, may be NULL
  7381. * @param pm the pending message for transmission
  7382. * @return corresponding fresh pending acknowledgement
  7383. */
  7384. static struct PendingAcknowledgement *
  7385. prepare_pending_acknowledgement (struct Queue *queue,
  7386. struct DistanceVectorHop *dvh,
  7387. struct PendingMessage *pm)
  7388. {
  7389. struct PendingAcknowledgement *pa;
  7390. pa = GNUNET_new (struct PendingAcknowledgement);
  7391. pa->queue = queue;
  7392. pa->dvh = dvh;
  7393. pa->pm = pm;
  7394. do
  7395. {
  7396. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
  7397. &pa->ack_uuid,
  7398. sizeof(pa->ack_uuid));
  7399. }
  7400. while (GNUNET_YES != GNUNET_CONTAINER_multiuuidmap_put (
  7401. pending_acks,
  7402. &pa->ack_uuid.value,
  7403. pa,
  7404. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  7405. GNUNET_CONTAINER_MDLL_insert (queue, queue->pa_head, queue->pa_tail, pa);
  7406. GNUNET_CONTAINER_MDLL_insert (pm, pm->pa_head, pm->pa_tail, pa);
  7407. if (NULL != dvh)
  7408. GNUNET_CONTAINER_MDLL_insert (dvh, dvh->pa_head, dvh->pa_tail, pa);
  7409. pa->transmission_time = GNUNET_TIME_absolute_get ();
  7410. pa->message_size = pm->bytes_msg;
  7411. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7412. "Waiting for ACKnowledgment `%s' for <%llu>\n",
  7413. GNUNET_uuid2s (&pa->ack_uuid.value),
  7414. pm->logging_uuid);
  7415. return pa;
  7416. }
  7417. /**
  7418. * Fragment the given @a pm to the given @a mtu. Adds
  7419. * additional fragments to the neighbour as well. If the
  7420. * @a mtu is too small, generates and error for the @a pm
  7421. * and returns NULL.
  7422. *
  7423. * @param queue which queue to fragment for
  7424. * @param dvh path the message will take, or NULL
  7425. * @param pm pending message to fragment for transmission
  7426. * @return new message to transmit
  7427. */
  7428. static struct PendingMessage *
  7429. fragment_message (struct Queue *queue,
  7430. struct DistanceVectorHop *dvh,
  7431. struct PendingMessage *pm)
  7432. {
  7433. struct PendingAcknowledgement *pa;
  7434. struct PendingMessage *ff;
  7435. uint16_t mtu;
  7436. mtu = (0 == queue->mtu)
  7437. ? UINT16_MAX - sizeof(struct GNUNET_TRANSPORT_SendMessageTo)
  7438. : queue->mtu;
  7439. set_pending_message_uuid (pm);
  7440. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7441. "Fragmenting message %llu <%llu> to %s for MTU %u\n",
  7442. (unsigned long long) pm->msg_uuid.uuid,
  7443. pm->logging_uuid,
  7444. GNUNET_i2s (&pm->vl->target),
  7445. (unsigned int) mtu);
  7446. pa = prepare_pending_acknowledgement (queue, dvh, pm);
  7447. /* This invariant is established in #handle_add_queue_message() */
  7448. GNUNET_assert (mtu > sizeof(struct TransportFragmentBoxMessage));
  7449. /* select fragment for transmission, descending the tree if it has
  7450. been expanded until we are at a leaf or at a fragment that is small
  7451. enough
  7452. */
  7453. ff = pm;
  7454. while (((ff->bytes_msg > mtu) || (pm == ff)) &&
  7455. (ff->frag_off == ff->bytes_msg) && (NULL != ff->head_frag))
  7456. {
  7457. ff = ff->head_frag; /* descent into fragmented fragments */
  7458. }
  7459. if (((ff->bytes_msg > mtu) || (pm == ff)) && (pm->frag_off < pm->bytes_msg))
  7460. {
  7461. /* Did not yet calculate all fragments, calculate next fragment */
  7462. struct PendingMessage *frag;
  7463. struct TransportFragmentBoxMessage tfb;
  7464. const char *orig;
  7465. char *msg;
  7466. uint16_t fragmax;
  7467. uint16_t fragsize;
  7468. uint16_t msize;
  7469. uint16_t xoff = 0;
  7470. orig = (const char *) &ff[1];
  7471. msize = ff->bytes_msg;
  7472. if (pm != ff)
  7473. {
  7474. const struct TransportFragmentBoxMessage *tfbo;
  7475. tfbo = (const struct TransportFragmentBoxMessage *) orig;
  7476. orig += sizeof(struct TransportFragmentBoxMessage);
  7477. msize -= sizeof(struct TransportFragmentBoxMessage);
  7478. xoff = ntohs (tfbo->frag_off);
  7479. }
  7480. fragmax = mtu - sizeof(struct TransportFragmentBoxMessage);
  7481. fragsize = GNUNET_MIN (msize - ff->frag_off, fragmax);
  7482. frag =
  7483. GNUNET_malloc (sizeof(struct PendingMessage)
  7484. + sizeof(struct TransportFragmentBoxMessage) + fragsize);
  7485. frag->logging_uuid = logging_uuid_gen++;
  7486. frag->vl = pm->vl;
  7487. frag->frag_parent = ff;
  7488. frag->timeout = pm->timeout;
  7489. frag->bytes_msg = sizeof(struct TransportFragmentBoxMessage) + fragsize;
  7490. frag->pmt = PMT_FRAGMENT_BOX;
  7491. msg = (char *) &frag[1];
  7492. tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT);
  7493. tfb.header.size =
  7494. htons (sizeof(struct TransportFragmentBoxMessage) + fragsize);
  7495. tfb.ack_uuid = pa->ack_uuid;
  7496. tfb.msg_uuid = pm->msg_uuid;
  7497. tfb.frag_off = htons (ff->frag_off + xoff);
  7498. tfb.msg_size = htons (pm->bytes_msg);
  7499. memcpy (msg, &tfb, sizeof(tfb));
  7500. memcpy (&msg[sizeof(tfb)], &orig[ff->frag_off], fragsize);
  7501. GNUNET_CONTAINER_MDLL_insert (frag, ff->head_frag, ff->tail_frag, frag);
  7502. ff->frag_off += fragsize;
  7503. ff = frag;
  7504. }
  7505. /* Move head to the tail and return it */
  7506. GNUNET_CONTAINER_MDLL_remove (frag,
  7507. ff->frag_parent->head_frag,
  7508. ff->frag_parent->tail_frag,
  7509. ff);
  7510. GNUNET_CONTAINER_MDLL_insert_tail (frag,
  7511. ff->frag_parent->head_frag,
  7512. ff->frag_parent->tail_frag,
  7513. ff);
  7514. return ff;
  7515. }
  7516. /**
  7517. * Reliability-box the given @a pm. On error (can there be any), NULL
  7518. * may be returned, otherwise the "replacement" for @a pm (which
  7519. * should then be added to the respective neighbour's queue instead of
  7520. * @a pm). If the @a pm is already fragmented or reliability boxed,
  7521. * or itself an ACK, this function simply returns @a pm.
  7522. *
  7523. * @param queue which queue to prepare transmission for
  7524. * @param dvh path the message will take, or NULL
  7525. * @param pm pending message to box for transmission over unreliabile queue
  7526. * @return new message to transmit
  7527. */
  7528. static struct PendingMessage *
  7529. reliability_box_message (struct Queue *queue,
  7530. struct DistanceVectorHop *dvh,
  7531. struct PendingMessage *pm)
  7532. {
  7533. struct TransportReliabilityBoxMessage rbox;
  7534. struct PendingAcknowledgement *pa;
  7535. struct PendingMessage *bpm;
  7536. char *msg;
  7537. if (PMT_CORE != pm->pmt)
  7538. return pm; /* already fragmented or reliability boxed, or control message:
  7539. do nothing */
  7540. if (NULL != pm->bpm)
  7541. return pm->bpm; /* already computed earlier: do nothing */
  7542. GNUNET_assert (NULL == pm->head_frag);
  7543. if (pm->bytes_msg + sizeof(rbox) > UINT16_MAX)
  7544. {
  7545. /* failed hard */
  7546. GNUNET_break (0);
  7547. client_send_response (pm);
  7548. return NULL;
  7549. }
  7550. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7551. "Preparing reliability box for message <%llu> to %s on queue %s\n",
  7552. pm->logging_uuid,
  7553. GNUNET_i2s (&pm->vl->target),
  7554. queue->address);
  7555. pa = prepare_pending_acknowledgement (queue, dvh, pm);
  7556. bpm = GNUNET_malloc (sizeof(struct PendingMessage) + sizeof(rbox)
  7557. + pm->bytes_msg);
  7558. bpm->logging_uuid = logging_uuid_gen++;
  7559. bpm->vl = pm->vl;
  7560. bpm->frag_parent = pm;
  7561. GNUNET_CONTAINER_MDLL_insert (frag, pm->head_frag, pm->tail_frag, bpm);
  7562. bpm->timeout = pm->timeout;
  7563. bpm->pmt = PMT_RELIABILITY_BOX;
  7564. bpm->bytes_msg = pm->bytes_msg + sizeof(rbox);
  7565. set_pending_message_uuid (bpm);
  7566. rbox.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX);
  7567. rbox.header.size = htons (sizeof(rbox) + pm->bytes_msg);
  7568. rbox.ack_countdown = htonl (0); // FIXME: implement ACK countdown support
  7569. rbox.ack_uuid = pa->ack_uuid;
  7570. msg = (char *) &bpm[1];
  7571. memcpy (msg, &rbox, sizeof(rbox));
  7572. memcpy (&msg[sizeof(rbox)], &pm[1], pm->bytes_msg);
  7573. pm->bpm = bpm;
  7574. return bpm;
  7575. }
  7576. /**
  7577. * Change the value of the `next_attempt` field of @a pm
  7578. * to @a next_attempt and re-order @a pm in the transmission
  7579. * list as required by the new timestmap.
  7580. *
  7581. * @param pm a pending message to update
  7582. * @param next_attempt timestamp to use
  7583. */
  7584. static void
  7585. update_pm_next_attempt (struct PendingMessage *pm,
  7586. struct GNUNET_TIME_Absolute next_attempt)
  7587. {
  7588. struct VirtualLink *vl = pm->vl;
  7589. pm->next_attempt = next_attempt;
  7590. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7591. "Next attempt for message <%llu> set to %s\n",
  7592. pm->logging_uuid,
  7593. GNUNET_STRINGS_absolute_time_to_string (next_attempt));
  7594. if (NULL == pm->frag_parent)
  7595. {
  7596. struct PendingMessage *pos;
  7597. /* re-insert sort in neighbour list */
  7598. GNUNET_CONTAINER_MDLL_remove (vl,
  7599. vl->pending_msg_head,
  7600. vl->pending_msg_tail,
  7601. pm);
  7602. pos = vl->pending_msg_tail;
  7603. while ((NULL != pos) &&
  7604. (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
  7605. pos = pos->prev_vl;
  7606. GNUNET_CONTAINER_MDLL_insert_after (vl,
  7607. vl->pending_msg_head,
  7608. vl->pending_msg_tail,
  7609. pos,
  7610. pm);
  7611. }
  7612. else
  7613. {
  7614. /* re-insert sort in fragment list */
  7615. struct PendingMessage *fp = pm->frag_parent;
  7616. struct PendingMessage *pos;
  7617. GNUNET_CONTAINER_MDLL_remove (frag, fp->head_frag, fp->tail_frag, pm);
  7618. pos = fp->tail_frag;
  7619. while ((NULL != pos) &&
  7620. (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
  7621. pos = pos->prev_frag;
  7622. GNUNET_CONTAINER_MDLL_insert_after (frag,
  7623. fp->head_frag,
  7624. fp->tail_frag,
  7625. pos,
  7626. pm);
  7627. }
  7628. }
  7629. /**
  7630. * Context for #select_best_pending_from_link().
  7631. */
  7632. struct PendingMessageScoreContext
  7633. {
  7634. /**
  7635. * Set to the best message that was found, NULL for none.
  7636. */
  7637. struct PendingMessage *best;
  7638. /**
  7639. * DVH that @e best should take, or NULL for direct transmission.
  7640. */
  7641. struct DistanceVectorHop *dvh;
  7642. /**
  7643. * What is the estimated total overhead for this message?
  7644. */
  7645. size_t real_overhead;
  7646. /**
  7647. * Number of pending messages we seriously considered this time.
  7648. */
  7649. unsigned int consideration_counter;
  7650. /**
  7651. * Did we have to fragment?
  7652. */
  7653. int frag;
  7654. /**
  7655. * Did we have to reliability box?
  7656. */
  7657. int relb;
  7658. };
  7659. /**
  7660. * Select the best pending message from @a vl for transmission
  7661. * via @a queue.
  7662. *
  7663. * @param sc[in,out] best message so far (NULL for none), plus scoring data
  7664. * @param queue the queue that will be used for transmission
  7665. * @param vl the virtual link providing the messages
  7666. * @param dvh path we are currently considering, or NULL for none
  7667. * @param overhead number of bytes of overhead to be expected
  7668. * from DV encapsulation (0 for without DV)
  7669. */
  7670. static void
  7671. select_best_pending_from_link (struct PendingMessageScoreContext *sc,
  7672. struct Queue *queue,
  7673. struct VirtualLink *vl,
  7674. struct DistanceVectorHop *dvh,
  7675. size_t overhead)
  7676. {
  7677. struct GNUNET_TIME_Absolute now;
  7678. now = GNUNET_TIME_absolute_get ();
  7679. for (struct PendingMessage *pos = vl->pending_msg_head; NULL != pos;
  7680. pos = pos->next_vl)
  7681. {
  7682. size_t real_overhead = overhead;
  7683. int frag;
  7684. int relb;
  7685. if ((NULL != dvh) && (PMT_DV_BOX == pos->pmt))
  7686. continue; /* DV messages must not be DV-routed to next hop! */
  7687. if (pos->next_attempt.abs_value_us > now.abs_value_us)
  7688. break; /* too early for all messages, they are sorted by next_attempt */
  7689. if (NULL != pos->qe)
  7690. continue; /* not eligible */
  7691. sc->consideration_counter++;
  7692. /* determine if we have to fragment, if so add fragmentation
  7693. overhead! */
  7694. frag = GNUNET_NO;
  7695. if (((0 != queue->mtu) &&
  7696. (pos->bytes_msg + real_overhead > queue->mtu)) ||
  7697. (pos->bytes_msg > UINT16_MAX - sizeof(struct
  7698. GNUNET_TRANSPORT_SendMessageTo))
  7699. ||
  7700. (NULL != pos->head_frag /* fragments already exist, should
  7701. respect that even if MTU is 0 for
  7702. this queue */))
  7703. {
  7704. frag = GNUNET_YES;
  7705. if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc)
  7706. {
  7707. /* FIXME-FRAG-REL-UUID: we could use an optimized, shorter fragmentation
  7708. header without the ACK UUID when using a *reliable* channel! */
  7709. }
  7710. real_overhead = overhead + sizeof(struct TransportFragmentBoxMessage);
  7711. }
  7712. /* determine if we have to reliability-box, if so add reliability box
  7713. overhead */
  7714. relb = GNUNET_NO;
  7715. if ((GNUNET_NO == frag) &&
  7716. (0 == (pos->prefs & GNUNET_MQ_PREF_UNRELIABLE)) &&
  7717. (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc))
  7718. {
  7719. relb = GNUNET_YES;
  7720. real_overhead += sizeof(struct TransportReliabilityBoxMessage);
  7721. }
  7722. /* Finally, compare to existing 'best' in sc to see if this 'pos' pending
  7723. message would beat it! */
  7724. if (NULL != sc->best)
  7725. {
  7726. /* CHECK if pos fits queue BETTER (=smaller) than pm, if not: continue;
  7727. OPTIMIZE-ME: This is a heuristic, which so far has NOT been
  7728. experimentally validated. There may be some huge potential for
  7729. improvement here. Also, we right now only compare how well the
  7730. given message fits _this_ queue, and do not consider how well other
  7731. queues might suit the message. Taking other queues into consideration
  7732. may further improve the result, but could also be expensive
  7733. in terms of CPU time. */long long sc_score = sc->frag * 40 + sc->relb * 20 + sc->real_overhead;
  7734. long long pm_score = frag * 40 + relb * 20 + real_overhead;
  7735. long long time_delta =
  7736. (sc->best->next_attempt.abs_value_us - pos->next_attempt.abs_value_us)
  7737. / 1000LL;
  7738. /* "time_delta" considers which message has been 'ready' for transmission
  7739. for longer, if a message has a preference for low latency, increase
  7740. the weight of the time_delta by 10x if it is favorable for that message */
  7741. if ((0 != (pos->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) &&
  7742. (0 != (sc->best->prefs & GNUNET_MQ_PREF_LOW_LATENCY)))
  7743. time_delta *= 10; /* increase weight (always, both are low latency) */
  7744. else if ((0 != (pos->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) &&
  7745. (time_delta > 0))
  7746. time_delta *=
  7747. 10; /* increase weight, favors 'pos', which is low latency */
  7748. else if ((0 != (sc->best->prefs & GNUNET_MQ_PREF_LOW_LATENCY)) &&
  7749. (time_delta < 0))
  7750. time_delta *=
  7751. 10; /* increase weight, favors 'sc->best', which is low latency */
  7752. if (0 != queue->mtu)
  7753. {
  7754. /* Grant bonus if we are bellow MTU, larger bonus the closer we will
  7755. be to the MTU */
  7756. if (queue->mtu > sc->real_overhead + sc->best->bytes_msg)
  7757. sc_score -= queue->mtu - (sc->real_overhead + sc->best->bytes_msg);
  7758. if (queue->mtu > real_overhead + pos->bytes_msg)
  7759. pm_score -= queue->mtu - (real_overhead + pos->bytes_msg);
  7760. }
  7761. if (sc_score + time_delta > pm_score)
  7762. continue; /* sc_score larger, keep sc->best */
  7763. }
  7764. sc->best = pos;
  7765. sc->dvh = dvh;
  7766. sc->frag = frag;
  7767. sc->relb = relb;
  7768. }
  7769. }
  7770. /**
  7771. * Function to call to further operate on the now DV encapsulated
  7772. * message @a hdr, forwarding it via @a next_hop under respect of
  7773. * @a options.
  7774. *
  7775. * @param cls a `struct PendingMessageScoreContext`
  7776. * @param next_hop next hop of the DV path
  7777. * @param hdr encapsulated message, technically a `struct TransportDFBoxMessage`
  7778. * @param options options of the original message
  7779. */
  7780. static void
  7781. extract_box_cb (void *cls,
  7782. struct Neighbour *next_hop,
  7783. const struct GNUNET_MessageHeader *hdr,
  7784. enum RouteMessageOptions options)
  7785. {
  7786. struct PendingMessageScoreContext *sc = cls;
  7787. struct PendingMessage *pm = sc->best;
  7788. struct PendingMessage *bpm;
  7789. uint16_t bsize = ntohs (hdr->size);
  7790. GNUNET_assert (NULL == pm->bpm);
  7791. bpm = GNUNET_malloc (sizeof(struct PendingMessage) + bsize);
  7792. bpm->logging_uuid = logging_uuid_gen++;
  7793. bpm->pmt = PMT_DV_BOX;
  7794. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7795. "Creating DV Box %llu for original message %llu (next hop is %s)\n",
  7796. bpm->logging_uuid,
  7797. pm->logging_uuid,
  7798. GNUNET_i2s (&next_hop->pid));
  7799. memcpy (&bpm[1], hdr, bsize);
  7800. pm->bpm = bpm;
  7801. }
  7802. /**
  7803. * We believe we are ready to transmit a `struct PendingMessage` on a
  7804. * queue, the big question is which one! We need to see if there is
  7805. * one pending that is allowed by flow control and congestion control
  7806. * and (ideally) matches our queue's performance profile.
  7807. *
  7808. * If such a message is found, we give the message to the communicator
  7809. * for transmission (updating the tracker, and re-scheduling ourselves
  7810. * if applicable).
  7811. *
  7812. * If no such message is found, the queue's `idle` field must be set
  7813. * to #GNUNET_YES.
  7814. *
  7815. * @param cls the `struct Queue` to process transmissions for
  7816. */
  7817. static void
  7818. transmit_on_queue (void *cls)
  7819. {
  7820. struct Queue *queue = cls;
  7821. struct Neighbour *n = queue->neighbour;
  7822. struct PendingMessageScoreContext sc;
  7823. struct PendingMessage *pm;
  7824. queue->transmit_task = NULL;
  7825. if (NULL == n->vl)
  7826. {
  7827. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7828. "Virtual link `%s' is down, cannot have PM for queue `%s'\n",
  7829. GNUNET_i2s (&n->pid),
  7830. queue->address);
  7831. queue->idle = GNUNET_YES;
  7832. return;
  7833. }
  7834. memset (&sc, 0, sizeof(sc));
  7835. select_best_pending_from_link (&sc, queue, n->vl, NULL, 0);
  7836. if (NULL == sc.best)
  7837. {
  7838. /* Also look at DVH that have the n as first hop! */
  7839. for (struct DistanceVectorHop *dvh = n->dv_head; NULL != dvh;
  7840. dvh = dvh->next_neighbour)
  7841. {
  7842. select_best_pending_from_link (&sc,
  7843. queue,
  7844. dvh->dv->vl,
  7845. dvh,
  7846. sizeof(struct GNUNET_PeerIdentity)
  7847. * (1 + dvh->distance)
  7848. + sizeof(struct TransportDVBoxMessage)
  7849. + sizeof(struct TransportDVBoxPayloadP));
  7850. }
  7851. }
  7852. if (NULL == sc.best)
  7853. {
  7854. /* no message pending, nothing to do here! */
  7855. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7856. "No pending messages, queue `%s' to %s now idle\n",
  7857. queue->address,
  7858. GNUNET_i2s (&n->pid));
  7859. queue->idle = GNUNET_YES;
  7860. return;
  7861. }
  7862. /* Given selection in `sc`, do transmission */
  7863. pm = sc.best;
  7864. if (NULL != sc.dvh)
  7865. {
  7866. GNUNET_assert (PMT_DV_BOX != pm->pmt);
  7867. if (NULL != sc.best->bpm)
  7868. {
  7869. /* We did this boxing before, but possibly for a different path!
  7870. Discard old DV box! OPTIMIZE-ME: we might want to check if
  7871. it is the same and then not re-build the message... */
  7872. free_pending_message (sc.best->bpm);
  7873. sc.best->bpm = NULL;
  7874. }
  7875. encapsulate_for_dv (sc.dvh->dv,
  7876. 1,
  7877. &sc.dvh,
  7878. (const struct GNUNET_MessageHeader *) &sc.best[1],
  7879. &extract_box_cb,
  7880. &sc,
  7881. RMO_NONE);
  7882. GNUNET_assert (NULL != sc.best->bpm);
  7883. pm = sc.best->bpm;
  7884. }
  7885. if (GNUNET_YES == sc.frag)
  7886. {
  7887. pm = fragment_message (queue, sc.dvh, pm);
  7888. if (NULL == pm)
  7889. {
  7890. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7891. "Fragmentation failed queue %s to %s for <%llu>, trying again\n",
  7892. queue->address,
  7893. GNUNET_i2s (&n->pid),
  7894. sc.best->logging_uuid);
  7895. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  7896. return;
  7897. }
  7898. }
  7899. else if (GNUNET_YES == sc.relb)
  7900. {
  7901. pm = reliability_box_message (queue, sc.dvh, pm);
  7902. if (NULL == pm)
  7903. {
  7904. /* Reliability boxing failed, try next message... */
  7905. GNUNET_log (
  7906. GNUNET_ERROR_TYPE_DEBUG,
  7907. "Reliability boxing failed queue %s to %s for <%llu>, trying again\n",
  7908. queue->address,
  7909. GNUNET_i2s (&n->pid),
  7910. sc.best->logging_uuid);
  7911. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  7912. return;
  7913. }
  7914. }
  7915. /* Pass 'pm' for transission to the communicator */
  7916. GNUNET_log (
  7917. GNUNET_ERROR_TYPE_DEBUG,
  7918. "Passing message <%llu> to queue %s for peer %s (considered %u others)\n",
  7919. pm->logging_uuid,
  7920. queue->address,
  7921. GNUNET_i2s (&n->pid),
  7922. sc.consideration_counter);
  7923. /* Flow control: increment amount of traffic sent; if we are routing
  7924. via DV (and thus the ultimate target of the pending message is for
  7925. a different virtual link than the one of the queue), then we need
  7926. to use up not only the window of the direct link but also the
  7927. flow control window for the DV link! */pm->vl->outbound_fc_window_size_used += pm->bytes_msg;
  7928. if (pm->vl != queue->neighbour->vl)
  7929. {
  7930. /* If the virtual link of the queue differs, this better be distance
  7931. vector routing! */
  7932. GNUNET_assert (NULL != sc.dvh);
  7933. /* If we do distance vector routing, we better not do this for a
  7934. message that was itself DV-routed */
  7935. GNUNET_assert (PMT_DV_BOX != sc.best->pmt);
  7936. /* We use the size of the unboxed message here, to avoid counting
  7937. the DV-Box header which is eaten up on the way by intermediaries */
  7938. queue->neighbour->vl->outbound_fc_window_size_used += sc.best->bytes_msg;
  7939. }
  7940. else
  7941. {
  7942. GNUNET_assert (NULL == sc.dvh);
  7943. }
  7944. queue_send_msg (queue, pm, &pm[1], pm->bytes_msg);
  7945. /* Check if this transmission somehow conclusively finished handing 'pm'
  7946. even without any explicit ACKs */
  7947. if ((PMT_CORE == pm->pmt) ||
  7948. (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc))
  7949. {
  7950. completed_pending_message (pm);
  7951. }
  7952. else
  7953. {
  7954. /* Message not finished, waiting for acknowledgement.
  7955. Update time by which we might retransmit 's' based on queue
  7956. characteristics (i.e. RTT); it takes one RTT for the message to
  7957. arrive and the ACK to come back in the best case; but the other
  7958. side is allowed to delay ACKs by 2 RTTs, so we use 4 RTT before
  7959. retransmitting.
  7960. OPTIMIZE: Note that in the future this heuristic should likely
  7961. be improved further (measure RTT stability, consider message
  7962. urgency and size when delaying ACKs, etc.) */update_pm_next_attempt (pm,
  7963. GNUNET_TIME_relative_to_absolute (
  7964. GNUNET_TIME_relative_multiply (queue->pd.aged_rtt,
  7965. 4)));
  7966. }
  7967. /* finally, re-schedule queue transmission task itself */
  7968. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  7969. }
  7970. /**
  7971. * Queue to a peer went down. Process the request.
  7972. *
  7973. * @param cls the client
  7974. * @param dqm the send message that was sent
  7975. */
  7976. static void
  7977. handle_del_queue_message (void *cls,
  7978. const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
  7979. {
  7980. struct TransportClient *tc = cls;
  7981. if (CT_COMMUNICATOR != tc->type)
  7982. {
  7983. GNUNET_break (0);
  7984. GNUNET_SERVICE_client_drop (tc->client);
  7985. return;
  7986. }
  7987. for (struct Queue *queue = tc->details.communicator.queue_head; NULL != queue;
  7988. queue = queue->next_client)
  7989. {
  7990. struct Neighbour *neighbour = queue->neighbour;
  7991. if ((dqm->qid != queue->qid) ||
  7992. (0 != GNUNET_memcmp (&dqm->receiver, &neighbour->pid)))
  7993. continue;
  7994. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  7995. "Dropped queue %s to peer %s\n",
  7996. queue->address,
  7997. GNUNET_i2s (&neighbour->pid));
  7998. free_queue (queue);
  7999. GNUNET_SERVICE_client_continue (tc->client);
  8000. return;
  8001. }
  8002. GNUNET_break (0);
  8003. GNUNET_SERVICE_client_drop (tc->client);
  8004. }
  8005. /**
  8006. * Message was transmitted. Process the request.
  8007. *
  8008. * @param cls the client
  8009. * @param sma the send message that was sent
  8010. */
  8011. static void
  8012. handle_send_message_ack (void *cls,
  8013. const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
  8014. {
  8015. struct TransportClient *tc = cls;
  8016. struct QueueEntry *qe;
  8017. struct PendingMessage *pm;
  8018. if (CT_COMMUNICATOR != tc->type)
  8019. {
  8020. GNUNET_break (0);
  8021. GNUNET_SERVICE_client_drop (tc->client);
  8022. return;
  8023. }
  8024. /* find our queue entry matching the ACK */
  8025. qe = NULL;
  8026. for (struct Queue *queue = tc->details.communicator.queue_head; NULL != queue;
  8027. queue = queue->next_client)
  8028. {
  8029. if (0 != GNUNET_memcmp (&queue->neighbour->pid, &sma->receiver))
  8030. continue;
  8031. for (struct QueueEntry *qep = queue->queue_head; NULL != qep;
  8032. qep = qep->next)
  8033. {
  8034. if (qep->mid != sma->mid)
  8035. continue;
  8036. qe = qep;
  8037. break;
  8038. }
  8039. break;
  8040. }
  8041. if (NULL == qe)
  8042. {
  8043. /* this should never happen */
  8044. GNUNET_break (0);
  8045. GNUNET_SERVICE_client_drop (tc->client);
  8046. return;
  8047. }
  8048. GNUNET_CONTAINER_DLL_remove (qe->queue->queue_head,
  8049. qe->queue->queue_tail,
  8050. qe);
  8051. qe->queue->queue_length--;
  8052. tc->details.communicator.total_queue_length--;
  8053. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8054. "Received ACK on queue %s to peer %s (new length: %u/%u)\n",
  8055. qe->queue->address,
  8056. GNUNET_i2s (&qe->queue->neighbour->pid),
  8057. qe->queue->queue_length,
  8058. tc->details.communicator.total_queue_length);
  8059. GNUNET_SERVICE_client_continue (tc->client);
  8060. /* if applicable, resume transmissions that waited on ACK */
  8061. if (COMMUNICATOR_TOTAL_QUEUE_LIMIT - 1 ==
  8062. tc->details.communicator.total_queue_length)
  8063. {
  8064. /* Communicator dropped below threshold, resume all queues
  8065. incident with this client! */
  8066. GNUNET_STATISTICS_update (
  8067. GST_stats,
  8068. "# Transmission throttled due to communicator queue limit",
  8069. -1,
  8070. GNUNET_NO);
  8071. for (struct Queue *queue = tc->details.communicator.queue_head;
  8072. NULL != queue;
  8073. queue = queue->next_client)
  8074. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  8075. }
  8076. else if (QUEUE_LENGTH_LIMIT - 1 == qe->queue->queue_length)
  8077. {
  8078. /* queue dropped below threshold; only resume this one queue */
  8079. GNUNET_STATISTICS_update (GST_stats,
  8080. "# Transmission throttled due to queue queue limit",
  8081. -1,
  8082. GNUNET_NO);
  8083. schedule_transmit_on_queue (qe->queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  8084. }
  8085. if (NULL != (pm = qe->pm))
  8086. {
  8087. struct VirtualLink *vl;
  8088. GNUNET_assert (qe == pm->qe);
  8089. pm->qe = NULL;
  8090. /* If waiting for this communicator may have blocked transmission
  8091. of pm on other queues for this neighbour, force schedule
  8092. transmit on queue for queues of the neighbour */
  8093. vl = pm->vl;
  8094. if (vl->pending_msg_head == pm)
  8095. check_vl_transmission (vl);
  8096. }
  8097. GNUNET_free (qe);
  8098. }
  8099. /**
  8100. * Iterator telling new MONITOR client about all existing
  8101. * queues to peers.
  8102. *
  8103. * @param cls the new `struct TransportClient`
  8104. * @param pid a connected peer
  8105. * @param value the `struct Neighbour` with more information
  8106. * @return #GNUNET_OK (continue to iterate)
  8107. */
  8108. static int
  8109. notify_client_queues (void *cls,
  8110. const struct GNUNET_PeerIdentity *pid,
  8111. void *value)
  8112. {
  8113. struct TransportClient *tc = cls;
  8114. struct Neighbour *neighbour = value;
  8115. GNUNET_assert (CT_MONITOR == tc->type);
  8116. for (struct Queue *q = neighbour->queue_head; NULL != q;
  8117. q = q->next_neighbour)
  8118. {
  8119. struct MonitorEvent me = { .rtt = q->pd.aged_rtt,
  8120. .cs = q->cs,
  8121. .num_msg_pending = q->num_msg_pending,
  8122. .num_bytes_pending = q->num_bytes_pending };
  8123. notify_monitor (tc, pid, q->address, q->nt, &me);
  8124. }
  8125. return GNUNET_OK;
  8126. }
  8127. /**
  8128. * Initialize a monitor client.
  8129. *
  8130. * @param cls the client
  8131. * @param start the start message that was sent
  8132. */
  8133. static void
  8134. handle_monitor_start (void *cls,
  8135. const struct GNUNET_TRANSPORT_MonitorStart *start)
  8136. {
  8137. struct TransportClient *tc = cls;
  8138. if (CT_NONE != tc->type)
  8139. {
  8140. GNUNET_break (0);
  8141. GNUNET_SERVICE_client_drop (tc->client);
  8142. return;
  8143. }
  8144. tc->type = CT_MONITOR;
  8145. tc->details.monitor.peer = start->peer;
  8146. tc->details.monitor.one_shot = ntohl (start->one_shot);
  8147. GNUNET_CONTAINER_multipeermap_iterate (neighbours, &notify_client_queues, tc);
  8148. GNUNET_SERVICE_client_mark_monitor (tc->client);
  8149. GNUNET_SERVICE_client_continue (tc->client);
  8150. }
  8151. /**
  8152. * Find transport client providing communication service
  8153. * for the protocol @a prefix.
  8154. *
  8155. * @param prefix communicator name
  8156. * @return NULL if no such transport client is available
  8157. */
  8158. static struct TransportClient *
  8159. lookup_communicator (const char *prefix)
  8160. {
  8161. for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
  8162. {
  8163. if (CT_COMMUNICATOR != tc->type)
  8164. continue;
  8165. if (0 == strcmp (prefix, tc->details.communicator.address_prefix))
  8166. return tc;
  8167. }
  8168. GNUNET_log (
  8169. GNUNET_ERROR_TYPE_WARNING,
  8170. "Somone suggested use of communicator for `%s', but we do not have such a communicator!\n",
  8171. prefix);
  8172. return NULL;
  8173. }
  8174. /**
  8175. * Signature of a function called with a communicator @a address of a peer
  8176. * @a pid that an application wants us to connect to.
  8177. *
  8178. * @param pid target peer
  8179. * @param address the address to try
  8180. */
  8181. static void
  8182. suggest_to_connect (const struct GNUNET_PeerIdentity *pid, const char *address)
  8183. {
  8184. static uint32_t idgen;
  8185. struct TransportClient *tc;
  8186. char *prefix;
  8187. struct GNUNET_TRANSPORT_CreateQueue *cqm;
  8188. struct GNUNET_MQ_Envelope *env;
  8189. size_t alen;
  8190. prefix = GNUNET_HELLO_address_to_prefix (address);
  8191. if (NULL == prefix)
  8192. {
  8193. GNUNET_break (0); /* We got an invalid address!? */
  8194. return;
  8195. }
  8196. tc = lookup_communicator (prefix);
  8197. if (NULL == tc)
  8198. {
  8199. GNUNET_STATISTICS_update (GST_stats,
  8200. "# Suggestions ignored due to missing communicator",
  8201. 1,
  8202. GNUNET_NO);
  8203. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  8204. "Cannot connect to %s at `%s', no matching communicator present\n",
  8205. GNUNET_i2s (pid),
  8206. address);
  8207. GNUNET_free (prefix);
  8208. return;
  8209. }
  8210. /* forward suggestion for queue creation to communicator */
  8211. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8212. "Request #%u for `%s' communicator to create queue to `%s'\n",
  8213. (unsigned int) idgen,
  8214. prefix,
  8215. address);
  8216. GNUNET_free (prefix);
  8217. alen = strlen (address) + 1;
  8218. env =
  8219. GNUNET_MQ_msg_extra (cqm, alen, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE);
  8220. cqm->request_id = htonl (idgen++);
  8221. cqm->receiver = *pid;
  8222. memcpy (&cqm[1], address, alen);
  8223. GNUNET_MQ_send (tc->mq, env);
  8224. }
  8225. /**
  8226. * The queue @a q (which matches the peer and address in @a vs) is
  8227. * ready for queueing. We should now queue the validation request.
  8228. *
  8229. * @param q queue to send on
  8230. * @param vs state to derive validation challenge from
  8231. */
  8232. static void
  8233. validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs)
  8234. {
  8235. struct TransportValidationChallengeMessage tvc;
  8236. vs->last_challenge_use = GNUNET_TIME_absolute_get_monotonic (GST_cfg);
  8237. tvc.header.type =
  8238. htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE);
  8239. tvc.header.size = htons (sizeof(tvc));
  8240. tvc.reserved = htonl (0);
  8241. tvc.challenge = vs->challenge;
  8242. tvc.sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use);
  8243. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  8244. "Sending address validation challenge %s to %s\n",
  8245. GNUNET_sh2s (&tvc.challenge.value),
  8246. GNUNET_i2s (&q->neighbour->pid));
  8247. queue_send_msg (q, NULL, &tvc, sizeof(tvc));
  8248. }
  8249. /**
  8250. * Task run periodically to validate some address based on #validation_heap.
  8251. *
  8252. * @param cls NULL
  8253. */
  8254. static void
  8255. validation_start_cb (void *cls)
  8256. {
  8257. struct ValidationState *vs;
  8258. struct Queue *q;
  8259. (void) cls;
  8260. validation_task = NULL;
  8261. vs = GNUNET_CONTAINER_heap_peek (validation_heap);
  8262. /* drop validations past their expiration */
  8263. while (
  8264. (NULL != vs) &&
  8265. (0 == GNUNET_TIME_absolute_get_remaining (vs->valid_until).rel_value_us))
  8266. {
  8267. free_validation_state (vs);
  8268. vs = GNUNET_CONTAINER_heap_peek (validation_heap);
  8269. }
  8270. if (NULL == vs)
  8271. {
  8272. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  8273. "Address validation task not scheduled anymore, nothing to do\n");
  8274. return; /* woopsie, no more addresses known, should only
  8275. happen if we're really a lonely peer */
  8276. }
  8277. q = find_queue (&vs->pid, vs->address);
  8278. if (NULL == q)
  8279. {
  8280. vs->awaiting_queue = GNUNET_YES;
  8281. suggest_to_connect (&vs->pid, vs->address);
  8282. }
  8283. else
  8284. validation_transmit_on_queue (q, vs);
  8285. /* Finally, reschedule next attempt */
  8286. vs->challenge_backoff =
  8287. GNUNET_TIME_randomized_backoff (vs->challenge_backoff,
  8288. MAX_VALIDATION_CHALLENGE_FREQ);
  8289. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8290. "Address validation task will run again in %s\n",
  8291. GNUNET_STRINGS_relative_time_to_string (vs->challenge_backoff,
  8292. GNUNET_YES));
  8293. update_next_challenge_time (vs,
  8294. GNUNET_TIME_relative_to_absolute (
  8295. vs->challenge_backoff));
  8296. }
  8297. /**
  8298. * Closure for #check_connection_quality.
  8299. */
  8300. struct QueueQualityContext
  8301. {
  8302. /**
  8303. * Set to the @e k'th queue encountered.
  8304. */
  8305. struct Queue *q;
  8306. /**
  8307. * Set to the number of quality queues encountered.
  8308. */
  8309. unsigned int quality_count;
  8310. /**
  8311. * Set to the total number of queues encountered.
  8312. */
  8313. unsigned int num_queues;
  8314. /**
  8315. * Decremented for each queue, for selection of the
  8316. * k-th queue in @e q.
  8317. */
  8318. unsigned int k;
  8319. };
  8320. /**
  8321. * Check whether any queue to the given neighbour is
  8322. * of a good "quality" and if so, increment the counter.
  8323. * Also counts the total number of queues, and returns
  8324. * the k-th queue found.
  8325. *
  8326. * @param cls a `struct QueueQualityContext *` with counters
  8327. * @param pid peer this is about
  8328. * @param value a `struct Neighbour`
  8329. * @return #GNUNET_OK (continue to iterate)
  8330. */
  8331. static int
  8332. check_connection_quality (void *cls,
  8333. const struct GNUNET_PeerIdentity *pid,
  8334. void *value)
  8335. {
  8336. struct QueueQualityContext *ctx = cls;
  8337. struct Neighbour *n = value;
  8338. int do_inc;
  8339. (void) pid;
  8340. do_inc = GNUNET_NO;
  8341. for (struct Queue *q = n->queue_head; NULL != q; q = q->next_neighbour)
  8342. {
  8343. ctx->num_queues++;
  8344. if (0 == ctx->k--)
  8345. ctx->q = q;
  8346. /* FIXME-CONQ-STATISTICS: in the future, add reliability / goodput
  8347. statistics and consider those as well here? */
  8348. if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us)
  8349. do_inc = GNUNET_YES;
  8350. }
  8351. if (GNUNET_YES == do_inc)
  8352. ctx->quality_count++;
  8353. return GNUNET_OK;
  8354. }
  8355. /**
  8356. * Task run when we CONSIDER initiating a DV learn
  8357. * process. We first check that sending out a message is
  8358. * even possible (queues exist), then that it is desirable
  8359. * (if not, reschedule the task for later), and finally
  8360. * we may then begin the job. If there are too many
  8361. * entries in the #dvlearn_map, we purge the oldest entry
  8362. * using #lle_tail.
  8363. *
  8364. * @param cls NULL
  8365. */
  8366. static void
  8367. start_dv_learn (void *cls)
  8368. {
  8369. struct LearnLaunchEntry *lle;
  8370. struct QueueQualityContext qqc;
  8371. struct TransportDVLearnMessage dvl;
  8372. (void) cls;
  8373. dvlearn_task = NULL;
  8374. if (0 == GNUNET_CONTAINER_multipeermap_size (neighbours))
  8375. return; /* lost all connectivity, cannot do learning */
  8376. qqc.quality_count = 0;
  8377. qqc.num_queues = 0;
  8378. GNUNET_CONTAINER_multipeermap_iterate (neighbours,
  8379. &check_connection_quality,
  8380. &qqc);
  8381. if (qqc.quality_count > DV_LEARN_QUALITY_THRESHOLD)
  8382. {
  8383. struct GNUNET_TIME_Relative delay;
  8384. unsigned int factor;
  8385. /* scale our retries by how far we are above the threshold */
  8386. factor = qqc.quality_count / DV_LEARN_QUALITY_THRESHOLD;
  8387. delay = GNUNET_TIME_relative_multiply (DV_LEARN_BASE_FREQUENCY, factor);
  8388. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8389. "At connection quality %u, will launch DV learn in %s\n",
  8390. qqc.quality_count,
  8391. GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
  8392. dvlearn_task = GNUNET_SCHEDULER_add_delayed (delay, &start_dv_learn, NULL);
  8393. return;
  8394. }
  8395. /* remove old entries in #dvlearn_map if it has grown too big */
  8396. while (MAX_DV_LEARN_PENDING >=
  8397. GNUNET_CONTAINER_multishortmap_size (dvlearn_map))
  8398. {
  8399. lle = lle_tail;
  8400. GNUNET_assert (GNUNET_YES ==
  8401. GNUNET_CONTAINER_multishortmap_remove (dvlearn_map,
  8402. &lle->challenge.value,
  8403. lle));
  8404. GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle);
  8405. GNUNET_free (lle);
  8406. }
  8407. /* setup data structure for learning */
  8408. lle = GNUNET_new (struct LearnLaunchEntry);
  8409. GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
  8410. &lle->challenge,
  8411. sizeof(lle->challenge));
  8412. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8413. "Starting launch DV learn with challenge %s\n",
  8414. GNUNET_sh2s (&lle->challenge.value));
  8415. GNUNET_CONTAINER_DLL_insert (lle_head, lle_tail, lle);
  8416. GNUNET_break (GNUNET_YES ==
  8417. GNUNET_CONTAINER_multishortmap_put (
  8418. dvlearn_map,
  8419. &lle->challenge.value,
  8420. lle,
  8421. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  8422. dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
  8423. dvl.header.size = htons (sizeof(dvl));
  8424. dvl.num_hops = htons (0);
  8425. dvl.bidirectional = htons (0);
  8426. dvl.non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO);
  8427. dvl.monotonic_time =
  8428. GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
  8429. {
  8430. struct DvInitPS dvip = {
  8431. .purpose.purpose = htonl (
  8432. GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
  8433. .purpose.size = htonl (sizeof(dvip)),
  8434. .monotonic_time = dvl.monotonic_time,
  8435. .challenge = lle->challenge
  8436. };
  8437. GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
  8438. &dvip,
  8439. &dvl.init_sig);
  8440. }
  8441. dvl.initiator = GST_my_identity;
  8442. dvl.challenge = lle->challenge;
  8443. qqc.quality_count = 0;
  8444. qqc.k = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, qqc.num_queues);
  8445. qqc.num_queues = 0;
  8446. qqc.q = NULL;
  8447. GNUNET_CONTAINER_multipeermap_iterate (neighbours,
  8448. &check_connection_quality,
  8449. &qqc);
  8450. GNUNET_assert (NULL != qqc.q);
  8451. /* Do this as close to transmission time as possible! */
  8452. lle->launch_time = GNUNET_TIME_absolute_get ();
  8453. queue_send_msg (qqc.q, NULL, &dvl, sizeof(dvl));
  8454. /* reschedule this job, randomizing the time it runs (but no
  8455. actual backoff!) */
  8456. dvlearn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_randomize (
  8457. DV_LEARN_BASE_FREQUENCY),
  8458. &start_dv_learn,
  8459. NULL);
  8460. }
  8461. /**
  8462. * A new queue has been created, check if any address validation
  8463. * requests have been waiting for it.
  8464. *
  8465. * @param cls a `struct Queue`
  8466. * @param pid peer concerned (unused)
  8467. * @param value a `struct ValidationState`
  8468. * @return #GNUNET_NO if a match was found and we can stop looking
  8469. */
  8470. static int
  8471. check_validation_request_pending (void *cls,
  8472. const struct GNUNET_PeerIdentity *pid,
  8473. void *value)
  8474. {
  8475. struct Queue *q = cls;
  8476. struct ValidationState *vs = value;
  8477. (void) pid;
  8478. if ((GNUNET_YES == vs->awaiting_queue) &&
  8479. (0 == strcmp (vs->address, q->address)))
  8480. {
  8481. vs->awaiting_queue = GNUNET_NO;
  8482. validation_transmit_on_queue (q, vs);
  8483. return GNUNET_NO;
  8484. }
  8485. return GNUNET_OK;
  8486. }
  8487. /**
  8488. * Function called with the monotonic time of a DV initiator
  8489. * by PEERSTORE. Updates the time.
  8490. *
  8491. * @param cls a `struct Neighbour`
  8492. * @param record the information found, NULL for the last call
  8493. * @param emsg error message
  8494. */
  8495. static void
  8496. neighbour_dv_monotime_cb (void *cls,
  8497. const struct GNUNET_PEERSTORE_Record *record,
  8498. const char *emsg)
  8499. {
  8500. struct Neighbour *n = cls;
  8501. struct GNUNET_TIME_AbsoluteNBO *mtbe;
  8502. (void) emsg;
  8503. if (NULL == record)
  8504. {
  8505. /* we're done with #neighbour_dv_monotime_cb() invocations,
  8506. continue normal processing */
  8507. n->get = NULL;
  8508. n->dv_monotime_available = GNUNET_YES;
  8509. return;
  8510. }
  8511. if (sizeof(*mtbe) != record->value_size)
  8512. {
  8513. GNUNET_break (0);
  8514. return;
  8515. }
  8516. mtbe = record->value;
  8517. n->last_dv_learn_monotime =
  8518. GNUNET_TIME_absolute_max (n->last_dv_learn_monotime,
  8519. GNUNET_TIME_absolute_ntoh (*mtbe));
  8520. }
  8521. /**
  8522. * New queue became available. Process the request.
  8523. *
  8524. * @param cls the client
  8525. * @param aqm the send message that was sent
  8526. */
  8527. static void
  8528. handle_add_queue_message (void *cls,
  8529. const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
  8530. {
  8531. struct TransportClient *tc = cls;
  8532. struct Queue *queue;
  8533. struct Neighbour *neighbour;
  8534. const char *addr;
  8535. uint16_t addr_len;
  8536. if (ntohl (aqm->mtu) <= sizeof(struct TransportFragmentBoxMessage))
  8537. {
  8538. /* MTU so small as to be useless for transmissions,
  8539. required for #fragment_message()! */
  8540. GNUNET_break_op (0);
  8541. GNUNET_SERVICE_client_drop (tc->client);
  8542. return;
  8543. }
  8544. neighbour = lookup_neighbour (&aqm->receiver);
  8545. if (NULL == neighbour)
  8546. {
  8547. neighbour = GNUNET_new (struct Neighbour);
  8548. neighbour->pid = aqm->receiver;
  8549. GNUNET_assert (GNUNET_OK ==
  8550. GNUNET_CONTAINER_multipeermap_put (
  8551. neighbours,
  8552. &neighbour->pid,
  8553. neighbour,
  8554. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  8555. neighbour->get =
  8556. GNUNET_PEERSTORE_iterate (peerstore,
  8557. "transport",
  8558. &neighbour->pid,
  8559. GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME,
  8560. &neighbour_dv_monotime_cb,
  8561. neighbour);
  8562. }
  8563. addr_len = ntohs (aqm->header.size) - sizeof(*aqm);
  8564. addr = (const char *) &aqm[1];
  8565. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8566. "New queue %s to %s available with QID %llu\n",
  8567. addr,
  8568. GNUNET_i2s (&aqm->receiver),
  8569. (unsigned long long) aqm->qid);
  8570. queue = GNUNET_malloc (sizeof(struct Queue) + addr_len);
  8571. queue->tc = tc;
  8572. queue->address = (const char *) &queue[1];
  8573. queue->pd.aged_rtt = GNUNET_TIME_UNIT_FOREVER_REL;
  8574. queue->qid = aqm->qid;
  8575. queue->mtu = ntohl (aqm->mtu);
  8576. queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt);
  8577. queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs);
  8578. queue->neighbour = neighbour;
  8579. queue->idle = GNUNET_YES;
  8580. memcpy (&queue[1], addr, addr_len);
  8581. /* notify monitors about new queue */
  8582. {
  8583. struct MonitorEvent me = { .rtt = queue->pd.aged_rtt, .cs = queue->cs };
  8584. notify_monitors (&neighbour->pid, queue->address, queue->nt, &me);
  8585. }
  8586. GNUNET_CONTAINER_MDLL_insert (neighbour,
  8587. neighbour->queue_head,
  8588. neighbour->queue_tail,
  8589. queue);
  8590. GNUNET_CONTAINER_MDLL_insert (client,
  8591. tc->details.communicator.queue_head,
  8592. tc->details.communicator.queue_tail,
  8593. queue);
  8594. /* check if valdiations are waiting for the queue */
  8595. (void)
  8596. GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
  8597. &aqm->receiver,
  8598. &check_validation_request_pending,
  8599. queue);
  8600. /* look for traffic for this queue */
  8601. schedule_transmit_on_queue (queue, GNUNET_SCHEDULER_PRIORITY_DEFAULT);
  8602. /* might be our first queue, try launching DV learning */
  8603. if (NULL == dvlearn_task)
  8604. dvlearn_task = GNUNET_SCHEDULER_add_now (&start_dv_learn, NULL);
  8605. GNUNET_SERVICE_client_continue (tc->client);
  8606. }
  8607. /**
  8608. * Communicator tells us that our request to create a queue "worked", that
  8609. * is setting up the queue is now in process.
  8610. *
  8611. * @param cls the `struct TransportClient`
  8612. * @param cqr confirmation message
  8613. */
  8614. static void
  8615. handle_queue_create_ok (void *cls,
  8616. const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
  8617. {
  8618. struct TransportClient *tc = cls;
  8619. if (CT_COMMUNICATOR != tc->type)
  8620. {
  8621. GNUNET_break (0);
  8622. GNUNET_SERVICE_client_drop (tc->client);
  8623. return;
  8624. }
  8625. GNUNET_STATISTICS_update (GST_stats,
  8626. "# Suggestions succeeded at communicator",
  8627. 1,
  8628. GNUNET_NO);
  8629. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8630. "Request #%u for communicator to create queue succeeded\n",
  8631. (unsigned int) ntohs (cqr->request_id));
  8632. GNUNET_SERVICE_client_continue (tc->client);
  8633. }
  8634. /**
  8635. * Communicator tells us that our request to create a queue failed. This
  8636. * usually indicates that the provided address is simply invalid or that the
  8637. * communicator's resources are exhausted.
  8638. *
  8639. * @param cls the `struct TransportClient`
  8640. * @param cqr failure message
  8641. */
  8642. static void
  8643. handle_queue_create_fail (
  8644. void *cls,
  8645. const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
  8646. {
  8647. struct TransportClient *tc = cls;
  8648. if (CT_COMMUNICATOR != tc->type)
  8649. {
  8650. GNUNET_break (0);
  8651. GNUNET_SERVICE_client_drop (tc->client);
  8652. return;
  8653. }
  8654. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8655. "Request #%u for communicator to create queue failed\n",
  8656. (unsigned int) ntohs (cqr->request_id));
  8657. GNUNET_STATISTICS_update (GST_stats,
  8658. "# Suggestions failed in queue creation at communicator",
  8659. 1,
  8660. GNUNET_NO);
  8661. GNUNET_SERVICE_client_continue (tc->client);
  8662. }
  8663. /**
  8664. * We have received a `struct ExpressPreferenceMessage` from an application
  8665. * client.
  8666. *
  8667. * @param cls handle to the client
  8668. * @param msg the start message
  8669. */
  8670. static void
  8671. handle_suggest_cancel (void *cls, const struct ExpressPreferenceMessage *msg)
  8672. {
  8673. struct TransportClient *tc = cls;
  8674. struct PeerRequest *pr;
  8675. if (CT_APPLICATION != tc->type)
  8676. {
  8677. GNUNET_break (0);
  8678. GNUNET_SERVICE_client_drop (tc->client);
  8679. return;
  8680. }
  8681. pr = GNUNET_CONTAINER_multipeermap_get (tc->details.application.requests,
  8682. &msg->peer);
  8683. if (NULL == pr)
  8684. {
  8685. GNUNET_break (0);
  8686. GNUNET_SERVICE_client_drop (tc->client);
  8687. return;
  8688. }
  8689. (void) stop_peer_request (tc, &pr->pid, pr);
  8690. GNUNET_SERVICE_client_continue (tc->client);
  8691. }
  8692. /**
  8693. * Function called by PEERSTORE for each matching record.
  8694. *
  8695. * @param cls closure, a `struct PeerRequest`
  8696. * @param record peerstore record information
  8697. * @param emsg error message, or NULL if no errors
  8698. */
  8699. static void
  8700. handle_hello_for_client (void *cls,
  8701. const struct GNUNET_PEERSTORE_Record *record,
  8702. const char *emsg)
  8703. {
  8704. struct PeerRequest *pr = cls;
  8705. const char *val;
  8706. if (NULL != emsg)
  8707. {
  8708. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  8709. "Got failure from PEERSTORE: %s\n",
  8710. emsg);
  8711. return;
  8712. }
  8713. val = record->value;
  8714. if ((0 == record->value_size) || ('\0' != val[record->value_size - 1]))
  8715. {
  8716. GNUNET_break (0);
  8717. return;
  8718. }
  8719. start_address_validation (&pr->pid, (const char *) record->value);
  8720. }
  8721. /**
  8722. * We have received a `struct ExpressPreferenceMessage` from an application
  8723. * client.
  8724. *
  8725. * @param cls handle to the client
  8726. * @param msg the start message
  8727. */
  8728. static void
  8729. handle_suggest (void *cls, const struct ExpressPreferenceMessage *msg)
  8730. {
  8731. struct TransportClient *tc = cls;
  8732. struct PeerRequest *pr;
  8733. if (CT_NONE == tc->type)
  8734. {
  8735. tc->type = CT_APPLICATION;
  8736. tc->details.application.requests =
  8737. GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
  8738. }
  8739. if (CT_APPLICATION != tc->type)
  8740. {
  8741. GNUNET_break (0);
  8742. GNUNET_SERVICE_client_drop (tc->client);
  8743. return;
  8744. }
  8745. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  8746. "Client suggested we talk to %s with preference %d at rate %u\n",
  8747. GNUNET_i2s (&msg->peer),
  8748. (int) ntohl (msg->pk),
  8749. (int) ntohl (msg->bw.value__));
  8750. pr = GNUNET_new (struct PeerRequest);
  8751. pr->tc = tc;
  8752. pr->pid = msg->peer;
  8753. pr->bw = msg->bw;
  8754. pr->pk = (enum GNUNET_MQ_PriorityPreferences) ntohl (msg->pk);
  8755. if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_put (
  8756. tc->details.application.requests,
  8757. &pr->pid,
  8758. pr,
  8759. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
  8760. {
  8761. GNUNET_break (0);
  8762. GNUNET_free (pr);
  8763. GNUNET_SERVICE_client_drop (tc->client);
  8764. return;
  8765. }
  8766. pr->wc = GNUNET_PEERSTORE_watch (peerstore,
  8767. "transport",
  8768. &pr->pid,
  8769. GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
  8770. &handle_hello_for_client,
  8771. pr);
  8772. GNUNET_SERVICE_client_continue (tc->client);
  8773. }
  8774. /**
  8775. * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
  8776. * messages.
  8777. *
  8778. * @param cls a `struct TransportClient *`
  8779. * @param m message to verify
  8780. * @return #GNUNET_OK on success
  8781. */
  8782. static int
  8783. check_request_hello_validation (void *cls,
  8784. const struct RequestHelloValidationMessage *m)
  8785. {
  8786. (void) cls;
  8787. GNUNET_MQ_check_zero_termination (m);
  8788. return GNUNET_OK;
  8789. }
  8790. /**
  8791. * A client encountered an address of another peer. Consider validating it,
  8792. * and if validation succeeds, persist it to PEERSTORE.
  8793. *
  8794. * @param cls a `struct TransportClient *`
  8795. * @param m message to verify
  8796. */
  8797. static void
  8798. handle_request_hello_validation (void *cls,
  8799. const struct RequestHelloValidationMessage *m)
  8800. {
  8801. struct TransportClient *tc = cls;
  8802. start_address_validation (&m->peer, (const char *) &m[1]);
  8803. GNUNET_SERVICE_client_continue (tc->client);
  8804. }
  8805. /**
  8806. * Free neighbour entry.
  8807. *
  8808. * @param cls NULL
  8809. * @param pid unused
  8810. * @param value a `struct Neighbour`
  8811. * @return #GNUNET_OK (always)
  8812. */
  8813. static int
  8814. free_neighbour_cb (void *cls,
  8815. const struct GNUNET_PeerIdentity *pid,
  8816. void *value)
  8817. {
  8818. struct Neighbour *neighbour = value;
  8819. (void) cls;
  8820. (void) pid;
  8821. GNUNET_break (0); // should this ever happen?
  8822. free_neighbour (neighbour);
  8823. return GNUNET_OK;
  8824. }
  8825. /**
  8826. * Free DV route entry.
  8827. *
  8828. * @param cls NULL
  8829. * @param pid unused
  8830. * @param value a `struct DistanceVector`
  8831. * @return #GNUNET_OK (always)
  8832. */
  8833. static int
  8834. free_dv_routes_cb (void *cls,
  8835. const struct GNUNET_PeerIdentity *pid,
  8836. void *value)
  8837. {
  8838. struct DistanceVector *dv = value;
  8839. (void) cls;
  8840. (void) pid;
  8841. free_dv_route (dv);
  8842. return GNUNET_OK;
  8843. }
  8844. /**
  8845. * Free validation state.
  8846. *
  8847. * @param cls NULL
  8848. * @param pid unused
  8849. * @param value a `struct ValidationState`
  8850. * @return #GNUNET_OK (always)
  8851. */
  8852. static int
  8853. free_validation_state_cb (void *cls,
  8854. const struct GNUNET_PeerIdentity *pid,
  8855. void *value)
  8856. {
  8857. struct ValidationState *vs = value;
  8858. (void) cls;
  8859. (void) pid;
  8860. free_validation_state (vs);
  8861. return GNUNET_OK;
  8862. }
  8863. /**
  8864. * Free pending acknowledgement.
  8865. *
  8866. * @param cls NULL
  8867. * @param key unused
  8868. * @param value a `struct PendingAcknowledgement`
  8869. * @return #GNUNET_OK (always)
  8870. */
  8871. static int
  8872. free_pending_ack_cb (void *cls, const struct GNUNET_Uuid *key, void *value)
  8873. {
  8874. struct PendingAcknowledgement *pa = value;
  8875. (void) cls;
  8876. (void) key;
  8877. free_pending_acknowledgement (pa);
  8878. return GNUNET_OK;
  8879. }
  8880. /**
  8881. * Free acknowledgement cummulator.
  8882. *
  8883. * @param cls NULL
  8884. * @param pid unused
  8885. * @param value a `struct AcknowledgementCummulator`
  8886. * @return #GNUNET_OK (always)
  8887. */
  8888. static int
  8889. free_ack_cummulator_cb (void *cls,
  8890. const struct GNUNET_PeerIdentity *pid,
  8891. void *value)
  8892. {
  8893. struct AcknowledgementCummulator *ac = value;
  8894. (void) cls;
  8895. (void) pid;
  8896. GNUNET_free (ac);
  8897. return GNUNET_OK;
  8898. }
  8899. /**
  8900. * Function called when the service shuts down. Unloads our plugins
  8901. * and cancels pending validations.
  8902. *
  8903. * @param cls closure, unused
  8904. */
  8905. static void
  8906. do_shutdown (void *cls)
  8907. {
  8908. struct LearnLaunchEntry *lle;
  8909. (void) cls;
  8910. GNUNET_CONTAINER_multipeermap_iterate (neighbours, &free_neighbour_cb, NULL);
  8911. if (NULL != peerstore)
  8912. {
  8913. GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO);
  8914. peerstore = NULL;
  8915. }
  8916. if (NULL != GST_stats)
  8917. {
  8918. GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
  8919. GST_stats = NULL;
  8920. }
  8921. if (NULL != GST_my_private_key)
  8922. {
  8923. GNUNET_free (GST_my_private_key);
  8924. GST_my_private_key = NULL;
  8925. }
  8926. GNUNET_CONTAINER_multipeermap_iterate (ack_cummulators,
  8927. &free_ack_cummulator_cb,
  8928. NULL);
  8929. GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators);
  8930. ack_cummulators = NULL;
  8931. GNUNET_CONTAINER_multiuuidmap_iterate (pending_acks,
  8932. &free_pending_ack_cb,
  8933. NULL);
  8934. GNUNET_CONTAINER_multiuuidmap_destroy (pending_acks);
  8935. pending_acks = NULL;
  8936. GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (neighbours));
  8937. GNUNET_CONTAINER_multipeermap_destroy (neighbours);
  8938. neighbours = NULL;
  8939. GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (links));
  8940. GNUNET_CONTAINER_multipeermap_destroy (links);
  8941. links = NULL;
  8942. GNUNET_CONTAINER_multipeermap_iterate (backtalkers,
  8943. &free_backtalker_cb,
  8944. NULL);
  8945. GNUNET_CONTAINER_multipeermap_destroy (backtalkers);
  8946. backtalkers = NULL;
  8947. GNUNET_CONTAINER_multipeermap_iterate (validation_map,
  8948. &free_validation_state_cb,
  8949. NULL);
  8950. GNUNET_CONTAINER_multipeermap_destroy (validation_map);
  8951. validation_map = NULL;
  8952. while (NULL != ir_head)
  8953. free_incoming_request (ir_head);
  8954. GNUNET_assert (0 == ir_total);
  8955. while (NULL != (lle = lle_head))
  8956. {
  8957. GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle);
  8958. GNUNET_free (lle);
  8959. }
  8960. GNUNET_CONTAINER_multishortmap_destroy (dvlearn_map);
  8961. dvlearn_map = NULL;
  8962. GNUNET_CONTAINER_heap_destroy (validation_heap);
  8963. validation_heap = NULL;
  8964. GNUNET_CONTAINER_multipeermap_iterate (dv_routes, &free_dv_routes_cb, NULL);
  8965. GNUNET_CONTAINER_multipeermap_destroy (dv_routes);
  8966. dv_routes = NULL;
  8967. }
  8968. /**
  8969. * Initiate transport service.
  8970. *
  8971. * @param cls closure
  8972. * @param c configuration to use
  8973. * @param service the initialized service
  8974. */
  8975. static void
  8976. run (void *cls,
  8977. const struct GNUNET_CONFIGURATION_Handle *c,
  8978. struct GNUNET_SERVICE_Handle *service)
  8979. {
  8980. (void) cls;
  8981. (void) service;
  8982. /* setup globals */
  8983. hello_mono_time = GNUNET_TIME_absolute_get_monotonic (c);
  8984. GST_cfg = c;
  8985. backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
  8986. pending_acks = GNUNET_CONTAINER_multiuuidmap_create (32768, GNUNET_YES);
  8987. ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES);
  8988. neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
  8989. links = GNUNET_CONTAINER_multipeermap_create (512, GNUNET_YES);
  8990. dv_routes = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
  8991. dvlearn_map = GNUNET_CONTAINER_multishortmap_create (2 * MAX_DV_LEARN_PENDING,
  8992. GNUNET_YES);
  8993. validation_map = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
  8994. validation_heap =
  8995. GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
  8996. GST_my_private_key =
  8997. GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
  8998. if (NULL == GST_my_private_key)
  8999. {
  9000. GNUNET_log (
  9001. GNUNET_ERROR_TYPE_ERROR,
  9002. _ (
  9003. "Transport service is lacking key configuration settings. Exiting.\n"));
  9004. GNUNET_SCHEDULER_shutdown ();
  9005. return;
  9006. }
  9007. GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
  9008. &GST_my_identity.public_key);
  9009. GNUNET_log (GNUNET_ERROR_TYPE_INFO,
  9010. "My identity is `%s'\n",
  9011. GNUNET_i2s_full (&GST_my_identity));
  9012. GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
  9013. GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
  9014. peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
  9015. if (NULL == peerstore)
  9016. {
  9017. GNUNET_break (0);
  9018. GNUNET_SCHEDULER_shutdown ();
  9019. return;
  9020. }
  9021. }
  9022. /**
  9023. * Define "main" method using service macro.
  9024. */
  9025. GNUNET_SERVICE_MAIN (
  9026. "transport",
  9027. GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN,
  9028. &run,
  9029. &client_connect_cb,
  9030. &client_disconnect_cb,
  9031. NULL,
  9032. /* communication with applications */
  9033. GNUNET_MQ_hd_fixed_size (suggest,
  9034. GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST,
  9035. struct ExpressPreferenceMessage,
  9036. NULL),
  9037. GNUNET_MQ_hd_fixed_size (suggest_cancel,
  9038. GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
  9039. struct ExpressPreferenceMessage,
  9040. NULL),
  9041. GNUNET_MQ_hd_var_size (request_hello_validation,
  9042. GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
  9043. struct RequestHelloValidationMessage,
  9044. NULL),
  9045. /* communication with core */
  9046. GNUNET_MQ_hd_fixed_size (client_start,
  9047. GNUNET_MESSAGE_TYPE_TRANSPORT_START,
  9048. struct StartMessage,
  9049. NULL),
  9050. GNUNET_MQ_hd_var_size (client_send,
  9051. GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
  9052. struct OutboundMessage,
  9053. NULL),
  9054. GNUNET_MQ_hd_fixed_size (client_recv_ok,
  9055. GNUNET_MESSAGE_TYPE_TRANSPORT_RECV_OK,
  9056. struct RecvOkMessage,
  9057. NULL),
  9058. /* communication with communicators */
  9059. GNUNET_MQ_hd_var_size (communicator_available,
  9060. GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
  9061. struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
  9062. NULL),
  9063. GNUNET_MQ_hd_var_size (communicator_backchannel,
  9064. GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL,
  9065. struct GNUNET_TRANSPORT_CommunicatorBackchannel,
  9066. NULL),
  9067. GNUNET_MQ_hd_var_size (add_address,
  9068. GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
  9069. struct GNUNET_TRANSPORT_AddAddressMessage,
  9070. NULL),
  9071. GNUNET_MQ_hd_fixed_size (del_address,
  9072. GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
  9073. struct GNUNET_TRANSPORT_DelAddressMessage,
  9074. NULL),
  9075. GNUNET_MQ_hd_var_size (incoming_msg,
  9076. GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
  9077. struct GNUNET_TRANSPORT_IncomingMessage,
  9078. NULL),
  9079. GNUNET_MQ_hd_fixed_size (queue_create_ok,
  9080. GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK,
  9081. struct GNUNET_TRANSPORT_CreateQueueResponse,
  9082. NULL),
  9083. GNUNET_MQ_hd_fixed_size (queue_create_fail,
  9084. GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL,
  9085. struct GNUNET_TRANSPORT_CreateQueueResponse,
  9086. NULL),
  9087. GNUNET_MQ_hd_var_size (add_queue_message,
  9088. GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
  9089. struct GNUNET_TRANSPORT_AddQueueMessage,
  9090. NULL),
  9091. GNUNET_MQ_hd_fixed_size (del_queue_message,
  9092. GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
  9093. struct GNUNET_TRANSPORT_DelQueueMessage,
  9094. NULL),
  9095. GNUNET_MQ_hd_fixed_size (send_message_ack,
  9096. GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
  9097. struct GNUNET_TRANSPORT_SendMessageToAck,
  9098. NULL),
  9099. /* communication with monitors */
  9100. GNUNET_MQ_hd_fixed_size (monitor_start,
  9101. GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START,
  9102. struct GNUNET_TRANSPORT_MonitorStart,
  9103. NULL),
  9104. GNUNET_MQ_handler_end ());
  9105. /* end of file gnunet-service-transport.c */