tport.c 121 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@CFILE tport.c Transport interface implementation.
  25. *
  26. * See tport.docs for more detailed description of tport interface.
  27. *
  28. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  29. * @author Ismo Puustinen <Ismo.H.Puustinen@nokia.com>
  30. * @author Tat Chan <Tat.Chan@nokia.com>
  31. * @author Kai Vehmanen <kai.vehmanen@nokia.com>
  32. * @author Martti Mela <Martti.Mela@nokia.com>
  33. *
  34. * @date Created: Thu Jul 20 12:54:32 2000 ppessi
  35. */
  36. #include "config.h"
  37. #include <sofia-sip/su_string.h>
  38. #include <sofia-sip/su.h>
  39. #include <sofia-sip/su_errno.h>
  40. #include <sofia-sip/su_alloc.h>
  41. #include <sofia-sip/su_tagarg.h>
  42. #include <sofia-sip/su_localinfo.h>
  43. typedef struct tport_nat_s tport_nat_t;
  44. #define SU_WAKEUP_ARG_T struct tport_s
  45. #define SU_TIMER_ARG_T struct tport_s
  46. #define SU_MSG_ARG_T union tport_su_msg_arg
  47. #include <sofia-sip/su_wait.h>
  48. #include <sofia-sip/msg.h>
  49. #include <sofia-sip/msg_addr.h>
  50. #include <sofia-sip/hostdomain.h>
  51. #include <stdlib.h>
  52. #include <time.h>
  53. #include <assert.h>
  54. #include <errno.h>
  55. #include <limits.h>
  56. #ifndef IPPROTO_SCTP
  57. #define IPPROTO_SCTP (132)
  58. #endif
  59. #include "sofia-sip/tport.h"
  60. #include "sofia-sip/su_uniqueid.h"
  61. #include <sofia-sip/rbtree.h>
  62. #include "tport_internal.h"
  63. #if HAVE_FUNC
  64. #elif HAVE_FUNCTION
  65. #define __func__ __FUNCTION__
  66. #else
  67. static char const __func__[] = "tport";
  68. #endif
  69. #define STACK_RECV(tp, msg, now) \
  70. (tp)->tp_master->mr_tpac->tpac_recv((tp)->tp_master->mr_stack, (tp), \
  71. (msg), (tp)->tp_magic, (now))
  72. #define STACK_ERROR(tp, errcode, dstname) \
  73. (tp)->tp_master->mr_tpac->tpac_error((tp)->tp_master->mr_stack, (tp), \
  74. (errcode), (dstname))
  75. #define STACK_ADDRESS(tp) \
  76. (tp)->tp_master->mr_tpac->tpac_address((tp)->tp_master->mr_stack, (tp))
  77. #define TP_STACK tp_master->mr_stack
  78. /* Define macros for rbtree implementation */
  79. #define TP_LEFT(tp) ((tp)->tp_left)
  80. #define TP_RIGHT(tp) ((tp)->tp_right)
  81. #define TP_PARENT(tp) ((tp)->tp_dad)
  82. #define TP_SET_RED(tp) ((tp)->tp_black = 0)
  83. #define TP_SET_BLACK(tp) ((tp)->tp_black = 1)
  84. #define TP_IS_RED(tp) ((tp) && (tp)->tp_black == 0)
  85. #define TP_IS_BLACK(tp) (!(tp) || (tp)->tp_black == 1)
  86. #define TP_COPY_COLOR(dst, src) ((dst)->tp_black = (src)->tp_black)
  87. #define TP_INSERT(tp) ((void)0)
  88. #define TP_REMOVE(tp) ((tp)->tp_left = (tp)->tp_right = (tp)->tp_dad = NULL)
  89. su_inline int tp_cmp(tport_t const *a, tport_t const *b)
  90. {
  91. if (a == b)
  92. return 0;
  93. if (a->tp_addrlen != b->tp_addrlen)
  94. return (int)(a->tp_addrlen - b->tp_addrlen);
  95. return memcmp(a->tp_addr, b->tp_addr, a->tp_addrlen);
  96. }
  97. #ifdef __clang__
  98. #pragma clang diagnostic push
  99. #pragma clang diagnostic ignored "-Wunused-function"
  100. #endif
  101. RBTREE_PROTOS(su_inline, tprb, tport_t);
  102. RBTREE_BODIES(su_inline, tprb, tport_t,
  103. TP_LEFT, TP_RIGHT, TP_PARENT,
  104. TP_IS_RED, TP_SET_RED, TP_IS_BLACK, TP_SET_BLACK, TP_COPY_COLOR,
  105. tp_cmp, TP_INSERT, TP_REMOVE);
  106. #ifdef __clang__
  107. #pragma clang diagnostic pop
  108. #endif
  109. static void tplist_insert(tport_t **list, tport_t *tp)
  110. {
  111. if (*list == NULL)
  112. *list = tp;
  113. else
  114. tp->tp_right = *list, (*list)->tp_left = tp, *list = tp;
  115. for (tp = *list; tp; tp = tp->tp_right) {
  116. assert(tp->tp_left == NULL || tp == tp->tp_left->tp_right);
  117. assert(tp->tp_right == NULL || tp == tp->tp_right->tp_left);
  118. }
  119. }
  120. static void tplist_remove(tport_t **list, tport_t *tp)
  121. {
  122. if (*list == tp) {
  123. *list = tp->tp_right; assert(tp->tp_left == NULL);
  124. }
  125. else if (tp->tp_left) {
  126. tp->tp_left->tp_right = tp->tp_right;
  127. }
  128. if (tp->tp_right) {
  129. tp->tp_right->tp_left = tp->tp_left;
  130. }
  131. TP_REMOVE(tp);
  132. }
  133. enum {
  134. /** Default per-thread read queue length */
  135. THRP_PENDING = 8
  136. };
  137. struct tport_pending_s {
  138. /* tport_pending_t *p_left, *p_right, *p_parent; */
  139. void *p_client;
  140. tport_pending_error_f *p_callback;
  141. msg_t *p_msg;
  142. unsigned short p_reported;
  143. unsigned short p_on_success;
  144. };
  145. /** Return true if transport is master. */
  146. int tport_is_master(tport_t const *self)
  147. {
  148. return
  149. self &&
  150. self->tp_master->mr_master == self;
  151. }
  152. /** Return true if transport is primary. */
  153. int tport_is_primary(tport_t const *self)
  154. {
  155. return
  156. self &&
  157. self->tp_pri->pri_primary == self;
  158. }
  159. /** Return true if transport is secondary. */
  160. int tport_is_secondary(tport_t const *self)
  161. {
  162. return
  163. self &&
  164. self->tp_master->mr_master != self &&
  165. self->tp_pri->pri_primary != self;
  166. }
  167. /** Test if transport has been registered to su_root_t */
  168. int tport_is_registered(tport_t const *self)
  169. {
  170. return self && self->tp_index != 0;
  171. }
  172. /** Test if transport is stream. */
  173. int tport_is_stream(tport_t const *self)
  174. {
  175. return self && !self->tp_pre_framed && self->tp_addrinfo->ai_socktype == SOCK_STREAM;
  176. }
  177. /** Test if transport is dgram. */
  178. int tport_is_dgram(tport_t const *self)
  179. {
  180. return self && self->tp_addrinfo->ai_socktype == SOCK_DGRAM;
  181. }
  182. /** Test if transport is udp. */
  183. int tport_is_udp(tport_t const *self)
  184. {
  185. return self && self->tp_addrinfo->ai_protocol == IPPROTO_UDP;
  186. }
  187. /** Test if transport is tcp. */
  188. int tport_is_tcp(tport_t const *self)
  189. {
  190. return self && self->tp_addrinfo->ai_protocol == IPPROTO_TCP;
  191. }
  192. /** Return 1 if transport is reliable, 0 otherwise.
  193. *
  194. * (Note that this is part of external API).
  195. */
  196. int tport_is_reliable(tport_t const *self)
  197. {
  198. return self != NULL &&
  199. (self->tp_addrinfo->ai_socktype == SOCK_STREAM ||
  200. self->tp_addrinfo->ai_socktype == SOCK_SEQPACKET);
  201. }
  202. /** Return 0 if self is local, nonzero otherwise.
  203. *
  204. * The return valu is the tport_via enum.
  205. *
  206. * @sa TPTAG_PUBLIC(), enum tport_via.
  207. */
  208. int tport_is_public(tport_t const *self)
  209. {
  210. return self && self->tp_pri->pri_public;
  211. }
  212. /** Return true if transport supports IPv4 */
  213. int tport_has_ip4(tport_t const *self)
  214. {
  215. return self &&
  216. (self->tp_addrinfo->ai_family == 0 ||
  217. self->tp_addrinfo->ai_family == AF_INET);
  218. }
  219. #if SU_HAVE_IN6
  220. /** Return true if transport supports IPv6 */
  221. int tport_has_ip6(tport_t const *self)
  222. {
  223. return self &&
  224. (self->tp_addrinfo->ai_family == 0 ||
  225. self->tp_addrinfo->ai_family == AF_INET6);
  226. }
  227. #endif
  228. /** Return true if transport supports TLS. */
  229. int tport_has_tls(tport_t const *self)
  230. {
  231. return self && self->tp_pri->pri_has_tls;
  232. }
  233. /** Return true if transport certificate verified successfully */
  234. int tport_is_verified(tport_t const *self)
  235. {
  236. return tport_has_tls(self) && self->tp_is_connected && self->tp_verified;
  237. }
  238. /** Return true if transport is being updated. */
  239. int tport_is_updating(tport_t const *self)
  240. {
  241. tport_primary_t *pri;
  242. if (tport_is_master(self)) {
  243. for (pri = self->tp_master->mr_primaries; pri; pri = pri->pri_next)
  244. if (pri->pri_updating)
  245. return 1;
  246. }
  247. else if (tport_is_primary(self)) {
  248. return self->tp_pri->pri_updating;
  249. }
  250. return 0;
  251. }
  252. /** Test if transport has been closed.
  253. *
  254. * @since New in @VERSION_1_12_4
  255. */
  256. inline int tport_is_closed(tport_t const *self)
  257. {
  258. return self->tp_closed;
  259. }
  260. /** Test if transport has been shut down.
  261. *
  262. * @since New in @VERSION_1_12_4
  263. */
  264. inline int tport_is_shutdown(tport_t const *self)
  265. {
  266. return self->tp_closed || self->tp_send_close || self->tp_recv_close;
  267. }
  268. /** Test if transport connection has been established. @NEW_1_12_5. */
  269. int tport_is_connected(tport_t const *self)
  270. {
  271. return self->tp_is_connected;
  272. }
  273. /** Test if transport can be used to send message. @NEW_1_12_7. */
  274. int tport_is_clear_to_send(tport_t const *self)
  275. {
  276. return
  277. tport_is_master(self) ||
  278. tport_is_primary(self) ||
  279. (tport_is_secondary(self) &&
  280. tport_is_registered(self) &&
  281. self->tp_reusable &&
  282. !self->tp_closed &&
  283. !self->tp_send_close);
  284. }
  285. /** Return true if transport has message in send queue. @NEW_1_12_7. */
  286. int tport_has_queued(tport_t const *self)
  287. {
  288. return self && self->tp_queue && self->tp_queue[self->tp_qhead];
  289. }
  290. /** MTU for transport */
  291. su_inline unsigned tport_mtu(tport_t const *self)
  292. {
  293. return self->tp_params->tpp_mtu;
  294. }
  295. /** Set IP TOS for socket */
  296. void tport_set_tos(su_socket_t socket, su_addrinfo_t *ai, int tos)
  297. {
  298. if (tos >= 0 &&
  299. ai->ai_family == AF_INET &&
  300. setsockopt(socket, IPPROTO_IP, IP_TOS, (const void*)&tos, sizeof(tos)) < 0) {
  301. SU_DEBUG_3(("tport: setsockopt(IP_TOS): %s\n",
  302. su_strerror(su_errno())));
  303. }
  304. }
  305. static
  306. tport_t *tport_connect(tport_primary_t *pri, su_addrinfo_t *ai,
  307. tp_name_t const *tpn);
  308. static int bind6only_check(tport_master_t *mr);
  309. static
  310. int tport_server_addrinfo(tport_master_t *mr,
  311. char const *canon,
  312. int family,
  313. char const *host,
  314. char const *service,
  315. char const *protocol,
  316. char const * const transports[],
  317. su_addrinfo_t **res);
  318. static int tport_get_local_addrinfo(tport_master_t *mr,
  319. char const *port,
  320. su_addrinfo_t const *hints,
  321. su_addrinfo_t **return_ai);
  322. int tport_getaddrinfo(char const *node, char const *service,
  323. su_addrinfo_t const *hints,
  324. su_addrinfo_t **res);
  325. static void tport_freeaddrinfo(su_addrinfo_t *ai);
  326. static
  327. int tport_addrinfo_copy(su_addrinfo_t *dst, void *addr, socklen_t addrlen,
  328. su_addrinfo_t const *src);
  329. static int
  330. tport_bind_client(tport_master_t *self, tp_name_t const *tpn,
  331. char const * const transports[], enum tport_via public,
  332. tagi_t *tags),
  333. tport_bind_server(tport_master_t *, tp_name_t const *tpn,
  334. char const * const transports[], enum tport_via public,
  335. tagi_t *tags),
  336. tport_wakeup_pri(su_root_magic_t *m, su_wait_t *w, tport_t *self),
  337. tport_base_wakeup(tport_t *self, int events),
  338. tport_connected(su_root_magic_t *m, su_wait_t *w, tport_t *self),
  339. tport_resolve(tport_t *self, msg_t *msg, tp_name_t const *tpn),
  340. tport_send_error(tport_t *, msg_t *, tp_name_t const *, char const *who),
  341. tport_send_fatal(tport_t *, msg_t *, tp_name_t const *, char const *who),
  342. tport_queue(tport_t *self, msg_t *msg),
  343. tport_queue_rest(tport_t *self, msg_t *msg, msg_iovec_t iov[], size_t iovused),
  344. tport_pending_error(tport_t *self, su_sockaddr_t const *dst, int error),
  345. tport_pending_errmsg(tport_t *self, msg_t *msg, int error);
  346. static ssize_t tport_vsend(tport_t *self, msg_t *msg, tp_name_t const *tpn,
  347. msg_iovec_t iov[], size_t iovused,
  348. struct sigcomp_compartment *cc);
  349. tport_t *tport_by_addrinfo(tport_primary_t const *pri,
  350. su_addrinfo_t const *ai,
  351. tp_name_t const *tpn);
  352. void tport_peer_address(tport_t *self, msg_t *msg);
  353. static void tport_parse(tport_t *self, int complete, su_time_t now);
  354. static tport_primary_t *tport_alloc_primary(tport_master_t *mr,
  355. tport_vtable_t const *vtable,
  356. tp_name_t tpn[1],
  357. su_addrinfo_t *ai,
  358. tagi_t const *tags,
  359. char const **return_culprit);
  360. static tport_primary_t *tport_listen(tport_master_t *mr,
  361. tport_vtable_t const *vtable,
  362. tp_name_t tpn[1],
  363. su_addrinfo_t *ai,
  364. tagi_t *tags);
  365. static void tport_zap_primary(tport_primary_t *);
  366. static char *localipname(int pf, char *buf, size_t bufsiz);
  367. static int getprotohints(su_addrinfo_t *hints,
  368. char const *proto, int flags);
  369. /* Stack class used when transports are being destroyed */
  370. static
  371. void tport_destroy_recv(tp_stack_t *stack, tport_t *tp,
  372. msg_t *msg, tp_magic_t *magic,
  373. su_time_t received)
  374. {
  375. msg_destroy(msg);
  376. }
  377. static
  378. void tport_destroy_error(tp_stack_t *stack, tport_t *tp,
  379. int errcode, char const *remote)
  380. {
  381. }
  382. static
  383. msg_t *tport_destroy_alloc(tp_stack_t *stack, int flags,
  384. char const data[], usize_t len,
  385. tport_t const *tp,
  386. tp_client_t *tpc)
  387. {
  388. return NULL;
  389. }
  390. /** Name for "any" transport. @internal */
  391. static char const tpn_any[] = "*";
  392. /** Create the master transport.
  393. *
  394. * Master transport object is used to bind the protocol using transport with
  395. * actual transport objects corresponding to TCP, UDP, etc.
  396. *
  397. * @sa tport_tbind()
  398. *
  399. * @TAGS
  400. * TPTAG_LOG(), TPTAG_DUMP(), tags used with tport_set_params(), especially
  401. * TPTAG_QUEUESIZE().
  402. */
  403. tport_t *tport_tcreate(tp_stack_t *stack,
  404. tp_stack_class_t const *tpac,
  405. su_root_t *root,
  406. tag_type_t tag, tag_value_t value, ...)
  407. {
  408. tport_master_t *mr;
  409. tp_name_t *tpn;
  410. tport_params_t *tpp;
  411. ta_list ta;
  412. if (!stack || !tpac || !root) {
  413. su_seterrno(EINVAL);
  414. return NULL;
  415. }
  416. mr = su_home_clone(NULL, sizeof *mr);
  417. if (!mr)
  418. return NULL;
  419. SU_DEBUG_7(("%s(): %p\n", "tport_create", (void *)mr));
  420. mr->mr_stack = stack;
  421. mr->mr_tpac = tpac;
  422. mr->mr_root = root;
  423. mr->mr_master->tp_master = mr;
  424. mr->mr_master->tp_params = tpp = mr->mr_params;
  425. mr->mr_master->tp_reusable = 1;
  426. tpp->tpp_mtu = UINT_MAX;
  427. tpp->tpp_thrprqsize = THRP_PENDING;
  428. tpp->tpp_qsize = TPORT_QUEUESIZE;
  429. tpp->tpp_sdwn_error = 1;
  430. tpp->tpp_idle = UINT_MAX;
  431. tpp->tpp_timeout = UINT_MAX;
  432. tpp->tpp_sigcomp_lifetime = UINT_MAX;
  433. tpp->tpp_socket_keepalive = 30;
  434. tpp->tpp_keepalive = 0;
  435. tpp->tpp_pingpong = 0;
  436. tpp->tpp_pong2ping = 0;
  437. tpp->tpp_stun_server = 1;
  438. tpp->tpp_tos = -1; /* set invalid, valid values are 0-255 */
  439. tpn = mr->mr_master->tp_name;
  440. tpn->tpn_proto = "*";
  441. tpn->tpn_host = "*";
  442. tpn->tpn_canon = "*";
  443. tpn->tpn_port = "*";
  444. ta_start(ta, tag, value);
  445. tport_set_params(mr->mr_master, ta_tags(ta));
  446. #if HAVE_SOFIA_STUN
  447. tport_init_stun_server(mr, ta_args(ta));
  448. #endif
  449. ta_end(ta);
  450. return mr->mr_master;
  451. }
  452. /** Destroy the master transport. */
  453. void tport_destroy(tport_t *self)
  454. {
  455. tport_master_t *mr;
  456. static tp_stack_class_t tport_destroy_tpac[1] =
  457. {{
  458. sizeof tport_destroy_tpac,
  459. /* tpac_recv */ tport_destroy_recv,
  460. /* tpac_error */ tport_destroy_error,
  461. /* tpac_alloc */ tport_destroy_alloc,
  462. /* tpac_address */ NULL
  463. }};
  464. SU_DEBUG_7(("%s(%p)\n", __func__, (void *)self));
  465. if (self == NULL)
  466. return;
  467. assert(tport_is_master(self));
  468. if (!tport_is_master(self))
  469. return;
  470. mr = (tport_master_t *)self;
  471. mr->mr_tpac = tport_destroy_tpac;
  472. while (mr->mr_primaries)
  473. tport_zap_primary(mr->mr_primaries);
  474. #if HAVE_SOFIA_STUN
  475. tport_deinit_stun_server(mr);
  476. #endif
  477. if (mr->mr_dump_file)
  478. fclose(mr->mr_dump_file), mr->mr_dump_file = NULL;
  479. if (mr->mr_timer)
  480. su_timer_destroy(mr->mr_timer), mr->mr_timer = NULL;
  481. if (mr->mr_capt_src_addr) {
  482. su_freeaddrinfo(mr->mr_capt_src_addr);
  483. mr->mr_capt_src_addr = NULL;
  484. }
  485. su_home_zap(mr->mr_home);
  486. }
  487. /** Allocate a primary transport */
  488. static
  489. tport_primary_t *tport_alloc_primary(tport_master_t *mr,
  490. tport_vtable_t const *vtable,
  491. tp_name_t tpn[1],
  492. su_addrinfo_t *ai,
  493. tagi_t const *tags,
  494. char const **return_culprit)
  495. {
  496. tport_primary_t *pri, **next;
  497. tport_t *tp;
  498. int save_errno;
  499. for (next = &mr->mr_primaries; *next; next = &(*next)->pri_next)
  500. ;
  501. assert(vtable->vtp_pri_size >= sizeof *pri);
  502. if ((pri = su_home_clone(mr->mr_home, vtable->vtp_pri_size))) {
  503. tport_t *tp = pri->pri_primary;
  504. pri->pri_vtable = vtable;
  505. pri->pri_public = vtable->vtp_public;
  506. tp->tp_master = mr;
  507. tp->tp_pri = pri;
  508. tp->tp_socket = INVALID_SOCKET;
  509. tp->tp_magic = mr->mr_master->tp_magic;
  510. tp->tp_params = pri->pri_params;
  511. memcpy(tp->tp_params, mr->mr_params, sizeof (*tp->tp_params));
  512. tp->tp_reusable = mr->mr_master->tp_reusable;
  513. if (!pri->pri_public)
  514. tp->tp_addrinfo->ai_addr = &tp->tp_addr->su_sa;
  515. SU_DEBUG_5(("%s(%p): new primary tport %p\n", __func__, (void *)mr,
  516. (void *)pri));
  517. }
  518. *next = pri;
  519. tp = pri->pri_primary;
  520. if (!tp)
  521. *return_culprit = "alloc";
  522. else if (tport_set_params(tp, TAG_NEXT(tags)) < 0)
  523. *return_culprit = "tport_set_params";
  524. else if (vtable->vtp_init_primary &&
  525. vtable->vtp_init_primary(pri, tpn, ai, tags, return_culprit) < 0)
  526. ;
  527. else if (tport_setname(tp, vtable->vtp_name, ai, tpn->tpn_canon) == -1)
  528. *return_culprit = "tport_setname";
  529. else if (tpn->tpn_ident &&
  530. !(tp->tp_name->tpn_ident = su_strdup(tp->tp_home, tpn->tpn_ident)))
  531. *return_culprit = "alloc ident";
  532. else
  533. return pri; /* Success */
  534. save_errno = su_errno();
  535. tport_zap_primary(pri);
  536. su_seterrno(save_errno);
  537. return NULL;
  538. }
  539. /** Destroy a primary transport and its secondary transports. @internal */
  540. static
  541. void tport_zap_primary(tport_primary_t *pri)
  542. {
  543. tport_primary_t **prip;
  544. if (pri == NULL)
  545. return;
  546. assert(tport_is_primary(pri->pri_primary));
  547. if (pri->pri_vtable->vtp_deinit_primary)
  548. pri->pri_vtable->vtp_deinit_primary(pri);
  549. while (pri->pri_open)
  550. tport_zap_secondary(pri->pri_open);
  551. while (pri->pri_closed)
  552. tport_zap_secondary(pri->pri_closed);
  553. /* We have just a single-linked list for primary transports */
  554. for (prip = &pri->pri_master->mr_primaries;
  555. *prip != pri;
  556. prip = &(*prip)->pri_next)
  557. assert(*prip);
  558. *prip = pri->pri_next;
  559. tport_zap_secondary((tport_t *)pri);
  560. }
  561. /**Create a primary transport object with socket.
  562. *
  563. * Creates a primary transport object with a server socket, and then
  564. * registers the socket with suitable events to the root.
  565. *
  566. * @param dad parent (master or primary) transport object
  567. * @param ai pointer to addrinfo structure
  568. * @param canon canonical name of node
  569. * @param protoname name of the protocol
  570. */
  571. static
  572. tport_primary_t *tport_listen(tport_master_t *mr,
  573. tport_vtable_t const *vtable,
  574. tp_name_t tpn[1],
  575. su_addrinfo_t *ai,
  576. tagi_t *tags)
  577. {
  578. tport_primary_t *pri = NULL;
  579. int err;
  580. int errlevel = 3;
  581. char buf[TPORT_HOSTPORTSIZE];
  582. char const *protoname = vtable->vtp_name;
  583. char const *culprit = "unknown";
  584. su_sockaddr_t *su = (void *)ai->ai_addr;
  585. /* Log an error, return error */
  586. #define TPORT_LISTEN_ERROR(errno, what) \
  587. ((void)(err = errno, \
  588. ((err == EADDRINUSE || err == EAFNOSUPPORT || \
  589. err == ESOCKTNOSUPPORT || err == EPROTONOSUPPORT || \
  590. err == ENOPROTOOPT ? 7 : 3) < SU_LOG_LEVEL ? \
  591. su_llog(tport_log, errlevel, \
  592. "%s(%p): %s(pf=%d %s/%s): %s\n", \
  593. __func__, pri ? (void *)pri : (void *)mr, what, \
  594. ai->ai_family, protoname, \
  595. tport_hostport(buf, sizeof(buf), su, 2), \
  596. su_strerror(err)) : (void)0), \
  597. tport_zap_primary(pri), \
  598. su_seterrno(err)), \
  599. (void *)NULL)
  600. /* Create a primary transport object for another transport. */
  601. pri = tport_alloc_primary(mr, vtable, tpn, ai, tags, &culprit);
  602. if (pri == NULL)
  603. return TPORT_LISTEN_ERROR(su_errno(), culprit);
  604. if (pri->pri_primary->tp_socket != INVALID_SOCKET) {
  605. int index = 0;
  606. tport_t *tp = pri->pri_primary;
  607. su_wait_t wait[1] = { SU_WAIT_INIT };
  608. if (su_wait_create(wait, tp->tp_socket, tp->tp_events) == -1)
  609. return TPORT_LISTEN_ERROR(su_errno(), "su_wait_create");
  610. /* Register receiving or accepting function with events specified above */
  611. index = su_root_register(mr->mr_root, wait, tport_wakeup_pri, tp, 0);
  612. if (index == -1) {
  613. su_wait_destroy(wait);
  614. return TPORT_LISTEN_ERROR(su_errno(), "su_root_register");
  615. }
  616. tp->tp_index = index;
  617. }
  618. pri->pri_primary->tp_has_connection = 0;
  619. SU_DEBUG_5(("%s(%p): %s " TPN_FORMAT "\n",
  620. __func__, (void *)pri, "listening at",
  621. TPN_ARGS(pri->pri_primary->tp_name)));
  622. return pri;
  623. }
  624. int tport_bind_socket(int socket,
  625. su_addrinfo_t *ai,
  626. char const **return_culprit)
  627. {
  628. su_sockaddr_t *su = (su_sockaddr_t *)ai->ai_addr;
  629. socklen_t sulen = (socklen_t)(ai->ai_addrlen);
  630. if (bind(socket, ai->ai_addr, sulen) == -1) {
  631. return *return_culprit = "bind", -1;
  632. }
  633. if (getsockname(socket, &su->su_sa, &sulen) == SOCKET_ERROR) {
  634. return *return_culprit = "getsockname", -1;
  635. }
  636. ai->ai_addrlen = sulen;
  637. #if defined (__linux__) && defined (SU_HAVE_IN6)
  638. if (ai->ai_family == AF_INET6) {
  639. if (!SU_SOCKADDR_INADDR_ANY(su) &&
  640. (IN6_IS_ADDR_V4MAPPED(&su->su_sin6.sin6_addr) ||
  641. IN6_IS_ADDR_V4COMPAT(&su->su_sin6.sin6_addr))) {
  642. su_sockaddr_t su0[1];
  643. memcpy(su0, su, sizeof su0);
  644. memset(su, 0, ai->ai_addrlen = sizeof su->su_sin);
  645. su->su_family = ai->ai_family = AF_INET;
  646. su->su_port = su0->su_port;
  647. #ifndef IN6_V4MAPPED_TO_INADDR
  648. #define IN6_V4MAPPED_TO_INADDR(in6, in4) \
  649. memcpy((in4), 12 + (uint8_t *)(in6), sizeof(struct in_addr))
  650. #endif
  651. IN6_V4MAPPED_TO_INADDR(&su0->su_sin6.sin6_addr, &su->su_sin.sin_addr);
  652. }
  653. }
  654. #endif
  655. return 0;
  656. }
  657. /** Indicate stack that a transport has been updated */
  658. void tport_has_been_updated(tport_t *self)
  659. {
  660. self->tp_pri->pri_updating = 0;
  661. if (self->tp_master->mr_tpac->tpac_address)
  662. self->tp_master->mr_tpac->tpac_address(self->tp_master->mr_stack, self);
  663. }
  664. static
  665. int tport_set_events(tport_t *self, int set, int clear)
  666. {
  667. int events;
  668. if (self == NULL)
  669. return -1;
  670. events = (self->tp_events | set) & ~clear;
  671. self->tp_events = events;
  672. if (self->tp_pri->pri_vtable->vtp_set_events)
  673. return self->tp_pri->pri_vtable->vtp_set_events(self);
  674. SU_DEBUG_7(("tport_set_events(%p): events%s%s%s\n", (void *)self,
  675. (events & SU_WAIT_IN) ? " IN" : "",
  676. (events & SU_WAIT_OUT) ? " OUT" : "",
  677. SU_WAIT_CONNECT != SU_WAIT_OUT &&
  678. (events & SU_WAIT_CONNECT) ? " CONNECT" : ""));
  679. return
  680. su_root_eventmask(self->tp_master->mr_root,
  681. self->tp_index,
  682. self->tp_socket,
  683. self->tp_events = events);
  684. }
  685. /**Allocate a secondary transport. @internal
  686. *
  687. * Create a secondary transport object. The new transport initally shares
  688. * parameters structure with the original transport.
  689. *
  690. * @param pri primary transport
  691. * @param socket socket for transport
  692. * @parma accepted true if the socket was accepted from server socket
  693. *
  694. * @return
  695. * Pointer to the newly created transport, or NULL upon an error.
  696. *
  697. * @note The socket is always closed upon error.
  698. */
  699. tport_t *tport_alloc_secondary(tport_primary_t *pri,
  700. int socket,
  701. int accepted,
  702. char const **return_reason)
  703. {
  704. tport_master_t *mr = pri->pri_master;
  705. tport_t *self;
  706. self = su_home_clone(mr->mr_home, pri->pri_vtable->vtp_secondary_size);
  707. if (self) {
  708. SU_DEBUG_7(("%s(%p): new secondary tport %p\n",
  709. __func__, (void *)pri, (void *)self));
  710. self->tp_refs = -1; /* Freshly allocated */
  711. self->tp_master = mr;
  712. self->tp_pri = pri;
  713. self->tp_params = pri->pri_params;
  714. self->tp_accepted = accepted != 0;
  715. self->tp_reusable = pri->pri_primary->tp_reusable;
  716. self->tp_magic = pri->pri_primary->tp_magic;
  717. self->tp_addrinfo->ai_addr = (void *)self->tp_addr;
  718. self->tp_socket = socket;
  719. self->tp_timer = su_timer_create(su_root_task(mr->mr_root), 0);
  720. self->tp_stime = self->tp_ktime = self->tp_rtime = su_now();
  721. if (pri->pri_vtable->vtp_init_secondary &&
  722. pri->pri_vtable->vtp_init_secondary(self, socket, accepted, return_reason) < 0) {
  723. if (pri->pri_vtable->vtp_deinit_secondary) {
  724. pri->pri_vtable->vtp_deinit_secondary(self);
  725. }
  726. su_timer_destroy(self->tp_timer);
  727. su_home_zap(self->tp_home);
  728. return NULL;
  729. }
  730. /* Set IP TOS if it is set in primary */
  731. tport_set_tos(socket,
  732. pri->pri_primary->tp_addrinfo,
  733. pri->pri_params->tpp_tos);
  734. }
  735. else {
  736. *return_reason = "malloc";
  737. }
  738. return self;
  739. }
  740. /** Create a connected transport object with socket.
  741. *
  742. * The function tport_connect() creates a secondary transport with a
  743. * connected socket. It registers the socket with suitable events to the
  744. * root.
  745. *
  746. * @param pri primary transport object
  747. * @param ai pointer to addrinfo structure
  748. * @param tpn canonical name of node
  749. */
  750. static
  751. tport_t *tport_connect(tport_primary_t *pri,
  752. su_addrinfo_t *ai,
  753. tp_name_t const *tpn)
  754. {
  755. tport_t *tp;
  756. if (ai == NULL || ai->ai_addrlen > sizeof (pri->pri_primary->tp_addr))
  757. return NULL;
  758. if (pri->pri_vtable->vtp_connect)
  759. return pri->pri_vtable->vtp_connect(pri, ai, tpn);
  760. tp = tport_base_connect(pri, ai, ai, tpn);
  761. if (tp)
  762. tport_set_secondary_timer(tp);
  763. return tp;
  764. }
  765. /**Create a connected transport object with socket.
  766. *
  767. * The function tport_connect() creates a secondary transport with a
  768. * connected socket. It registers the socket with suitable events to the
  769. * root.
  770. *
  771. * @param pri primary transport object
  772. * @param ai pointer to addrinfo structure describing socket
  773. * @param real_ai pointer to addrinfo structure describing real target
  774. * @param tpn canonical name of node
  775. */
  776. tport_t *tport_base_connect(tport_primary_t *pri,
  777. su_addrinfo_t *ai,
  778. su_addrinfo_t *real_ai,
  779. tp_name_t const *tpn)
  780. {
  781. tport_t *self = NULL;
  782. su_socket_t s, server_socket;
  783. su_wakeup_f wakeup = tport_wakeup;
  784. int events = SU_WAIT_IN | SU_WAIT_ERR;
  785. int err;
  786. unsigned errlevel = 3;
  787. char buf[TPORT_HOSTPORTSIZE];
  788. char const *what;
  789. /* Log an error, return error */
  790. #define TPORT_CONNECT_ERROR(errno, what) \
  791. return \
  792. ((void)(err = errno, \
  793. (SU_LOG_LEVEL >= errlevel ? \
  794. su_llog(tport_log, errlevel, \
  795. "%s(%p): %s(pf=%d %s/%s): %s\n", \
  796. __func__, (void *)pri, #what, ai->ai_family, \
  797. tpn->tpn_proto, \
  798. tport_hostport(buf, sizeof(buf), \
  799. (void *)ai->ai_addr, 2), \
  800. su_strerror(err)) : (void)0), \
  801. tport_zap_secondary(self), \
  802. su_seterrno(err)), \
  803. (void *)NULL)
  804. s = su_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  805. if (s == INVALID_SOCKET)
  806. TPORT_CONNECT_ERROR(su_errno(), "socket");
  807. what = "tport_alloc_secondary";
  808. if ((self = tport_alloc_secondary(pri, s, 0, &what)) == NULL)
  809. TPORT_CONNECT_ERROR(su_errno(), what);
  810. self->tp_conn_orient = 1;
  811. if ((server_socket = pri->pri_primary->tp_socket) != INVALID_SOCKET) {
  812. su_sockaddr_t susa;
  813. socklen_t susalen = sizeof(susa);
  814. /* Bind this socket to same IP address as the primary server socket */
  815. if (getsockname(server_socket, &susa.su_sa, &susalen) < 0) {
  816. SU_DEBUG_3(("%s(%p): getsockname(): %s\n",
  817. __func__, (void *)self, su_strerror(su_errno())));
  818. }
  819. else {
  820. susa.su_port = 0;
  821. if (bind(s, &susa.su_sa, susalen) < 0) {
  822. SU_DEBUG_3(("%s(%p): bind(local-ip): %s\n",
  823. __func__, (void *)self, su_strerror(su_errno())));
  824. }
  825. }
  826. }
  827. /* Set sockname for the tport */
  828. if (tport_setname(self, tpn->tpn_proto, real_ai, tpn->tpn_canon) == -1)
  829. TPORT_CONNECT_ERROR(su_errno(), tport_setname);
  830. /* Try to have a non-blocking connect().
  831. * The tport_register_secondary() below makes the socket non-blocking anyway. */
  832. su_setblocking(s, 0);
  833. if (connect(s, ai->ai_addr, (socklen_t)(ai->ai_addrlen)) == SOCKET_ERROR) {
  834. err = su_errno();
  835. if (!su_is_blocking(err))
  836. TPORT_CONNECT_ERROR(err, connect);
  837. events = SU_WAIT_CONNECT | SU_WAIT_ERR;
  838. wakeup = tport_connected;
  839. what = "connecting";
  840. }
  841. else {
  842. what = "connected";
  843. self->tp_is_connected = 1;
  844. }
  845. if (tport_register_secondary(self, wakeup, events) == -1)
  846. TPORT_CONNECT_ERROR(su_errno(), tport_register_secondary);
  847. if (ai == real_ai) {
  848. SU_DEBUG_5(("%s(%p): %s to " TPN_FORMAT "\n",
  849. __func__, (void *)self, what, TPN_ARGS(self->tp_name)));
  850. }
  851. else {
  852. SU_DEBUG_5(("%s(%p): %s via %s to " TPN_FORMAT "\n",
  853. __func__, (void *)self, what,
  854. tport_hostport(buf, sizeof(buf), (void *)ai->ai_addr, 2),
  855. TPN_ARGS(self->tp_name)));
  856. }
  857. return self;
  858. }
  859. /** Register a new secondary transport. @internal */
  860. int tport_register_secondary(tport_t *self, su_wakeup_f wakeup, int events)
  861. {
  862. int i;
  863. su_root_t *root = tport_is_secondary(self) ? self->tp_master->mr_root : NULL;
  864. su_wait_t wait[1] = { SU_WAIT_INIT };
  865. if (root != NULL
  866. /* Create wait object with appropriate events. */
  867. &&
  868. su_wait_create(wait, self->tp_socket, events) != -1
  869. /* Register socket to root */
  870. &&
  871. (i = su_root_register(root, wait, wakeup, self, 0)) != -1) {
  872. /* Can't be added to list of opened if already closed */
  873. if (tport_is_closed(self)) goto fail;
  874. self->tp_index = i;
  875. self->tp_events = events;
  876. tprb_append(&self->tp_pri->pri_open, self);
  877. return 0;
  878. }
  879. fail:
  880. SU_DEBUG_9(("%s(%p): tport is %s!\n", __func__, (void *)self, (tport_is_closed(self) ? "closed" : "opened")));
  881. su_wait_destroy(wait);
  882. return -1;
  883. }
  884. /** Destroy a secondary transport. @internal */
  885. void tport_zap_secondary(tport_t *self)
  886. {
  887. tport_master_t *mr;
  888. if (self == NULL)
  889. return;
  890. /* Remove from rbtree */
  891. if (!tport_is_closed(self))
  892. tprb_remove(&self->tp_pri->pri_open, self);
  893. else
  894. tplist_remove(&self->tp_pri->pri_closed, self);
  895. if (self->tp_timer)
  896. su_timer_destroy(self->tp_timer), self->tp_timer = NULL;
  897. /* Do not deinit primary as secondary! */
  898. if (tport_is_secondary(self) &&
  899. self->tp_pri->pri_vtable->vtp_deinit_secondary)
  900. self->tp_pri->pri_vtable->vtp_deinit_secondary(self);
  901. if (self->tp_msg) {
  902. msg_destroy(self->tp_msg), self->tp_msg = NULL;
  903. SU_DEBUG_3(("%s(%p): zapped partially received message\n",
  904. __func__, (void *)self));
  905. }
  906. if (tport_has_queued(self)) {
  907. size_t n = 0, i, N = self->tp_params->tpp_qsize;
  908. for (i = self->tp_qhead; self->tp_queue[i]; i = (i + 1) % N) {
  909. msg_destroy(self->tp_queue[i]), self->tp_queue[i] = NULL;
  910. n++;
  911. }
  912. SU_DEBUG_3(("%s(%p): zapped %lu queued messages\n",
  913. __func__, (void *)self, (LU)n));
  914. }
  915. if (self->tp_pused) {
  916. SU_DEBUG_3(("%s(%p): zapped while pending\n",
  917. __func__, (void *)self));
  918. }
  919. mr = self->tp_master;
  920. #if HAVE_SOFIA_STUN
  921. tport_stun_server_remove_socket(self);
  922. #endif
  923. if (self->tp_index)
  924. su_root_deregister(mr->mr_root, self->tp_index);
  925. self->tp_index = 0;
  926. if (self->tp_socket != INVALID_SOCKET)
  927. su_close(self->tp_socket);
  928. self->tp_socket = INVALID_SOCKET;
  929. su_home_zap(self->tp_home);
  930. }
  931. /** Create a new reference to a transport object. */
  932. tport_t *tport_ref(tport_t *tp)
  933. {
  934. if (tp) {
  935. if (tp->tp_refs >= 0)
  936. tp->tp_refs++;
  937. else if (tp->tp_refs == -1)
  938. tp->tp_refs = 1;
  939. }
  940. return tp;
  941. }
  942. /** Destroy reference to a transport object. */
  943. void tport_unref(tport_t *tp)
  944. {
  945. if (tp == NULL || tp->tp_refs <= 0)
  946. return;
  947. if (--tp->tp_refs > 0)
  948. return;
  949. if (!tport_is_secondary(tp))
  950. return;
  951. if (tp->tp_params->tpp_idle == 0)
  952. tport_close(tp);
  953. tport_set_secondary_timer(tp);
  954. }
  955. /** Create a new reference to transport object. */
  956. tport_t *tport_incref(tport_t *tp)
  957. {
  958. return tport_ref(tp);
  959. }
  960. /** Destroy a transport reference. */
  961. void tport_decref(tport_t **ttp)
  962. {
  963. assert(ttp);
  964. if (*ttp) {
  965. tport_unref(*ttp);
  966. *ttp = NULL;
  967. }
  968. }
  969. /** Get transport parameters.
  970. *
  971. * @param self pointer to a transport object
  972. * @param tag,value,... list of tags
  973. *
  974. * @TAGS
  975. * TPTAG_MTU_REF(), TPTAG_QUEUESIZE_REF(), TPTAG_IDLE_REF(),
  976. * TPTAG_TIMEOUT_REF(), TPTAG_KEEPALIVE_REF(), TPTAG_PINGPONG_REF(),
  977. * TPTAG_PONG2PING_REF(), TPTAG_DEBUG_DROP_REF(), TPTAG_THRPSIZE_REF(),
  978. * TPTAG_THRPRQSIZE_REF(), TPTAG_SIGCOMP_LIFETIME_REF(),
  979. * TPTAG_CONNECT_REF(), TPTAG_SDWN_ERROR_REF(), TPTAG_REUSE_REF(),
  980. * TPTAG_STUN_SERVER_REF(), TPTAG_PUBLIC_REF() and TPTAG_TOS_REF().
  981. */
  982. int tport_get_params(tport_t const *self,
  983. tag_type_t tag, tag_value_t value, ...)
  984. {
  985. ta_list ta;
  986. int n;
  987. tport_params_t const *tpp;
  988. int connect;
  989. tport_master_t *mr = self->tp_master;
  990. if (self == NULL)
  991. return su_seterrno(EINVAL);
  992. tpp = self->tp_params;
  993. ta_start(ta, tag, value);
  994. connect = tpp->tpp_conn_orient
  995. /* Only dgram primary is *not* connection-oriented */
  996. || !tport_is_primary(self) || !tport_is_dgram(self);
  997. n = tl_tgets(ta_args(ta),
  998. TPTAG_MTU((usize_t)tpp->tpp_mtu),
  999. TPTAG_REUSE(self->tp_reusable),
  1000. TPTAG_CONNECT(connect),
  1001. TPTAG_QUEUESIZE(tpp->tpp_qsize),
  1002. TPTAG_IDLE(tpp->tpp_idle),
  1003. TPTAG_TIMEOUT(tpp->tpp_timeout),
  1004. TPTAG_SOCKET_KEEPALIVE(tpp->tpp_socket_keepalive),
  1005. TPTAG_KEEPALIVE(tpp->tpp_keepalive),
  1006. TPTAG_PINGPONG(tpp->tpp_pingpong),
  1007. TPTAG_PONG2PING(tpp->tpp_pong2ping),
  1008. TPTAG_SDWN_ERROR(tpp->tpp_sdwn_error),
  1009. TPTAG_DEBUG_DROP(tpp->tpp_drop),
  1010. TPTAG_THRPSIZE(tpp->tpp_thrpsize),
  1011. TPTAG_THRPRQSIZE(tpp->tpp_thrprqsize),
  1012. TPTAG_SIGCOMP_LIFETIME(tpp->tpp_sigcomp_lifetime),
  1013. TPTAG_STUN_SERVER(tpp->tpp_stun_server),
  1014. TAG_IF(self->tp_pri,
  1015. TPTAG_PUBLIC(self->tp_pri ?
  1016. self->tp_pri->pri_public : 0)),
  1017. TPTAG_TOS(tpp->tpp_tos),
  1018. TAG_IF((void *)self == (void *)mr,
  1019. TPTAG_LOG(mr->mr_log != 0)),
  1020. TAG_IF((void *)self == (void *)mr,
  1021. TPTAG_DUMP(mr->mr_dump)),
  1022. TAG_END());
  1023. ta_end(ta);
  1024. return n;
  1025. }
  1026. /** Set transport parameters.
  1027. *
  1028. * @param self pointer to a transport object
  1029. * @param tag,value,... list of tags
  1030. *
  1031. * @TAGS
  1032. * TPTAG_MTU(), TPTAG_QUEUESIZE(), TPTAG_IDLE(), TPTAG_TIMEOUT(),
  1033. * TPTAG_KEEPALIVE(), TPTAG_PINGPONG(), TPTAG_PONG2PING(),
  1034. * TPTAG_DEBUG_DROP(), TPTAG_THRPSIZE(), TPTAG_THRPRQSIZE(),
  1035. * TPTAG_SIGCOMP_LIFETIME(), TPTAG_CONNECT(), TPTAG_SDWN_ERROR(),
  1036. * TPTAG_REUSE(), TPTAG_STUN_SERVER(), and TPTAG_TOS().
  1037. */
  1038. int tport_set_params(tport_t *self,
  1039. tag_type_t tag, tag_value_t value, ...)
  1040. {
  1041. ta_list ta;
  1042. int n, m = 0;
  1043. tport_params_t tpp[1], *tpp0;
  1044. usize_t mtu;
  1045. int connect, sdwn_error, reusable, stun_server, pong2ping;
  1046. if (self == NULL)
  1047. return su_seterrno(EINVAL);
  1048. memcpy(tpp, tpp0 = self->tp_params, sizeof tpp);
  1049. mtu = tpp->tpp_mtu;
  1050. connect = tpp->tpp_conn_orient;
  1051. sdwn_error = tpp->tpp_sdwn_error;
  1052. reusable = self->tp_reusable;
  1053. stun_server = tpp->tpp_stun_server;
  1054. pong2ping = tpp->tpp_pong2ping;
  1055. ta_start(ta, tag, value);
  1056. n = tl_gets(ta_args(ta),
  1057. TPTAG_MTU_REF(mtu),
  1058. TAG_IF(!self->tp_queue, TPTAG_QUEUESIZE_REF(tpp->tpp_qsize)),
  1059. TPTAG_IDLE_REF(tpp->tpp_idle),
  1060. TPTAG_TIMEOUT_REF(tpp->tpp_timeout),
  1061. TPTAG_SOCKET_KEEPALIVE_REF(tpp->tpp_socket_keepalive),
  1062. TPTAG_KEEPALIVE_REF(tpp->tpp_keepalive),
  1063. TPTAG_PINGPONG_REF(tpp->tpp_pingpong),
  1064. TPTAG_PONG2PING_REF(pong2ping),
  1065. TPTAG_DEBUG_DROP_REF(tpp->tpp_drop),
  1066. TPTAG_THRPSIZE_REF(tpp->tpp_thrpsize),
  1067. TPTAG_THRPRQSIZE_REF(tpp->tpp_thrprqsize),
  1068. TPTAG_SIGCOMP_LIFETIME_REF(tpp->tpp_sigcomp_lifetime),
  1069. TPTAG_CONNECT_REF(connect),
  1070. TPTAG_SDWN_ERROR_REF(sdwn_error),
  1071. TPTAG_REUSE_REF(reusable),
  1072. TPTAG_STUN_SERVER_REF(stun_server),
  1073. TPTAG_TOS_REF(tpp->tpp_tos),
  1074. TAG_END());
  1075. if (self == (tport_t *)self->tp_master)
  1076. m = tport_open_log(self->tp_master, ta_args(ta));
  1077. ta_end(ta);
  1078. if (n == 0)
  1079. return m;
  1080. if (tpp->tpp_idle > 0 && tpp->tpp_idle < 100)
  1081. tpp->tpp_idle = 100;
  1082. if (tpp->tpp_timeout < 100)
  1083. tpp->tpp_timeout = 100;
  1084. if (tpp->tpp_drop > 1000)
  1085. tpp->tpp_drop = 1000;
  1086. if (tpp->tpp_thrprqsize > 0)
  1087. tpp->tpp_thrprqsize = tpp0->tpp_thrprqsize;
  1088. if (tpp->tpp_sigcomp_lifetime != 0 && tpp->tpp_sigcomp_lifetime < 30)
  1089. tpp->tpp_sigcomp_lifetime = 30;
  1090. if (tpp->tpp_qsize >= 1000)
  1091. tpp->tpp_qsize = 1000;
  1092. if (mtu > UINT_MAX)
  1093. mtu = UINT_MAX;
  1094. tpp->tpp_mtu = (unsigned)mtu;
  1095. /* Currently only primary UDP transport can *not* be connection oriented */
  1096. tpp->tpp_conn_orient = connect;
  1097. tpp->tpp_sdwn_error = sdwn_error;
  1098. self->tp_reusable = reusable;
  1099. tpp->tpp_stun_server = stun_server;
  1100. tpp->tpp_pong2ping = pong2ping;
  1101. if (memcmp(tpp0, tpp, sizeof tpp) == 0)
  1102. return n + m;
  1103. if (tport_is_secondary(self) &&
  1104. self->tp_params == self->tp_pri->pri_primary->tp_params) {
  1105. tpp0 = su_zalloc(self->tp_home, sizeof *tpp0); if (!tpp0) return -1;
  1106. self->tp_params = tpp0;
  1107. }
  1108. memcpy(tpp0, tpp, sizeof tpp);
  1109. if (tport_is_secondary(self))
  1110. tport_set_secondary_timer(self);
  1111. return n + m;
  1112. }
  1113. extern tport_vtable_t const tport_udp_vtable;
  1114. extern tport_vtable_t const tport_tcp_vtable;
  1115. extern tport_vtable_t const tport_tls_vtable;
  1116. extern tport_vtable_t const tport_ws_vtable;
  1117. extern tport_vtable_t const tport_wss_vtable;
  1118. extern tport_vtable_t const tport_sctp_vtable;
  1119. extern tport_vtable_t const tport_udp_client_vtable;
  1120. extern tport_vtable_t const tport_tcp_client_vtable;
  1121. extern tport_vtable_t const tport_sctp_client_vtable;
  1122. extern tport_vtable_t const tport_ws_client_vtable;
  1123. extern tport_vtable_t const tport_wss_client_vtable;
  1124. extern tport_vtable_t const tport_tls_client_vtable;
  1125. extern tport_vtable_t const tport_http_connect_vtable;
  1126. extern tport_vtable_t const tport_threadpool_vtable;
  1127. #define TPORT_NUMBER_OF_TYPES 64
  1128. tport_vtable_t const *tport_vtables[TPORT_NUMBER_OF_TYPES + 1] =
  1129. {
  1130. #if HAVE_SOFIA_NTH
  1131. &tport_http_connect_vtable,
  1132. &tport_ws_client_vtable,
  1133. &tport_ws_vtable,
  1134. &tport_wss_client_vtable,
  1135. &tport_wss_vtable,
  1136. #endif
  1137. #if HAVE_TLS
  1138. &tport_tls_client_vtable,
  1139. &tport_tls_vtable,
  1140. #endif
  1141. #if HAVE_SCTP /* SCTP is broken */
  1142. &tport_sctp_client_vtable,
  1143. &tport_sctp_vtable,
  1144. #endif
  1145. &tport_tcp_client_vtable,
  1146. &tport_tcp_vtable,
  1147. &tport_udp_client_vtable,
  1148. &tport_udp_vtable,
  1149. #if 0
  1150. &tport_threadpool_vtable,
  1151. #endif
  1152. #if HAVE_SOFIA_STUN
  1153. &tport_stun_vtable,
  1154. #endif
  1155. };
  1156. /** Register new transport vtable */
  1157. int tport_register_type(tport_vtable_t const *vtp)
  1158. {
  1159. int i;
  1160. for (i = TPORT_NUMBER_OF_TYPES; i >= 0; i--) {
  1161. if (tport_vtables[i] == NULL) {
  1162. tport_vtables[i] = vtp;
  1163. return 0;
  1164. }
  1165. }
  1166. su_seterrno(ENOMEM);
  1167. return -1;
  1168. }
  1169. /**Get a vtable for given protocol */
  1170. tport_vtable_t const *tport_vtable_by_name(char const *protoname,
  1171. enum tport_via public)
  1172. {
  1173. int i;
  1174. for (i = TPORT_NUMBER_OF_TYPES; i >= 0; i--) {
  1175. tport_vtable_t const *vtable = tport_vtables[i];
  1176. if (vtable == NULL)
  1177. continue;
  1178. if (vtable->vtp_public != public)
  1179. continue;
  1180. if (!su_casematch(protoname, vtable->vtp_name))
  1181. continue;
  1182. assert(vtable->vtp_pri_size >= sizeof (tport_primary_t));
  1183. assert(vtable->vtp_secondary_size >= sizeof (tport_t));
  1184. return vtable;
  1185. }
  1186. return NULL;
  1187. }
  1188. #if 0
  1189. tport_set_f const *tport_set_methods[TPORT_NUMBER_OF_TYPES + 1] =
  1190. {
  1191. tport_server_bind_set,
  1192. tport_client_bind_set,
  1193. tport_threadpool_set,
  1194. #if HAVE_SOFIA_NTH
  1195. tport_http_connect_set,
  1196. #endif
  1197. #if HAVE_TLS
  1198. tport_tls_set,
  1199. #endif
  1200. NULL
  1201. };
  1202. int tport_bind_set(tport_master_t *mr,
  1203. tp_name_t const *tpn,
  1204. char const * const transports[],
  1205. tagi_t const *taglist,
  1206. tport_set_t **return_set,
  1207. int set_size)
  1208. {
  1209. int i;
  1210. for (i = TPORT_NUMBER_OF_TYPES; i >= 0; i--) {
  1211. tport_set_f const *perhaps = tport_vtables[i];
  1212. int result;
  1213. if (perhaps == NULL)
  1214. continue;
  1215. result = perhaps(mr, tpn, transports, taglist, return_set, set_size);
  1216. if (result != 0)
  1217. return result;
  1218. }
  1219. return 0;
  1220. }
  1221. #endif
  1222. /** Bind transport objects.
  1223. *
  1224. * @param self pointer to a transport object
  1225. * @param tpn desired transport address
  1226. * @param transports list of protocol names supported by stack
  1227. * @param tag,value,... tagged argument list
  1228. *
  1229. * @TAGS
  1230. * TPTAG_SERVER(), TPTAG_PUBLIC(), TPTAG_IDENT(), TPTAG_HTTP_CONNECT(),
  1231. * TPTAG_CERTIFICATE(), TPTAG_TLS_VERSION(), TPTAG_TLS_VERIFY_POLICY, and
  1232. * tags used with tport_set_params(), especially TPTAG_QUEUESIZE().
  1233. */
  1234. int tport_tbind(tport_t *self,
  1235. tp_name_t const *tpn,
  1236. char const * const transports[],
  1237. tag_type_t tag, tag_value_t value, ...)
  1238. {
  1239. ta_list ta;
  1240. int server = 1, retval, public = 0;
  1241. tp_name_t mytpn[1];
  1242. tport_master_t *mr;
  1243. char const *http_connect = NULL;
  1244. if (self == NULL || tport_is_secondary(self) ||
  1245. tpn == NULL || transports == NULL) {
  1246. su_seterrno(EINVAL);
  1247. return -1;
  1248. }
  1249. *mytpn = *tpn;
  1250. if (mytpn->tpn_ident == NULL)
  1251. mytpn->tpn_ident = self->tp_ident;
  1252. ta_start(ta, tag, value);
  1253. tl_gets(ta_args(ta),
  1254. TPTAG_SERVER_REF(server),
  1255. TPTAG_PUBLIC_REF(public),
  1256. TPTAG_IDENT_REF(mytpn->tpn_ident),
  1257. TPTAG_HTTP_CONNECT_REF(http_connect),
  1258. TAG_END());
  1259. mr = self->tp_master; assert(mr);
  1260. if (http_connect && public == 0)
  1261. public = tport_type_connect;
  1262. if (public && public != tport_type_stun)
  1263. server = 0;
  1264. if (server)
  1265. retval = tport_bind_server(mr, mytpn, transports, (enum tport_via)public, ta_args(ta));
  1266. else
  1267. retval = tport_bind_client(mr, mytpn, transports, (enum tport_via)public, ta_args(ta));
  1268. ta_end(ta);
  1269. return retval;
  1270. }
  1271. /** Bind primary transport objects used by a client-only application.
  1272. * @internal
  1273. */
  1274. int tport_bind_client(tport_master_t *mr,
  1275. tp_name_t const *tpn,
  1276. char const * const transports[],
  1277. enum tport_via public,
  1278. tagi_t *tags)
  1279. {
  1280. int i;
  1281. tport_primary_t *pri = NULL, **tbf;
  1282. tp_name_t tpn0[1] = {{ "*", "*", "*", "*", NULL, NULL }};
  1283. char const *why = "unknown";
  1284. tport_vtable_t const *vtable;
  1285. if (public == tport_type_local)
  1286. public = tport_type_client;
  1287. SU_DEBUG_5(("%s(%p) to " TPN_FORMAT "\n",
  1288. __func__, (void *)mr, TPN_ARGS(tpn)));
  1289. memset(tpn0, 0, sizeof(tpn0));
  1290. for (tbf = &mr->mr_primaries; *tbf; tbf = &(*tbf)->pri_next)
  1291. ;
  1292. for (i = 0; transports[i]; i++) {
  1293. su_addrinfo_t hints[1];
  1294. char const *proto = transports[i];
  1295. if (strcmp(proto, tpn->tpn_proto) != 0 &&
  1296. strcmp(tpn->tpn_proto, tpn_any) != 0)
  1297. continue;
  1298. vtable = tport_vtable_by_name(proto, public);
  1299. if (!vtable)
  1300. continue;
  1301. /* Resolve protocol, skip unknown transport protocols */
  1302. if (getprotohints(hints, proto, AI_PASSIVE) < 0)
  1303. continue;
  1304. tpn0->tpn_proto = proto;
  1305. tpn0->tpn_comp = tpn->tpn_comp;
  1306. tpn0->tpn_ident = tpn->tpn_ident;
  1307. hints->ai_canonname = "*";
  1308. if (!(pri = tport_alloc_primary(mr, vtable, tpn0, hints, tags, &why)))
  1309. break;
  1310. pri->pri_public = tport_type_client; /* XXX */
  1311. }
  1312. if (!pri) {
  1313. SU_DEBUG_3(("tport_alloc_primary: %s failed\n", why));
  1314. tport_zap_primary(*tbf);
  1315. }
  1316. return pri ? 0 : -1;
  1317. }
  1318. /** Bind primary transport objects used by a server application. */
  1319. int tport_bind_server(tport_master_t *mr,
  1320. tp_name_t const *tpn,
  1321. char const * const transports[],
  1322. enum tport_via public,
  1323. tagi_t *tags)
  1324. {
  1325. char hostname[TPORT_HOSTPORTSIZE];
  1326. char const *canon = NULL, *host, *service;
  1327. int error = 0, family = 0;
  1328. tport_primary_t *pri = NULL, **tbf;
  1329. su_addrinfo_t *ai, *res = NULL;
  1330. unsigned port, port0, port1, old;
  1331. unsigned short step = 0;
  1332. bind6only_check(mr);
  1333. (void)hostname;
  1334. SU_DEBUG_5(("%s(%p) to " TPN_FORMAT "\n",
  1335. __func__, (void *)mr, TPN_ARGS(tpn)));
  1336. if (tpn->tpn_host == NULL || strcmp(tpn->tpn_host, tpn_any) == 0) {
  1337. /* Use a local IP address */
  1338. host = NULL;
  1339. }
  1340. #ifdef SU_HAVE_IN6
  1341. else if (host_is_ip6_reference(tpn->tpn_host)) {
  1342. /* Remove [] around IPv6 addresses. */
  1343. size_t len = strlen(tpn->tpn_host);
  1344. assert(len < sizeof hostname);
  1345. host = memcpy(hostname, tpn->tpn_host + 1, len - 2);
  1346. hostname[len - 2] = '\0';
  1347. }
  1348. #endif
  1349. else
  1350. host = tpn->tpn_host;
  1351. if (tpn->tpn_port != NULL && strlen(tpn->tpn_port) > 0 &&
  1352. strcmp(tpn->tpn_port, tpn_any) != 0)
  1353. service = tpn->tpn_port;
  1354. else
  1355. service = "";
  1356. if (host && (strcmp(host, "0.0.0.0") == 0 || strcmp(host, "0") == 0))
  1357. host = NULL, family = AF_INET;
  1358. #if SU_HAVE_IN6
  1359. else if (host && strcmp(host, "::") == 0)
  1360. host = NULL, family = AF_INET6;
  1361. #endif
  1362. if (tpn->tpn_canon && strcmp(tpn->tpn_canon, tpn_any) &&
  1363. (host || tpn->tpn_canon != tpn->tpn_host))
  1364. canon = tpn->tpn_canon;
  1365. if (tport_server_addrinfo(mr, canon, family,
  1366. host, service, tpn->tpn_proto,
  1367. transports, &res) < 0)
  1368. return -1;
  1369. for (tbf = &mr->mr_primaries; *tbf; tbf = &(*tbf)->pri_next)
  1370. ;
  1371. if (!res)
  1372. return -1;
  1373. port = port0 = port1 = ntohs(((su_sockaddr_t *)res->ai_addr)->su_port);
  1374. error = EPROTONOSUPPORT;
  1375. /*
  1376. * Loop until we can bind all the transports requested
  1377. * by the transport user to the same port.
  1378. */
  1379. for (;;) {
  1380. for (ai = res; ai; ai = ai->ai_next) {
  1381. tp_name_t tpname[1];
  1382. su_addrinfo_t ainfo[1];
  1383. su_sockaddr_t su[1];
  1384. tport_vtable_t const *vtable;
  1385. vtable = tport_vtable_by_name(ai->ai_canonname, public);
  1386. if (!vtable)
  1387. continue;
  1388. tport_addrinfo_copy(ainfo, su, sizeof su, ai);
  1389. ainfo->ai_canonname = (char *)canon;
  1390. su->su_port = htons(port);
  1391. memcpy(tpname, tpn, sizeof tpname);
  1392. tpname->tpn_canon = canon;
  1393. tpname->tpn_host = host;
  1394. SU_DEBUG_9(("%s(%p): calling tport_listen for %s\n",
  1395. __func__, (void *)mr, ai->ai_canonname));
  1396. pri = tport_listen(mr, vtable, tpname, ainfo, tags);
  1397. if (!pri) {
  1398. switch (error = su_errno()) {
  1399. case EADDRNOTAVAIL: /* Not our address */
  1400. case ENOPROTOOPT: /* Protocol not supported */
  1401. case ESOCKTNOSUPPORT: /* Socket type not supported */
  1402. continue;
  1403. default:
  1404. break;
  1405. }
  1406. break;
  1407. }
  1408. if (port0 == 0 && port == 0) {
  1409. port = port1 = ntohs(su->su_port);
  1410. assert(public != tport_type_server || port != 0);
  1411. }
  1412. }
  1413. if (ai == NULL)
  1414. break;
  1415. while (*tbf)
  1416. tport_zap_primary(*tbf);
  1417. if (error != EADDRINUSE || port0 != 0 || port == 0)
  1418. break;
  1419. while (step == 0) {
  1420. /* step should be relative prime to 65536 - 1024 */
  1421. /* 65536 - 1024 = 7 * 3 * 3 * 1024 */
  1422. step = su_randint(1, 65535 - 1024 - 1) | 1;
  1423. if (step % 3 == 0)
  1424. step = (step + 2) % (65536 - 1024);
  1425. if (step % 7 == 0)
  1426. step = (step + 2) % (65536 - 1024);
  1427. }
  1428. old = port; port += step; if (port >= 65536) port -= (65536 - 1024);
  1429. if (port == port1) /* All ports in use! */
  1430. break;
  1431. SU_DEBUG_3(("%s(%p): cannot bind all transports to port %u, trying %u\n",
  1432. __func__, (void *)mr, old, port));
  1433. }
  1434. tport_freeaddrinfo(res);
  1435. if (!*tbf) {
  1436. su_seterrno(error);
  1437. return -1;
  1438. }
  1439. return 0;
  1440. }
  1441. /** Check if we can bind to IPv6 separately from IPv4 bind */
  1442. static
  1443. int bind6only_check(tport_master_t *mr)
  1444. {
  1445. int retval = 0;
  1446. #if SU_HAVE_IN6
  1447. su_sockaddr_t su[1], su4[1];
  1448. socklen_t sulen, su4len;
  1449. int s6, s4;
  1450. if (mr->mr_boundserver)
  1451. return 0;
  1452. s4 = su_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  1453. s6 = su_socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
  1454. memset(su, 0, sizeof *su);
  1455. su->su_len = sulen = (sizeof su->su_sin6);
  1456. su->su_family = AF_INET6;
  1457. memset(su4, 0, sizeof *su4);
  1458. su4->su_len = su4len = (sizeof su->su_sin);
  1459. su4->su_family = AF_INET;
  1460. if (bind(s6, &su->su_sa, sulen) < 0)
  1461. ;
  1462. else if (getsockname(s6, &su->su_sa, &sulen) < 0)
  1463. ;
  1464. else if ((su4->su_port = su->su_port) != 0 &&
  1465. bind(s4, &su4->su_sa, su4len) == 0)
  1466. retval = 1;
  1467. su_close(s6), su_close(s4);
  1468. mr->mr_bindv6only = retval;
  1469. mr->mr_boundserver = 1;
  1470. #endif
  1471. return retval;
  1472. }
  1473. /* Number of supported transports */
  1474. #define TPORT_N (8)
  1475. /** Return list of addrinfo structures matching to
  1476. * canon/host/service/protocol
  1477. */
  1478. static
  1479. int tport_server_addrinfo(tport_master_t *mr,
  1480. char const *canon,
  1481. int family,
  1482. char const *host,
  1483. char const *service,
  1484. char const *protocol,
  1485. char const * const transports[],
  1486. su_addrinfo_t **return_addrinfo)
  1487. {
  1488. int i, N;
  1489. su_addrinfo_t hints[TPORT_N + 1];
  1490. *return_addrinfo = NULL;
  1491. /*
  1492. * Resolve all the transports requested by the protocol
  1493. */
  1494. for (i = 0, N = 0; transports[i] && N < TPORT_N; i++) {
  1495. su_addrinfo_t *ai = &hints[N];
  1496. if (!su_casematch(protocol, transports[i]) && !su_strmatch(protocol, "*"))
  1497. continue;
  1498. /* Resolve protocol, skip unknown transport protocols. */
  1499. if (getprotohints(ai, transports[i], AI_PASSIVE) < 0)
  1500. continue;
  1501. ai->ai_family = family;
  1502. ai->ai_next = &hints[++N];
  1503. }
  1504. if (N == 0)
  1505. return su_seterrno(EPROTONOSUPPORT);
  1506. if (transports[i] /* Too many protocols */)
  1507. return su_seterrno(ENOMEM);
  1508. hints[N - 1].ai_next = NULL;
  1509. if (host) {
  1510. int error = tport_getaddrinfo(host, service, hints, return_addrinfo);
  1511. if (error || !*return_addrinfo) {
  1512. SU_DEBUG_3(("%s(%p): su_getaddrinfo(%s, %s) for %s: %s\n",
  1513. __func__, (void *)mr,
  1514. host ? host : "\"\"", service, protocol,
  1515. su_gai_strerror(error)));
  1516. return su_seterrno(error != EAI_MEMORY ? ENOENT : ENOMEM);
  1517. }
  1518. return 0;
  1519. }
  1520. return tport_get_local_addrinfo(mr, service, hints, return_addrinfo);
  1521. }
  1522. /** Convert localinfo into addrinfo */
  1523. static
  1524. int
  1525. tport_get_local_addrinfo(tport_master_t *mr,
  1526. char const *port,
  1527. su_addrinfo_t const *hints,
  1528. su_addrinfo_t **return_ai)
  1529. {
  1530. int error, family;
  1531. su_localinfo_t lihints[1] = {{ 0 }};
  1532. su_localinfo_t *li, *li_result;
  1533. su_addrinfo_t const *h;
  1534. su_addrinfo_t *ai, **prev;
  1535. su_sockaddr_t *su;
  1536. unsigned long lport = 0;
  1537. char *rest;
  1538. prev = return_ai, *prev = NULL;
  1539. if (port) {
  1540. lport = strtoul(port, &rest, 10);
  1541. if (lport >= 65536) {
  1542. su_seterrno(EINVAL);
  1543. return -1;
  1544. }
  1545. }
  1546. family = hints->ai_family;
  1547. for (h = hints->ai_next; h && family; h = h->ai_next)
  1548. if (h->ai_family != family)
  1549. family = 0;
  1550. lihints->li_flags = 0;
  1551. lihints->li_family = family;
  1552. lihints->li_scope = LI_SCOPE_GLOBAL | LI_SCOPE_SITE | LI_SCOPE_HOST;
  1553. error = su_getlocalinfo(lihints, &li_result);
  1554. if (error) {
  1555. #if SU_HAVE_IN6
  1556. SU_DEBUG_3(("%s(%p): su_getlocalinfo() for %s address: %s\n",
  1557. __func__, (void *)mr,
  1558. family == AF_INET6 ? "ip6"
  1559. : family == AF_INET ? "ip4" : "ip",
  1560. su_gli_strerror(error)));
  1561. #else
  1562. SU_DEBUG_3(("%s(%p): su_getlocalinfo() for %s address: %s\n",
  1563. __func__, (void *)mr,
  1564. family == AF_INET ? "ip4" : "ip",
  1565. su_gli_strerror(error)));
  1566. #endif
  1567. su_seterrno(ENOENT);
  1568. return -1;
  1569. }
  1570. for (li = li_result; li; li = li->li_next) {
  1571. for (h = hints; h; h = h->ai_next) {
  1572. if (h->ai_family && h->ai_family != li->li_family)
  1573. continue;
  1574. ai = calloc(1, sizeof *ai + li->li_addrlen);
  1575. if (ai == NULL)
  1576. break;
  1577. *prev = ai, prev = &ai->ai_next;
  1578. ai->ai_flags = AI_PASSIVE | TP_AI_ANY;
  1579. ai->ai_family = li->li_family;
  1580. ai->ai_socktype = h->ai_socktype;
  1581. ai->ai_protocol = h->ai_protocol;
  1582. ai->ai_canonname = h->ai_canonname;
  1583. ai->ai_addr = memcpy(ai + 1, li->li_addr,
  1584. ai->ai_addrlen = li->li_addrlen);
  1585. su = (void *)ai->ai_addr;
  1586. su->su_port = htons(lport);
  1587. }
  1588. }
  1589. su_freelocalinfo(li_result);
  1590. if (li) {
  1591. tport_freeaddrinfo(*return_ai);
  1592. su_seterrno(ENOMEM);
  1593. return -1;
  1594. }
  1595. if (*return_ai == NULL) {
  1596. su_seterrno(ENOENT);
  1597. return -1;
  1598. }
  1599. return 0;
  1600. }
  1601. su_inline su_addrinfo_t *get_next_addrinfo(su_addrinfo_t **all);
  1602. /** Translate address and service.
  1603. *
  1604. * This is a getaddrinfo() supporting multiple hints in a list.
  1605. */
  1606. int tport_getaddrinfo(char const *node, char const *service,
  1607. su_addrinfo_t const *hints,
  1608. su_addrinfo_t **res)
  1609. {
  1610. su_addrinfo_t const *h0;
  1611. su_addrinfo_t *tbf, **prev;
  1612. int error = EAI_SOCKTYPE;
  1613. int i, N;
  1614. su_addrinfo_t *all[TPORT_N + 1]; /* Lists for all supported transports */
  1615. su_addrinfo_t *results[TPORT_N + 1];
  1616. void *addr;
  1617. int addrlen;
  1618. *res = NULL;
  1619. for (N = 0, h0 = hints; h0; h0 = h0->ai_next) {
  1620. su_addrinfo_t h[1];
  1621. *h = *h0, h->ai_next = NULL, h->ai_canonname = NULL;
  1622. error = su_getaddrinfo(node, service, h, &all[N]);
  1623. results[N] = all[N];
  1624. if (error == EAI_SOCKTYPE) {
  1625. SU_DEBUG_7(("%s(): su_getaddrinfo(%s, %s) for %s: %s\n",
  1626. __func__, node ? node : "\"\"", service,
  1627. h0->ai_canonname, su_gai_strerror(error)));
  1628. continue;
  1629. }
  1630. if (error || !all[N])
  1631. break;
  1632. N++;
  1633. }
  1634. if (h0)
  1635. for (i = 0; i < N; i++)
  1636. su_freeaddrinfo(all[i]);
  1637. if (error)
  1638. return error;
  1639. /* Combine all the valid addrinfo structures to a single list */
  1640. prev = &tbf, tbf = NULL;
  1641. for (;;) {
  1642. su_addrinfo_t *ai = NULL, *ai0;
  1643. for (i = 0, h0 = hints; i < N; i++, h0 = h0->ai_next) {
  1644. if ((ai = get_next_addrinfo(&results[i])))
  1645. break;
  1646. }
  1647. if (i == N)
  1648. break;
  1649. assert(ai);
  1650. addr = SU_ADDR((su_sockaddr_t *)ai->ai_addr);
  1651. addrlen = SU_ADDRLEN((su_sockaddr_t *)ai->ai_addr);
  1652. /* Copy all the addrinfo structures with same address to the list */
  1653. for (; i < N; i++, h0 = h0->ai_next) {
  1654. while ((ai0 = get_next_addrinfo(&results[i]))) {
  1655. void *a = SU_ADDR((su_sockaddr_t *)ai0->ai_addr);
  1656. if (memcmp(addr, a, addrlen)) /* Different address */
  1657. break;
  1658. results[i] = ai0->ai_next;
  1659. ai = calloc(1, sizeof *ai + ai0->ai_addrlen);
  1660. if (ai == NULL)
  1661. goto error;
  1662. *prev = memcpy(ai, ai0, sizeof *ai); prev = &ai->ai_next; *prev = NULL;
  1663. ai->ai_addr = memcpy(ai + 1, ai0->ai_addr, ai0->ai_addrlen);
  1664. ai->ai_canonname = h0->ai_canonname;
  1665. }
  1666. }
  1667. }
  1668. for (i = 0; i < N; i++)
  1669. su_freeaddrinfo(all[i]);
  1670. *res = tbf;
  1671. return 0;
  1672. error:
  1673. for (i = 0; i < N; i++)
  1674. su_freeaddrinfo(all[i]);
  1675. tport_freeaddrinfo(tbf);
  1676. return EAI_MEMORY;
  1677. }
  1678. su_inline
  1679. su_addrinfo_t *get_next_addrinfo(su_addrinfo_t **all)
  1680. {
  1681. su_addrinfo_t *ai;
  1682. while ((ai = *all)) {
  1683. if (ai->ai_family == AF_INET)
  1684. return ai;
  1685. #if SU_HAVE_IN6
  1686. if (ai->ai_family == AF_INET6)
  1687. return ai;
  1688. #endif
  1689. *all = ai->ai_next;
  1690. }
  1691. return ai;
  1692. }
  1693. static
  1694. void tport_freeaddrinfo(su_addrinfo_t *ai)
  1695. {
  1696. su_addrinfo_t *ai_next;
  1697. while (ai) {
  1698. ai_next = ai->ai_next;
  1699. free(ai);
  1700. ai = ai_next;
  1701. }
  1702. }
  1703. static
  1704. int tport_addrinfo_copy(su_addrinfo_t *dst, void *addr, socklen_t addrlen,
  1705. su_addrinfo_t const *src)
  1706. {
  1707. if (addrlen < src->ai_addrlen)
  1708. return -1;
  1709. memcpy(dst, src, sizeof *dst);
  1710. if (src->ai_addrlen < addrlen)
  1711. memset(addr, 0, addrlen);
  1712. dst->ai_addr = memcpy(addr, src->ai_addr, src->ai_addrlen);
  1713. dst->ai_next = NULL;
  1714. return 0;
  1715. }
  1716. /** Close a transport.
  1717. *
  1718. * Close the socket associated with a transport object. Report an error to
  1719. * all pending clients, if required. Set/reset timer, too.
  1720. */
  1721. void tport_close(tport_t *self)
  1722. {
  1723. SU_DEBUG_5(("%s(%p): " TPN_FORMAT "\n",
  1724. __func__, (void *)self, TPN_ARGS(self->tp_name)));
  1725. if (self->tp_refs == -1) {
  1726. self->tp_refs = 0;
  1727. }
  1728. if (self->tp_closed || !tport_is_secondary(self))
  1729. return;
  1730. tprb_remove(&self->tp_pri->pri_open, self);
  1731. tplist_insert(&self->tp_pri->pri_closed, self);
  1732. self->tp_closed = 1;
  1733. self->tp_send_close = 3;
  1734. self->tp_recv_close = 3;
  1735. if (self->tp_params->tpp_sdwn_error && self->tp_pused)
  1736. tport_error_report(self, -1, NULL);
  1737. if (self->tp_pri->pri_vtable->vtp_shutdown)
  1738. self->tp_pri->pri_vtable->vtp_shutdown(self, 2);
  1739. else if (self->tp_socket != -1)
  1740. shutdown(self->tp_socket, 2);
  1741. if (self->tp_index)
  1742. su_root_deregister(self->tp_master->mr_root, self->tp_index);
  1743. self->tp_index = 0;
  1744. #if SU_HAVE_BSDSOCK
  1745. if (self->tp_socket != -1)
  1746. su_close(self->tp_socket);
  1747. self->tp_socket = -1;
  1748. #endif
  1749. /* Zap the queued messages */
  1750. if (self->tp_queue) {
  1751. unsigned short i, N = self->tp_params->tpp_qsize;
  1752. for (i = 0; i < N; i++) {
  1753. if (self->tp_queue[i])
  1754. msg_ref_destroy(self->tp_queue[i]), self->tp_queue[i] = NULL;
  1755. }
  1756. }
  1757. self->tp_index = 0;
  1758. self->tp_events = 0;
  1759. }
  1760. /** Shutdown a transport.
  1761. *
  1762. * The tport_shutdown() shuts down a full-duplex transport connection
  1763. * partially or completely. If @a how is 0, the further incoming data is
  1764. * shut down. If @a how is 1, further outgoing data is shut down. If @a how
  1765. * is 2, both incoming and outgoing traffic is shut down.
  1766. *
  1767. */
  1768. int tport_shutdown(tport_t *self, int how)
  1769. {
  1770. int retval;
  1771. if (!tport_is_secondary(self))
  1772. return -1;
  1773. retval = tport_shutdown0(self, how);
  1774. tport_set_secondary_timer(self);
  1775. return retval;
  1776. }
  1777. /** Internal shutdown function */
  1778. int tport_shutdown0(tport_t *self, int how)
  1779. {
  1780. SU_DEBUG_7(("%s(%p, %d)\n", __func__, (void *)self, how));
  1781. if (!tport_is_tcp(self) ||
  1782. how < 0 || how >= 2 ||
  1783. (how == 0 && self->tp_send_close) ||
  1784. (how == 1 && self->tp_recv_close > 1)) {
  1785. tport_close(self);
  1786. return 1;
  1787. }
  1788. if (self->tp_pri->pri_vtable->vtp_shutdown)
  1789. self->tp_pri->pri_vtable->vtp_shutdown(self, how);
  1790. else
  1791. shutdown(self->tp_socket, how);
  1792. if (how == 0) {
  1793. self->tp_recv_close = 2;
  1794. tport_set_events(self, 0, SU_WAIT_IN);
  1795. if (self->tp_params->tpp_sdwn_error && self->tp_pused)
  1796. tport_error_report(self, -1, NULL);
  1797. }
  1798. else if (how == 1) {
  1799. self->tp_send_close = 2;
  1800. tport_set_events(self, 0, SU_WAIT_OUT);
  1801. if (tport_has_queued(self)) {
  1802. unsigned short i, N = self->tp_params->tpp_qsize;
  1803. for (i = 0; i < N; i++) {
  1804. if (self->tp_queue[i]) {
  1805. tport_pending_errmsg(self, self->tp_queue[i], EPIPE);
  1806. msg_ref_destroy(self->tp_queue[i]), self->tp_queue[i] = NULL;
  1807. }
  1808. }
  1809. }
  1810. }
  1811. return 0;
  1812. }
  1813. static void tport_secondary_timer(su_root_magic_t *magic,
  1814. su_timer_t *t,
  1815. tport_t *self)
  1816. {
  1817. su_time_t now;
  1818. if (tport_is_closed(self)) {
  1819. if (self->tp_refs == 0)
  1820. tport_zap_secondary(self);
  1821. return;
  1822. }
  1823. now = /* su_timer_expired(t); */ su_now();
  1824. if (self->tp_pri->pri_vtable->vtp_secondary_timer)
  1825. self->tp_pri->pri_vtable->vtp_secondary_timer(self, now);
  1826. else
  1827. tport_base_timer(self, now);
  1828. }
  1829. /** Base timer for secondary transports.
  1830. *
  1831. * Closes and zaps unused transports. Sets the timer again.
  1832. */
  1833. void tport_base_timer(tport_t *self, su_time_t now)
  1834. {
  1835. unsigned timeout = self->tp_params->tpp_idle;
  1836. if (timeout != UINT_MAX) {
  1837. if (self->tp_refs == 0 &&
  1838. self->tp_msg == NULL &&
  1839. !tport_has_queued(self) &&
  1840. su_time_cmp(su_time_add(self->tp_rtime, timeout), now) < 0 &&
  1841. su_time_cmp(su_time_add(self->tp_stime, timeout), now) < 0) {
  1842. SU_DEBUG_7(("%s(%p): unused for %d ms,%s zapping\n",
  1843. __func__, (void *)self,
  1844. timeout, tport_is_closed(self) ? "" : " closing and"));
  1845. if (!tport_is_closed(self))
  1846. tport_close(self);
  1847. tport_zap_secondary(self);
  1848. return;
  1849. }
  1850. }
  1851. tport_set_secondary_timer(self);
  1852. }
  1853. /** Set timer for a secondary transport.
  1854. *
  1855. * This function should be called after any network activity:
  1856. * tport_base_connect(), tport_send_msg(), tport_send_queue(),
  1857. * tport_recv_data(), tport_shutdown0(), tport_close(),
  1858. *
  1859. * @retval 0 always
  1860. */
  1861. int tport_set_secondary_timer(tport_t *self)
  1862. {
  1863. su_time_t const infinity = { ULONG_MAX, 999999 };
  1864. su_time_t target = infinity;
  1865. char const *why = "not specified";
  1866. su_timer_f timer = tport_secondary_timer;
  1867. if (!tport_is_secondary(self))
  1868. return 0;
  1869. if (tport_is_closed(self)) {
  1870. again:
  1871. if (self->tp_refs == 0) {
  1872. SU_DEBUG_7(("tport(%p): set timer at %u ms because %s\n",
  1873. (void *)self, 0, "zap"));
  1874. su_timer_set_interval(self->tp_timer, timer, self, 0);
  1875. }
  1876. else
  1877. su_timer_reset(self->tp_timer);
  1878. return 0;
  1879. }
  1880. if (self->tp_params->tpp_idle != UINT_MAX) {
  1881. if (self->tp_refs == 0 &&
  1882. self->tp_msg == NULL && !tport_has_queued(self)) {
  1883. if (su_time_cmp(self->tp_stime, self->tp_rtime) < 0) {
  1884. target = su_time_add(self->tp_rtime, self->tp_params->tpp_idle);
  1885. why = "idle since recv";
  1886. }
  1887. else {
  1888. target = su_time_add(self->tp_stime, self->tp_params->tpp_idle);
  1889. why = "idle since send";
  1890. }
  1891. }
  1892. }
  1893. if (self->tp_pri->pri_vtable->vtp_next_secondary_timer) {
  1894. if (self->tp_pri->pri_vtable->
  1895. vtp_next_secondary_timer(self, &target, &why) == -1) {
  1896. if (tport_is_closed(self)) {
  1897. goto again;
  1898. }
  1899. }
  1900. }
  1901. if (su_time_cmp(target, infinity)) {
  1902. SU_DEBUG_7(("tport(%p): set timer at %ld ms because %s\n",
  1903. (void *)self, su_duration(target, su_now()), why));
  1904. su_timer_set_at(self->tp_timer, timer, self, target);
  1905. }
  1906. else {
  1907. SU_DEBUG_9(("tport(%p): reset timer\n", (void *)self));
  1908. su_timer_reset(self->tp_timer);
  1909. }
  1910. return 0;
  1911. }
  1912. /** Flush idle connections. */
  1913. int tport_flush(tport_t *tp)
  1914. {
  1915. tport_t *tp_next;
  1916. tport_primary_t *pri;
  1917. if (tp == NULL)
  1918. return -1;
  1919. pri = tp->tp_pri;
  1920. while (pri->pri_closed)
  1921. tport_zap_secondary(pri->pri_closed);
  1922. /* Go through all secondary transports, zap idle ones */
  1923. for (tp = tprb_first(tp->tp_pri->pri_open); tp; tp = tp_next) {
  1924. tp_next = tprb_succ(tp);
  1925. if (tp->tp_refs != 0)
  1926. continue;
  1927. SU_DEBUG_1(("tport_flush(%p): %szapping\n",
  1928. (void *)tp, tport_is_closed(tp) ? "" : "closing and "));
  1929. tport_close(tp);
  1930. tport_zap_secondary(tp);
  1931. }
  1932. return 0;
  1933. }
  1934. /**Convert sockaddr_t to a transport name.
  1935. *
  1936. * @retval 0 when successful
  1937. * @retval -1 upon an error
  1938. */
  1939. int tport_convert_addr(su_home_t *home,
  1940. tp_name_t *tpn,
  1941. char const *protoname,
  1942. char const *canon,
  1943. su_sockaddr_t const *su)
  1944. {
  1945. tp_name_t name[1] = {{ NULL }};
  1946. char const *host;
  1947. char buf[TPORT_HOSTPORTSIZE];
  1948. char port[8];
  1949. size_t canonlen = canon ? strlen(canon) : 0;
  1950. if (su == NULL)
  1951. host = "*";
  1952. else if (!SU_SOCKADDR_INADDR_ANY(su))
  1953. host = tport_hostport(buf, sizeof(buf), su, 0);
  1954. else if (canonlen && su->su_family == AF_INET &&
  1955. strspn(canon, "0123456789.") == canonlen)
  1956. host = canon;
  1957. #if SU_HAVE_IN6
  1958. else if (canonlen && su->su_family == AF_INET6 &&
  1959. strspn(canon, "0123456789abcdefABCDEF:.") == canonlen)
  1960. host = canon;
  1961. #endif
  1962. else
  1963. host = localipname(su->su_family, buf, sizeof(buf));
  1964. if (host == NULL)
  1965. return -1;
  1966. if (su == NULL)
  1967. strcpy(port, "*");
  1968. else
  1969. snprintf(port, sizeof(port), "%u", ntohs(su->su_port));
  1970. name->tpn_proto = protoname;
  1971. name->tpn_host = host;
  1972. name->tpn_canon = canon ? canon : host;
  1973. name->tpn_port = port;
  1974. return tport_name_dup(home, tpn, name);
  1975. }
  1976. /** Set transport object name. @internal
  1977. */
  1978. int tport_setname(tport_t *self,
  1979. char const *protoname,
  1980. su_addrinfo_t const *ai,
  1981. char const *canon)
  1982. {
  1983. su_addrinfo_t *selfai = self->tp_addrinfo;
  1984. if (tport_convert_addr(self->tp_home, self->tp_name,
  1985. protoname, canon,
  1986. (su_sockaddr_t *)ai->ai_addr) < 0)
  1987. return -1;
  1988. if (tport_is_secondary(self))
  1989. self->tp_ident = self->tp_pri->pri_primary->tp_ident;
  1990. selfai->ai_flags = ai->ai_flags & TP_AI_MASK;
  1991. selfai->ai_family = ai->ai_family;
  1992. selfai->ai_socktype = ai->ai_socktype;
  1993. selfai->ai_protocol = ai->ai_protocol;
  1994. selfai->ai_canonname = (char *)self->tp_name->tpn_canon;
  1995. if (ai->ai_addr) {
  1996. assert(ai->ai_family), assert(ai->ai_socktype), assert(ai->ai_protocol);
  1997. memcpy(self->tp_addr, ai->ai_addr, selfai->ai_addrlen = ai->ai_addrlen);
  1998. }
  1999. return 0;
  2000. }
  2001. /**Resolve protocol name.
  2002. *
  2003. * Convert a protocol name to IP protocol number and socket type used by
  2004. * su_getaddrinfo().
  2005. *
  2006. * @param hints hints with the protocol number and socktype [OUT]
  2007. * @param proto protocol name [IN]
  2008. * @param flags hint flags
  2009. */
  2010. static
  2011. int getprotohints(su_addrinfo_t *hints,
  2012. char const *proto,
  2013. int flags)
  2014. {
  2015. memset(hints, 0, sizeof *hints);
  2016. hints->ai_flags = flags;
  2017. hints->ai_canonname = (char *)proto;
  2018. #if HAVE_TLS
  2019. if (su_casematch(proto, "tls"))
  2020. proto = "tcp";
  2021. #endif
  2022. #if HAVE_SOFIA_NTH
  2023. if (su_casematch(proto, "ws"))
  2024. proto = "tcp";
  2025. if (su_casematch(proto, "wss"))
  2026. proto = "tcp";
  2027. #endif
  2028. #if HAVE_SCTP
  2029. if (su_casematch(proto, "sctp")) {
  2030. hints->ai_protocol = IPPROTO_SCTP;
  2031. hints->ai_socktype = SOCK_STREAM;
  2032. return 0;
  2033. }
  2034. #endif
  2035. if (su_casematch(proto, "udp")) {
  2036. hints->ai_protocol = IPPROTO_UDP;
  2037. hints->ai_socktype = SOCK_DGRAM;
  2038. return 0;
  2039. }
  2040. if (su_casematch(proto, "tcp")) {
  2041. hints->ai_protocol = IPPROTO_TCP;
  2042. hints->ai_socktype = SOCK_STREAM;
  2043. return 0;
  2044. }
  2045. return -1;
  2046. }
  2047. /** Get local IP.
  2048. *
  2049. * Get primary local IP address in URI format (IPv6 address will be
  2050. * []-quoted).
  2051. */
  2052. static
  2053. char *localipname(int pf, char *buf, size_t bufsiz)
  2054. {
  2055. su_localinfo_t *li = NULL, hints[1] = {{ LI_NUMERIC | LI_CANONNAME }};
  2056. size_t n;
  2057. int error;
  2058. hints->li_family = pf;
  2059. #if SU_HAVE_IN6
  2060. if (pf == AF_INET6) {
  2061. /* Link-local addresses are not usable on IPv6 */
  2062. hints->li_scope = LI_SCOPE_GLOBAL | LI_SCOPE_SITE /* | LI_SCOPE_HOST */;
  2063. }
  2064. #endif
  2065. if ((error = su_getlocalinfo(hints, &li))) {
  2066. #if SU_HAVE_IN6
  2067. if (error == ELI_NOADDRESS && pf == AF_INET6) {
  2068. hints->li_family = AF_INET;
  2069. error = su_getlocalinfo(hints, &li);
  2070. if (error == ELI_NOADDRESS) {
  2071. hints->li_family = AF_INET6; hints->li_scope |= LI_SCOPE_HOST;
  2072. error = su_getlocalinfo(hints, &li);
  2073. }
  2074. if (error == ELI_NOADDRESS) {
  2075. hints->li_family = AF_INET;
  2076. error = su_getlocalinfo(hints, &li);
  2077. }
  2078. }
  2079. #endif
  2080. if (error) {
  2081. SU_DEBUG_1(("tport: su_getlocalinfo: %s\n", su_gli_strerror(error)));
  2082. return NULL;
  2083. }
  2084. }
  2085. assert(li); assert(li->li_canonname);
  2086. n = strlen(li->li_canonname);
  2087. if (li->li_family == AF_INET) {
  2088. if (n >= bufsiz)
  2089. return NULL;
  2090. memcpy(buf, li->li_canonname, n + 1);
  2091. }
  2092. else {
  2093. if (n + 2 >= bufsiz)
  2094. return NULL;
  2095. memcpy(buf + 1, li->li_canonname, n);
  2096. buf[0] = '['; buf[++n] = ']'; buf[++n] = '\0';
  2097. }
  2098. su_freelocalinfo(li);
  2099. return buf;
  2100. }
  2101. /** Process errors from transport. */
  2102. void tport_error_report(tport_t *self, int errcode,
  2103. su_sockaddr_t const *addr)
  2104. {
  2105. char const *errmsg;
  2106. if (errcode == 0)
  2107. return;
  2108. else if (errcode > 0)
  2109. errmsg = su_strerror(errcode);
  2110. else
  2111. /* Should be something like ENOTCONN */
  2112. errcode = 0, errmsg = "stream closed";
  2113. if (addr && addr->su_family == AF_UNSPEC)
  2114. addr = NULL;
  2115. /* Mark this connection as unusable */
  2116. if (errcode > 0 && tport_has_connection(self))
  2117. self->tp_reusable = 0;
  2118. /* Report error */
  2119. if (addr && tport_pending_error(self, addr, errcode))
  2120. ;
  2121. else if (tport_is_secondary(self) &&
  2122. tport_pending_error(self, NULL, errcode) > 0)
  2123. ;
  2124. else if (self->tp_master->mr_tpac->tpac_error) {
  2125. char *dstname = NULL;
  2126. char hp[TPORT_HOSTPORTSIZE];
  2127. if (addr)
  2128. dstname = tport_hostport(hp, sizeof hp, addr, 1);
  2129. STACK_ERROR(self, errcode, dstname);
  2130. }
  2131. else {
  2132. if (tport_is_primary(self))
  2133. SU_DEBUG_3(("%s(%p): %s (with %s)\n", __func__, (void *)self,
  2134. errmsg, self->tp_protoname));
  2135. else
  2136. SU_DEBUG_3(("%s(%p): %s (with %s/%s:%s)\n", __func__, (void *)self,
  2137. errmsg, self->tp_protoname, self->tp_host, self->tp_port));
  2138. }
  2139. /* Close connection */
  2140. if (!self->tp_closed && errcode > 0 && tport_has_connection(self)) {
  2141. tport_close(self);
  2142. tport_set_secondary_timer(self);
  2143. }
  2144. }
  2145. /** Accept a new connection.
  2146. *
  2147. * The function tport_accept() accepts a new connection and creates a
  2148. * secondary transport object for the new socket.
  2149. */
  2150. int tport_accept(tport_primary_t *pri, int events)
  2151. {
  2152. tport_t *self;
  2153. su_addrinfo_t ai[1];
  2154. su_sockaddr_t su[1] = { 0 };
  2155. socklen_t sulen = sizeof su;
  2156. su_socket_t s = INVALID_SOCKET, l = pri->pri_primary->tp_socket;
  2157. char const *reason = "accept";
  2158. if (events & SU_WAIT_ERR)
  2159. tport_error_event(pri->pri_primary);
  2160. if (!(events & SU_WAIT_ACCEPT))
  2161. return 0;
  2162. memcpy(ai, pri->pri_primary->tp_addrinfo, sizeof ai);
  2163. ai->ai_canonname = NULL;
  2164. s = accept(l, &su->su_sa, &sulen);
  2165. if (s < 0) {
  2166. tport_error_report(pri->pri_primary, su_errno(), NULL);
  2167. return 0;
  2168. }
  2169. ai->ai_addr = &su->su_sa, ai->ai_addrlen = sulen;
  2170. /* Alloc a new transport object, then register socket events with it */
  2171. if ((self = tport_alloc_secondary(pri, s, 1, &reason)) == NULL) {
  2172. SU_DEBUG_3(("%s(%p): incoming secondary on "TPN_FORMAT
  2173. " failed. reason = %s\n", __func__, (void *)pri,
  2174. TPN_ARGS(pri->pri_primary->tp_name), reason));
  2175. shutdown(s, 2);
  2176. su_close(s);
  2177. return 0;
  2178. }
  2179. else {
  2180. int events = SU_WAIT_IN|SU_WAIT_ERR|SU_WAIT_HUP;
  2181. SU_CANONIZE_SOCKADDR(su);
  2182. if (/* Prevent being marked as connected if already closed */
  2183. !tport_is_closed(self) &&
  2184. /* Name this transport */
  2185. tport_setname(self, pri->pri_protoname, ai, NULL) != -1
  2186. /* Register this secondary */
  2187. &&
  2188. tport_register_secondary(self, tport_wakeup, events) != -1) {
  2189. self->tp_conn_orient = 1;
  2190. self->tp_is_connected = 1;
  2191. SU_DEBUG_5(("%s(%p): new connection from " TPN_FORMAT "\n",
  2192. __func__, (void *)self, TPN_ARGS(self->tp_name)));
  2193. return 0;
  2194. }
  2195. /* Failure: shutdown socket, */
  2196. tport_close(self);
  2197. tport_zap_secondary(self);
  2198. self = NULL;
  2199. }
  2200. return 0;
  2201. }
  2202. /** Allocate a new message object */
  2203. msg_t *tport_msg_alloc(tport_t const *self, usize_t size)
  2204. {
  2205. if (self) {
  2206. tport_master_t *mr = self->tp_master;
  2207. msg_t *msg = mr->mr_tpac->tpac_alloc(mr->mr_stack, mr->mr_log,
  2208. NULL, size, self, NULL);
  2209. if (msg) {
  2210. su_addrinfo_t *mai = msg_addrinfo(msg);
  2211. su_addrinfo_t const *tai = self->tp_addrinfo;
  2212. mai->ai_family = tai->ai_family;
  2213. mai->ai_protocol = tai->ai_protocol;
  2214. mai->ai_socktype = tai->ai_socktype;
  2215. }
  2216. return msg;
  2217. }
  2218. else {
  2219. return NULL;
  2220. }
  2221. }
  2222. /** Process events for socket waiting to be connected
  2223. */
  2224. static int tport_connected(su_root_magic_t *magic, su_wait_t *w, tport_t *self)
  2225. {
  2226. int events = su_wait_events(w, self->tp_socket);
  2227. tport_master_t *mr = self->tp_master;
  2228. su_wait_t wait[1] = { SU_WAIT_INIT };
  2229. int su_wait_create_ret;
  2230. int error;
  2231. SU_DEBUG_7(("tport_connected(%p): events%s%s\n", (void *)self,
  2232. events & SU_WAIT_CONNECT ? " CONNECTED" : "",
  2233. events & SU_WAIT_ERR ? " ERR" : ""));
  2234. #if HAVE_POLL
  2235. assert(w->fd == self->tp_socket);
  2236. #endif
  2237. if (events & SU_WAIT_ERR)
  2238. tport_error_event(self);
  2239. if (!(events & SU_WAIT_CONNECT) || self->tp_closed) {
  2240. return 0;
  2241. }
  2242. error = su_soerror(self->tp_socket);
  2243. if (error) {
  2244. tport_error_report(self, error, NULL);
  2245. return 0;
  2246. }
  2247. self->tp_is_connected = 1;
  2248. su_root_deregister(mr->mr_root, self->tp_index);
  2249. self->tp_index = -1;
  2250. self->tp_events = SU_WAIT_IN | SU_WAIT_ERR | SU_WAIT_HUP;
  2251. if ((su_wait_create_ret = su_wait_create(wait, self->tp_socket, self->tp_events)) == -1 ||
  2252. (self->tp_index = su_root_register(mr->mr_root,
  2253. wait, tport_wakeup, self, 0))
  2254. == -1) {
  2255. if (su_wait_create_ret == 0) {
  2256. su_wait_destroy(wait);
  2257. }
  2258. tport_close(self);
  2259. tport_set_secondary_timer(self);
  2260. return 0;
  2261. }
  2262. if (tport_has_queued(self))
  2263. tport_send_event(self);
  2264. else
  2265. tport_set_secondary_timer(self);
  2266. return 0;
  2267. }
  2268. /** Process events for primary socket */
  2269. static int tport_wakeup_pri(su_root_magic_t *m, su_wait_t *w, tport_t *self)
  2270. {
  2271. tport_primary_t *pri = self->tp_pri;
  2272. int events = su_wait_events(w, self->tp_socket);
  2273. #if HAVE_POLL
  2274. assert(w->fd == self->tp_socket);
  2275. #endif
  2276. SU_DEBUG_7(("%s(%p): events%s%s%s%s%s%s\n",
  2277. "tport_wakeup_pri", (void *)self,
  2278. events & SU_WAIT_IN ? " IN" : "",
  2279. SU_WAIT_ACCEPT != SU_WAIT_IN &&
  2280. (events & SU_WAIT_ACCEPT) ? " ACCEPT" : "",
  2281. events & SU_WAIT_OUT ? " OUT" : "",
  2282. events & SU_WAIT_HUP ? " HUP" : "",
  2283. events & SU_WAIT_ERR ? " ERR" : "",
  2284. self->tp_closed ? " (closed)" : ""));
  2285. if (pri->pri_vtable->vtp_wakeup_pri)
  2286. return pri->pri_vtable->vtp_wakeup_pri(pri, events);
  2287. else
  2288. return tport_base_wakeup(self, events);
  2289. }
  2290. /** Process events for connected socket */
  2291. int tport_wakeup(su_root_magic_t *magic, su_wait_t *w, tport_t *self)
  2292. {
  2293. int events = su_wait_events(w, self->tp_socket);
  2294. int error;
  2295. #if HAVE_POLL
  2296. assert(w->fd == self->tp_socket);
  2297. #endif
  2298. SU_DEBUG_7(("%s(%p): events%s%s%s%s%s\n",
  2299. "tport_wakeup", (void *)self,
  2300. events & SU_WAIT_IN ? " IN" : "",
  2301. events & SU_WAIT_OUT ? " OUT" : "",
  2302. events & SU_WAIT_HUP ? " HUP" : "",
  2303. events & SU_WAIT_ERR ? " ERR" : "",
  2304. self->tp_closed ? " (closed)" : ""));
  2305. if (self->tp_pri->pri_vtable->vtp_wakeup)
  2306. error = self->tp_pri->pri_vtable->vtp_wakeup(self, events);
  2307. else
  2308. error = tport_base_wakeup(self, events);
  2309. if (tport_is_closed(self)) {
  2310. SU_DEBUG_9(("%s(%p): tport is closed! Setting secondary timer!\n", "tport_wakeup", (void *)self));
  2311. tport_set_secondary_timer(self);
  2312. }
  2313. return error;
  2314. }
  2315. static int tport_base_wakeup(tport_t *self, int events)
  2316. {
  2317. int error = 0;
  2318. if (events & SU_WAIT_ERR)
  2319. error = tport_error_event(self);
  2320. if ((events & SU_WAIT_OUT) && !self->tp_closed)
  2321. tport_send_event(self);
  2322. if ((events & SU_WAIT_IN) && !self->tp_closed)
  2323. tport_recv_event(self);
  2324. if ((events & SU_WAIT_HUP) && !self->tp_closed)
  2325. tport_hup_event(self);
  2326. if (error) {
  2327. if (self->tp_closed && error == EPIPE)
  2328. return 0;
  2329. tport_error_report(self, error, NULL);
  2330. }
  2331. return 0;
  2332. }
  2333. /** Stop reading from socket until tport_continue() is called. */
  2334. int tport_stall(tport_t *self)
  2335. {
  2336. return tport_set_events(self, 0, SU_WAIT_IN);
  2337. }
  2338. /** Continue reading from socket. */
  2339. int tport_continue(tport_t *self)
  2340. {
  2341. if (self == NULL || self->tp_recv_close)
  2342. return -1;
  2343. return tport_set_events(self, SU_WAIT_IN, 0);
  2344. }
  2345. /** Process "hangup" event.
  2346. *
  2347. */
  2348. void tport_hup_event(tport_t *self)
  2349. {
  2350. SU_DEBUG_7(("%s(%p)\n", __func__, (void *)self));
  2351. if (self->tp_msg) {
  2352. su_time_t now = su_now();
  2353. msg_recv_commit(self->tp_msg, 0, 1);
  2354. tport_parse(self, 1, now);
  2355. }
  2356. if (!tport_is_secondary(self))
  2357. return;
  2358. /* Shutdown completely if there are no queued messages */
  2359. /* Problem reported by Arsen Chaloyan */
  2360. tport_shutdown0(self, tport_has_queued(self) ? 0 : 2);
  2361. tport_set_secondary_timer(self);
  2362. }
  2363. /** Receive data available on the socket.
  2364. *
  2365. * @retval -1 error
  2366. * @retval 0 end-of-stream
  2367. * @retval 1 normal receive
  2368. * @retval 2 incomplete recv, recv again
  2369. * @retval 3 STUN keepalive, ignore
  2370. */
  2371. su_inline
  2372. int tport_recv_data(tport_t *self)
  2373. {
  2374. return self->tp_pri->pri_vtable->vtp_recv(self);
  2375. }
  2376. /** Process "ready to receive" event.
  2377. *
  2378. */
  2379. void tport_recv_event(tport_t *self)
  2380. {
  2381. int again;
  2382. SU_DEBUG_7(("%s(%p)\n", "tport_recv_event", (void *)self));
  2383. do {
  2384. /* Receive data from socket */
  2385. again = tport_recv_data(self);
  2386. su_time(&self->tp_rtime);
  2387. #if HAVE_SOFIA_STUN
  2388. if (again == 3) /* STUN keepalive */
  2389. return;
  2390. #endif
  2391. if (again < 0) {
  2392. int error = su_errno();
  2393. if (!su_is_blocking(error)) {
  2394. tport_error_report(self, error, NULL);
  2395. return;
  2396. }
  2397. else {
  2398. SU_DEBUG_3(("%s: recvfrom(): %s (%d)\n", __func__,
  2399. su_strerror(EAGAIN), EAGAIN));
  2400. }
  2401. }
  2402. if (again >= 0)
  2403. tport_parse(self, self->tp_pre_framed ? 1 : !again, self->tp_rtime);
  2404. }
  2405. while (again > 1);
  2406. if (!tport_is_secondary(self))
  2407. return;
  2408. if (again == 0 && !tport_is_dgram(self)) {
  2409. /* End of stream */
  2410. if (!self->tp_closed) {
  2411. /* Don't shutdown completely if there are queued messages */
  2412. tport_shutdown0(self, tport_has_queued(self) ? 0 : 2);
  2413. }
  2414. }
  2415. tport_set_secondary_timer(self);
  2416. }
  2417. /*
  2418. * Parse the data and feed complete messages to the stack
  2419. */
  2420. static void tport_parse(tport_t *self, int complete, su_time_t now)
  2421. {
  2422. msg_t *msg, *next = NULL;
  2423. int n, streaming, stall = 0;
  2424. for (msg = self->tp_msg; msg; msg = next) {
  2425. n = msg_extract(msg); /* Parse message */
  2426. streaming = 0;
  2427. if (n == 0) {
  2428. if (complete)
  2429. msg_mark_as_complete(msg, MSG_FLG_ERROR), n = -1;
  2430. else if (!(streaming = msg_is_streaming(msg))) {
  2431. tport_sigcomp_accept_incomplete(self, msg);
  2432. break;
  2433. }
  2434. }
  2435. if (msg_get_flags(msg, MSG_FLG_TOOLARGE))
  2436. SU_DEBUG_3(("%s(%p): too large message from " TPN_FORMAT "\n",
  2437. __func__, (void *)self, TPN_ARGS(self->tp_name)));
  2438. /* Do not try to read anymore from this connection? */
  2439. if (tport_is_stream(self) &&
  2440. msg_get_flags(msg, MSG_FLG_TOOLARGE | MSG_FLG_ERROR))
  2441. self->tp_recv_close = stall = 1;
  2442. if (n == -1)
  2443. next = NULL;
  2444. else if (streaming)
  2445. msg_ref_create(msg); /* Keep a reference */
  2446. else if (tport_is_stream(self))
  2447. next = msg_next(msg);
  2448. else
  2449. next = NULL;
  2450. tport_deliver(self, msg, next, self->tp_comp, now);
  2451. if (streaming && next == NULL)
  2452. break;
  2453. }
  2454. if (stall)
  2455. tport_stall(self);
  2456. if (self->tp_rlogged != msg)
  2457. self->tp_rlogged = NULL;
  2458. self->tp_msg = msg;
  2459. }
  2460. /** Deliver message to the protocol stack */
  2461. void tport_deliver(tport_t *self,
  2462. msg_t *msg,
  2463. msg_t *next,
  2464. tport_compressor_t *sc,
  2465. su_time_t now)
  2466. {
  2467. tport_t *ref;
  2468. int error;
  2469. struct tport_delivery *d;
  2470. char ipaddr[SU_ADDRSIZE + 2];
  2471. assert(msg);
  2472. d = self->tp_master->mr_delivery;
  2473. d->d_tport = self;
  2474. d->d_msg = msg;
  2475. *d->d_from = *self->tp_name;
  2476. if (tport_is_primary(self)) {
  2477. su_sockaddr_t const *su = msg_addr(msg);
  2478. #if SU_HAVE_IN6
  2479. if (su->su_family == AF_INET6) {
  2480. ipaddr[0] = '[';
  2481. su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr + 1, SU_ADDRSIZE);
  2482. strcat(ipaddr, "]");
  2483. }
  2484. else {
  2485. su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr));
  2486. }
  2487. #else
  2488. su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr));
  2489. #endif
  2490. d->d_from->tpn_canon = ipaddr;
  2491. d->d_from->tpn_host = ipaddr;
  2492. }
  2493. d->d_comp = sc;
  2494. if (!sc)
  2495. d->d_from->tpn_comp = NULL;
  2496. error = msg_has_error(msg);
  2497. if (error && !*msg_chain_head(msg)) {
  2498. /* This is badly damaged packet */
  2499. }
  2500. else if (self->tp_master->mr_log && msg != self->tp_rlogged) {
  2501. char const *via = "recv";
  2502. tport_log_msg(self, msg, via, "from", now);
  2503. self->tp_rlogged = msg;
  2504. }
  2505. SU_DEBUG_7(("%s(%p): %smsg %p ("MOD_ZU" bytes)"
  2506. " from " TPN_FORMAT " next=%p\n",
  2507. __func__, (void *)self, error ? "bad " : "",
  2508. (void *)msg, (size_t)msg_size(msg),
  2509. TPN_ARGS(d->d_from), (void *)next));
  2510. ref = tport_incref(self);
  2511. if (self->tp_pri->pri_vtable->vtp_deliver) {
  2512. self->tp_pri->pri_vtable->vtp_deliver(self, msg, now);
  2513. }
  2514. else
  2515. tport_base_deliver(self, msg, now);
  2516. memset(d->d_from, 0, sizeof d->d_from);
  2517. d->d_msg = NULL;
  2518. tport_decref(&ref);
  2519. }
  2520. /** Pass message to the protocol stack */
  2521. void
  2522. tport_base_deliver(tport_t *self, msg_t *msg, su_time_t now)
  2523. {
  2524. STACK_RECV(self, msg, now);
  2525. }
  2526. /** Return source transport object for delivered message */
  2527. tport_t *tport_delivered_by(tport_t const *tp, msg_t const *msg)
  2528. {
  2529. if (tp && msg && msg == tp->tp_master->mr_delivery->d_msg)
  2530. return tp->tp_master->mr_delivery->d_tport;
  2531. else
  2532. return NULL;
  2533. }
  2534. /** Return source transport name for delivered message */
  2535. int tport_delivered_from(tport_t *tp, msg_t const *msg, tp_name_t name[1])
  2536. {
  2537. if (name == NULL)
  2538. return -1;
  2539. if (tp == NULL || msg == NULL || msg != tp->tp_master->mr_delivery->d_msg) {
  2540. memset(name, 0, sizeof *name);
  2541. return -1;
  2542. }
  2543. else {
  2544. *name = *tp->tp_master->mr_delivery->d_from;
  2545. return 0;
  2546. }
  2547. }
  2548. /** Return TLS Subjects provided by the source transport */
  2549. su_strlst_t const *tport_delivered_from_subjects(tport_t *tp, msg_t const *msg)
  2550. {
  2551. if (tp && msg && msg == tp->tp_master->mr_delivery->d_msg) {
  2552. tport_t *tp_sec = tp->tp_master->mr_delivery->d_tport;
  2553. return (tp_sec) ? tp_sec->tp_subjects : NULL;
  2554. }
  2555. else
  2556. return NULL;
  2557. }
  2558. /** Return UDVM used to decompress the message. */
  2559. int
  2560. tport_delivered_with_comp(tport_t *tp, msg_t const *msg,
  2561. tport_compressor_t **return_compressor)
  2562. {
  2563. if (tp == NULL || msg == NULL || msg != tp->tp_master->mr_delivery->d_msg)
  2564. return -1;
  2565. if (return_compressor)
  2566. *return_compressor = tp->tp_master->mr_delivery->d_comp;
  2567. return 0;
  2568. }
  2569. /** Search for subject in list of TLS Certificate subjects */
  2570. int
  2571. tport_subject_search(char const *subject, su_strlst_t const *lst)
  2572. {
  2573. usize_t idx, ilen;
  2574. const char *subjuri;
  2575. if (!subject || su_strmatch(tpn_any, subject))
  2576. return 1;
  2577. if (!lst)
  2578. return 0;
  2579. /* Check if subject is a URI */
  2580. if (su_casenmatch(subject,"sip:",4) || su_casenmatch(subject,"sips:",5))
  2581. subjuri = subject + su_strncspn(subject,5,":") + 1;
  2582. else
  2583. subjuri = NULL;
  2584. ilen = su_strlst_len(lst);
  2585. for (idx = 0; idx < ilen; idx++) {
  2586. const char *lsturi, *lststr;
  2587. lststr = su_strlst_item(lst, idx);
  2588. /* check if lststr is a URI (sips URI is an unacceptable cert subject) */
  2589. if (su_casenmatch(lststr,"sip:",4))
  2590. lsturi = lststr + su_strncspn(lststr,4,":") + 1;
  2591. else
  2592. lsturi = NULL;
  2593. /* Match two SIP Server Identities */
  2594. if (host_cmp(subjuri ? subjuri : subject, lsturi ? lsturi : lststr) == 0)
  2595. return 1;
  2596. #if 0
  2597. /* XXX - IETF drafts forbid wildcard certs */
  2598. if (!subjuri && !lsturi && su_strnmatch("*.", lststr, 2)) {
  2599. size_t urioffset = su_strncspn(subject, 64, ".");
  2600. if (urioffset) {
  2601. if (su_casematch(subject + urioffset, lststr+1))
  2602. return 1;
  2603. }
  2604. }
  2605. #endif
  2606. }
  2607. return 0;
  2608. }
  2609. /** Allocate message for N bytes,
  2610. * return message buffer as a iovec
  2611. */
  2612. ssize_t tport_recv_iovec(tport_t const *self,
  2613. msg_t **in_out_msg,
  2614. msg_iovec_t iovec[msg_n_fragments],
  2615. size_t N,
  2616. int exact)
  2617. {
  2618. msg_t *msg = *in_out_msg;
  2619. ssize_t i, veclen;
  2620. int fresh;
  2621. if (N == 0)
  2622. return 0;
  2623. fresh = !msg;
  2624. /*
  2625. * Allocate a new message if needed
  2626. */
  2627. if (!msg) {
  2628. if (!(*in_out_msg = msg = tport_msg_alloc(self, N))) {
  2629. SU_DEBUG_7(("%s(%p): cannot allocate msg for "MOD_ZU" bytes "
  2630. "from (%s/%s:%s)\n",
  2631. __func__, (void *)self, N,
  2632. self->tp_protoname, self->tp_host, self->tp_port));
  2633. return -1;
  2634. }
  2635. }
  2636. /*
  2637. * Get enough buffer space for the incoming data
  2638. */
  2639. veclen = msg_recv_iovec(msg, iovec, msg_n_fragments, N, exact);
  2640. if (veclen < 0) {
  2641. int err = su_errno();
  2642. if (fresh && err == ENOBUFS && msg_get_flags(msg, MSG_FLG_TOOLARGE))
  2643. veclen = msg_recv_iovec(msg, iovec, msg_n_fragments, 4096, 1);
  2644. }
  2645. if (veclen < 0) {
  2646. int err = su_errno();
  2647. SU_DEBUG_7(("%s(%p): cannot get msg %p buffer for "MOD_ZU" bytes "
  2648. "from (%s/%s:%s): %s\n",
  2649. __func__, (void *)self, (void *)msg, N,
  2650. self->tp_protoname, self->tp_host, self->tp_port,
  2651. su_strerror(err)));
  2652. su_seterrno(err);
  2653. return veclen;
  2654. }
  2655. assert(veclen <= msg_n_fragments);
  2656. SU_DEBUG_7(("%s(%p) msg %p from (%s/%s:%s) has "MOD_ZU" bytes, "
  2657. "veclen = "MOD_ZD"\n",
  2658. __func__, (void *)self,
  2659. (void *)msg, self->tp_protoname, self->tp_host, self->tp_port,
  2660. N, veclen));
  2661. for (i = 0; veclen > 1 && i < veclen; i++) {
  2662. SU_DEBUG_7(("\tiovec[%lu] = %lu bytes\n", (LU)i, (LU)iovec[i].mv_len));
  2663. }
  2664. return veclen;
  2665. }
  2666. int tport_recv_error_report(tport_t *self)
  2667. {
  2668. if (su_is_blocking(su_errno()))
  2669. return 1;
  2670. /* Report error */
  2671. tport_error_report(self, su_errno(), NULL);
  2672. return -1;
  2673. }
  2674. /** Send a message.
  2675. *
  2676. * The function tport_tsend() sends a message using the transport @a self.
  2677. *
  2678. * @TAGS
  2679. * TPTAG_MTU(), TPTAG_REUSE(), TPTAG_CLOSE_AFTER(), TPTAG_SDWN_AFTER(),
  2680. * TPTAG_FRESH(), TPTAG_COMPARTMENT(), TPTAG_X509_SUBJECT()
  2681. */
  2682. tport_t *tport_tsend(tport_t *self,
  2683. msg_t *msg,
  2684. tp_name_t const *_tpn,
  2685. tag_type_t tag, tag_value_t value, ...)
  2686. {
  2687. ta_list ta;
  2688. tagi_t const *t;
  2689. int reuse, sdwn_after, close_after, resolved = 0, fresh;
  2690. unsigned mtu;
  2691. su_addrinfo_t *ai;
  2692. tport_primary_t *primary;
  2693. tp_name_t tpn[1];
  2694. struct sigcomp_compartment *cc;
  2695. if (!self || !msg || !_tpn) {
  2696. msg_set_errno(msg, EINVAL);
  2697. return NULL;
  2698. }
  2699. *tpn = *_tpn;
  2700. SU_DEBUG_7(("tport_tsend(%p) tpn = " TPN_FORMAT "\n",
  2701. (void *)self, TPN_ARGS(tpn)));
  2702. if (tport_is_master(self)) {
  2703. primary = (tport_primary_t *)tport_primary_by_name(self, tpn);
  2704. if (!primary) {
  2705. msg_set_errno(msg, EPROTONOSUPPORT);
  2706. return NULL;
  2707. }
  2708. }
  2709. else {
  2710. primary = self->tp_pri;
  2711. }
  2712. ta_start(ta, tag, value);
  2713. reuse = primary->pri_primary->tp_reusable && self->tp_reusable;
  2714. fresh = 0;
  2715. sdwn_after = 0;
  2716. close_after = 0;
  2717. mtu = 0;
  2718. cc = NULL;
  2719. /* tl_gets() is a bit too slow here... */
  2720. for (t = ta_args(ta); t; t = tl_next(t)) {
  2721. tag_type_t tt = t->t_tag;
  2722. if (tptag_reuse == tt)
  2723. reuse = t->t_value != 0;
  2724. else if (tptag_mtu == tt)
  2725. mtu = t->t_value;
  2726. else if (tptag_sdwn_after == tt)
  2727. sdwn_after = t->t_value != 0;
  2728. else if (tptag_close_after == tt)
  2729. close_after = t->t_value != 0;
  2730. else if (tptag_fresh == tt)
  2731. fresh = t->t_value != 0;
  2732. else if (tptag_compartment == tt)
  2733. cc = (struct sigcomp_compartment *)t->t_value;
  2734. }
  2735. ta_end(ta);
  2736. fresh = fresh || !reuse;
  2737. ai = msg_addrinfo(msg);
  2738. ai->ai_flags = 0;
  2739. tpn->tpn_comp = tport_canonize_comp(tpn->tpn_comp);
  2740. if (tpn->tpn_comp) {
  2741. ai->ai_flags |= TP_AI_COMPRESSED;
  2742. SU_DEBUG_9(("%s: compressed msg(%p) with %s\n",
  2743. __func__, (void *)msg, tpn->tpn_comp));
  2744. }
  2745. if (!tpn->tpn_comp || cc == NONE)
  2746. cc = NULL;
  2747. if (sdwn_after)
  2748. ai->ai_flags |= TP_AI_SHUTDOWN;
  2749. if (close_after)
  2750. ai->ai_flags |= TP_AI_CLOSE;
  2751. if (fresh) {
  2752. /* Select a primary protocol, make a fresh connection */
  2753. self = primary->pri_primary;
  2754. }
  2755. else if (tport_is_secondary(self) && tport_is_clear_to_send(self)) {
  2756. /* self = self; */
  2757. ;
  2758. }
  2759. /*
  2760. * Try to find an already open connection to the destination,
  2761. * or get a primary protocol
  2762. */
  2763. else {
  2764. /* If primary, resolve the destination address, store it in the msg */
  2765. if (tport_resolve(primary->pri_primary, msg, tpn) < 0) {
  2766. return NULL;
  2767. }
  2768. resolved = 1;
  2769. self = tport_by_addrinfo(primary, msg_addrinfo(msg), tpn);
  2770. if (!self)
  2771. self = primary->pri_primary;
  2772. }
  2773. if (tport_is_primary(self)) {
  2774. /* If primary, resolve the destination address, store it in the msg */
  2775. if (!resolved && tport_resolve(self, msg, tpn) < 0) {
  2776. return NULL;
  2777. }
  2778. if (tport_is_connection_oriented(self)
  2779. || self->tp_params->tpp_conn_orient) {
  2780. #if 0 && HAVE_UPNP /* We do not want to use UPnP with secondary transports! */
  2781. if (upnp_register_upnp_client(1) != 0) {
  2782. upnp_check_for_nat();
  2783. }
  2784. #endif
  2785. tpn->tpn_proto = self->tp_protoname;
  2786. if (!cc)
  2787. tpn->tpn_comp = NULL;
  2788. /* Create a secondary transport which is connected to the destination */
  2789. self = tport_connect(primary, msg_addrinfo(msg), tpn);
  2790. #if 0 && HAVE_UPNP /* We do not want to use UPnP with secondary transports! */
  2791. upnp_deregister_upnp_client(0, 0);
  2792. #endif
  2793. if (!self) {
  2794. msg_set_errno(msg, su_errno());
  2795. SU_DEBUG_9(("tport_socket failed in tsend\n" VA_NONE));
  2796. return NULL;
  2797. }
  2798. if (cc)
  2799. tport_sigcomp_assign(self, cc);
  2800. }
  2801. }
  2802. else if (tport_is_secondary(self)) {
  2803. cc = tport_sigcomp_assign_if_needed(self, cc);
  2804. }
  2805. if (cc == NULL)
  2806. tpn->tpn_comp = NULL;
  2807. if (tport_is_secondary(self)) {
  2808. /* Set the peer address to msg */
  2809. tport_peer_address(self, msg);
  2810. if (sdwn_after || close_after)
  2811. self->tp_reusable = 0;
  2812. }
  2813. if (self->tp_pri->pri_vtable->vtp_prepare
  2814. ? self->tp_pri->pri_vtable->vtp_prepare(self, msg, tpn, cc, mtu) < 0
  2815. : tport_prepare_and_send(self, msg, tpn, cc, mtu) < 0)
  2816. return NULL;
  2817. else
  2818. return self;
  2819. }
  2820. int tport_prepare_and_send(tport_t *self, msg_t *msg,
  2821. tp_name_t const *tpn,
  2822. struct sigcomp_compartment *cc,
  2823. unsigned mtu)
  2824. {
  2825. int retval;
  2826. /* Prepare message for sending - i.e., encode it */
  2827. if (msg_prepare(msg) < 0) {
  2828. msg_set_errno(msg, errno); /* msg parser uses plain errno. Hmph. */
  2829. return -1;
  2830. }
  2831. if (msg_size(msg) > (usize_t)(mtu ? mtu : tport_mtu(self))) {
  2832. msg_set_errno(msg, EMSGSIZE);
  2833. return -1;
  2834. }
  2835. /*
  2836. * If there is already an queued message,
  2837. * put this message straight in the queue
  2838. */
  2839. if ((self->tp_queue && self->tp_queue[self->tp_qhead]) ||
  2840. /* ...or we are connecting */
  2841. (self->tp_events & (SU_WAIT_CONNECT | SU_WAIT_OUT))) {
  2842. if (tport_queue(self, msg) < 0) {
  2843. SU_DEBUG_9(("tport_queue failed in tsend\n" VA_NONE));
  2844. return -1;
  2845. }
  2846. return 0;
  2847. }
  2848. retval = tport_send_msg(self, msg, tpn, cc);
  2849. tport_set_secondary_timer(self);
  2850. return retval;
  2851. }
  2852. /** Send a message.
  2853. *
  2854. * @retval 0 when succesful
  2855. * @retval -1 upon an error
  2856. */
  2857. int tport_send_msg(tport_t *self, msg_t *msg,
  2858. tp_name_t const *tpn,
  2859. struct sigcomp_compartment *cc)
  2860. {
  2861. msg_iovec_t *iov, auto_iov[40];
  2862. size_t iovlen, iovused, i, total;
  2863. size_t n;
  2864. ssize_t nerror;
  2865. int sdwn_after, close_after;
  2866. su_time_t now;
  2867. su_addrinfo_t *ai;
  2868. assert(self->tp_queue == NULL ||
  2869. self->tp_queue[self->tp_qhead] == NULL ||
  2870. self->tp_queue[self->tp_qhead] == msg);
  2871. if (self->tp_iov)
  2872. /* Use the heap-allocated I/O vector */
  2873. iov = self->tp_iov, iovlen = self->tp_iovlen;
  2874. else
  2875. /* Use the stack I/O vector */
  2876. iov = auto_iov, iovlen = sizeof(auto_iov)/sizeof(auto_iov[0]);
  2877. /* Get a iovec for message contents */
  2878. for (;;) {
  2879. iovused = msg_iovec(msg, iov, iovlen);
  2880. if (iovused <= iovlen)
  2881. break;
  2882. iov = su_realloc(self->tp_home, self->tp_iov, sizeof(*iov) * iovused);
  2883. if (iov == NULL) {
  2884. msg_set_errno(msg, errno);
  2885. return -1;
  2886. }
  2887. self->tp_iov = iov, self->tp_iovlen = iovlen = iovused;
  2888. }
  2889. assert(iovused > 0);
  2890. self->tp_stime = self->tp_ktime = now = su_now();
  2891. nerror = tport_vsend(self, msg, tpn, iov, iovused, cc);
  2892. SU_DEBUG_9(("tport_vsend returned "MOD_ZD"\n", nerror));
  2893. if (nerror == -1)
  2894. return -1;
  2895. n = (size_t)nerror;
  2896. self->tp_unsent = NULL, self->tp_unsentlen = 0;
  2897. if (n > 0 && self->tp_master->mr_log && self->tp_slogged != msg) {
  2898. tport_log_msg(self, msg, "send", "to", now);
  2899. self->tp_slogged = msg;
  2900. }
  2901. for (i = 0, total = 0; i < iovused; i++) {
  2902. if (total + (size_t)iov[i].mv_len > n) {
  2903. if (tport_is_connection_oriented(self)) {
  2904. iov[i].mv_len -= (su_ioveclen_t)(n - total);
  2905. iov[i].mv_base = (char *)iov[i].mv_base + (n - total);
  2906. if (tport_queue_rest(self, msg, &iov[i], iovused - i) < 0)
  2907. return tport_send_fatal(self, msg, tpn, "tport_queue_rest");
  2908. else
  2909. return 0;
  2910. }
  2911. else {
  2912. char const *comp = tpn->tpn_comp;
  2913. SU_DEBUG_1(("%s(%p): send truncated for %s/%s:%s%s%s\n",
  2914. "tport_vsend", (void *)self, tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port,
  2915. comp ? ";comp=" : "", comp ? comp : ""));
  2916. msg_set_errno(msg, EIO);
  2917. return /* tport_send_fatal(self, msg, tpn, "tport_send") */ -1;
  2918. }
  2919. }
  2920. total += iov[i].mv_len;
  2921. }
  2922. /* We have sent a complete message */
  2923. tport_sent_message(self, msg, 0);
  2924. if (!tport_is_secondary(self))
  2925. return 0;
  2926. ai = msg_addrinfo(msg); assert(ai);
  2927. close_after = (ai->ai_flags & TP_AI_CLOSE) == TP_AI_CLOSE;
  2928. sdwn_after = (ai->ai_flags & TP_AI_SHUTDOWN) == TP_AI_SHUTDOWN ||
  2929. self->tp_send_close;
  2930. if (close_after || sdwn_after)
  2931. tport_shutdown0(self, close_after ? 2 : 1);
  2932. return 0;
  2933. }
  2934. static
  2935. ssize_t tport_vsend(tport_t *self,
  2936. msg_t *msg,
  2937. tp_name_t const *tpn,
  2938. msg_iovec_t iov[],
  2939. size_t iovused,
  2940. struct sigcomp_compartment *cc)
  2941. {
  2942. ssize_t n;
  2943. su_addrinfo_t *ai = msg_addrinfo(msg);
  2944. if (cc) {
  2945. n = tport_send_comp(self, msg, iov, iovused, cc, self->tp_comp);
  2946. }
  2947. else {
  2948. ai->ai_flags &= ~TP_AI_COMPRESSED;
  2949. n = self->tp_pri->pri_vtable->vtp_send(self, msg, iov, iovused);
  2950. }
  2951. if (n == 0)
  2952. return 0;
  2953. if (n == -1)
  2954. return tport_send_error(self, msg, tpn, "tport_vsend");
  2955. tport_sent_bytes(self, n, n); /* Sigcomp will decrease on_line accodingly */
  2956. if (n > 0 && self->tp_master->mr_dump_file)
  2957. tport_dump_iovec(self, msg, n, iov, iovused, "sent", "to");
  2958. if (n > 0 && self->tp_master->mr_capt_sock)
  2959. tport_capt_msg(self, msg, n, iov, iovused, "sent");
  2960. if (tport_log->log_level >= 7) {
  2961. size_t i, m = 0;
  2962. for (i = 0; i < iovused; i++)
  2963. m += iov[i].mv_len;
  2964. if (tpn == NULL || tport_is_connection_oriented(self))
  2965. tpn = self->tp_name;
  2966. SU_DEBUG_7(("%s(%p): "MOD_ZU" bytes of "MOD_ZU" to %s/%s:%s%s\n",
  2967. "tport_vsend", (void *)self, n, m,
  2968. self->tp_name->tpn_proto, tpn->tpn_host, tpn->tpn_port,
  2969. (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : ""));
  2970. }
  2971. return n;
  2972. }
  2973. static
  2974. int tport_send_error(tport_t *self, msg_t *msg, tp_name_t const *tpn,
  2975. char const *who)
  2976. {
  2977. int error = su_errno();
  2978. if (error == EPIPE) {
  2979. /*Xyzzy*/
  2980. }
  2981. if (su_is_blocking(error)) {
  2982. su_addrinfo_t *ai = msg_addrinfo(msg);
  2983. char const *comp = (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : "";
  2984. SU_DEBUG_5(("%s(%p): %s with (s=%d %s/%s:%s%s)\n",
  2985. who, (void *)self, "EAGAIN", (int)self->tp_socket,
  2986. tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp));
  2987. return 0;
  2988. }
  2989. msg_set_errno(msg, error);
  2990. return tport_send_fatal(self, msg, tpn, who);
  2991. }
  2992. static
  2993. int tport_send_fatal(tport_t *self, msg_t *msg, tp_name_t const *tpn,
  2994. char const *who)
  2995. {
  2996. su_addrinfo_t *ai = msg_addrinfo(msg);
  2997. char const *comp = (ai->ai_flags & TP_AI_COMPRESSED) ? ";comp=sigcomp" : "";
  2998. int error = msg_errno(msg);
  2999. if (self->tp_addrinfo->ai_family == AF_INET) {
  3000. SU_DEBUG_3(("%s(%p): %s with (s=%d %s/%s:%s%s)\n",
  3001. who, (void *)self, su_strerror(error), (int)self->tp_socket,
  3002. tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp));
  3003. }
  3004. #if SU_HAVE_IN6
  3005. else if (self->tp_addrinfo->ai_family == AF_INET6) {
  3006. su_sockaddr_t const *su = (su_sockaddr_t const *)ai->ai_addr;
  3007. SU_DEBUG_3(("%s(%p): %s with (s=%d, IP6=%s/%s:%s%s"
  3008. " (scope=%i) addrlen=%u)\n",
  3009. who, (void *)self, su_strerror(error), (int)self->tp_socket,
  3010. tpn->tpn_proto, tpn->tpn_host, tpn->tpn_port, comp,
  3011. su->su_scope_id, (unsigned)ai->ai_addrlen));
  3012. }
  3013. #endif
  3014. else {
  3015. SU_DEBUG_3(("%s(%p): %s with (s=%d, AF=%u addrlen=%u)%s\n",
  3016. who, (void *)self, su_strerror(error),
  3017. (int)self->tp_socket, ai->ai_family, (unsigned)ai->ai_addrlen, comp));
  3018. }
  3019. #if 0
  3020. int i;
  3021. for (i = 0; i < iovused; i++)
  3022. SU_DEBUG_7(("\t\tiov[%d] = { %d bytes @ %p }\n",
  3023. i, iov[i].siv_len, (void *)iov[i].siv_base));
  3024. #endif
  3025. if (tport_is_connection_oriented(self)) {
  3026. tport_error_report(self, error, NULL);
  3027. if (tport_has_connection(self))
  3028. tport_close(self);
  3029. }
  3030. return -1;
  3031. }
  3032. static
  3033. int tport_queue_rest(tport_t *self,
  3034. msg_t *msg,
  3035. msg_iovec_t iov[],
  3036. size_t iovused)
  3037. {
  3038. size_t iovlen = self->tp_iovlen;
  3039. assert(tport_is_connection_oriented(self));
  3040. assert(self->tp_queue == NULL ||
  3041. self->tp_queue[self->tp_qhead] == NULL ||
  3042. self->tp_queue[self->tp_qhead] == msg);
  3043. if (tport_queue(self, msg) < 0)
  3044. return -1;
  3045. assert(self->tp_queue[self->tp_qhead] == msg);
  3046. if (self->tp_iov == NULL) {
  3047. if (iovlen < 40) iovlen = 40;
  3048. if (iovlen < iovused) iovlen = iovused;
  3049. self->tp_iov = su_alloc(self->tp_home, iovlen * sizeof(iov[0]));
  3050. self->tp_iovlen = iovlen;
  3051. if (!self->tp_iov) {
  3052. msg_set_errno(msg, errno);
  3053. return -1;
  3054. }
  3055. memcpy(self->tp_iov, iov, iovused * sizeof(iov[0]));
  3056. iov = self->tp_iov;
  3057. }
  3058. self->tp_unsent = iov;
  3059. self->tp_unsentlen = iovused;
  3060. /* the POLLOUT event is far too unreliable with SCTP */
  3061. if (self->tp_addrinfo->ai_protocol == IPPROTO_SCTP)
  3062. return 0;
  3063. /* Ask for a send event */
  3064. tport_set_events(self, SU_WAIT_OUT, 0);
  3065. return 0;
  3066. }
  3067. /** Queue a message to transport.
  3068. *
  3069. * The tport_tqueue() function queues a message in the send queue. It is
  3070. * used by an (server) application that is required to send (response)
  3071. * messages in certain order. For example, a HTTP server or proxy may
  3072. * receive multiple requests from a single TCP connection. The server is
  3073. * required to answer to the requests in same order as they are received.
  3074. * The responses are, however, sometimes generated asynchronously, that is,
  3075. * a response to a later request may be ready earlier. For that purpose, the
  3076. * HTTP protocol stack queues an empty response message immediately upon
  3077. * receiving a request. Other messages cannot be sent before the queued one.
  3078. *
  3079. * The function tport_tqsend() is used to send the completed response message.
  3080. *
  3081. * @param self pointer to transport object
  3082. * @param msg message to be inserted into queue
  3083. * @param tag,value,... tagged argument list
  3084. *
  3085. * @TAGS
  3086. * @par Currently none.
  3087. *
  3088. * @retval 0 when successful
  3089. * @retval -1 upon an error
  3090. * @ERRORS
  3091. * @ERROR EINVAL Invalid argument(s).
  3092. * @ERROR ENOMEM Memory was exhausted.
  3093. * @ERROR ENOBUFS The transport object queue was full.
  3094. *
  3095. * @deprecated Alternative interface will be provided in near future.
  3096. *
  3097. * @sa tport_tqsend()
  3098. */
  3099. int tport_tqueue(tport_t *self, msg_t *msg,
  3100. tag_type_t tag, tag_value_t value, ...)
  3101. {
  3102. msg_unprepare(msg);
  3103. return tport_queue(self, msg);
  3104. }
  3105. /** Return number of queued messages. */
  3106. isize_t tport_queuelen(tport_t const *self)
  3107. {
  3108. isize_t retval = 0;
  3109. if (self && self->tp_queue) {
  3110. unsigned short i, N = self->tp_params->tpp_qsize;
  3111. for (i = self->tp_qhead; self->tp_queue[i] && retval < N; i = (i + 1) % N)
  3112. retval++;
  3113. }
  3114. return retval;
  3115. }
  3116. static
  3117. int tport_queue(tport_t *self, msg_t *msg)
  3118. {
  3119. unsigned short qhead = self->tp_qhead;
  3120. unsigned short N = self->tp_params->tpp_qsize;
  3121. SU_DEBUG_7(("tport_queue(%p): queueing %p for %s/%s:%s\n",
  3122. (void *)self, (void *)msg,
  3123. self->tp_protoname, self->tp_host, self->tp_port));
  3124. if (self->tp_queue == NULL) {
  3125. assert(N > 0);
  3126. assert(qhead == 0);
  3127. self->tp_queue = su_zalloc(self->tp_home, N * sizeof(msg));
  3128. if (!self->tp_queue) {
  3129. msg_set_errno(msg, errno);
  3130. return -1;
  3131. }
  3132. }
  3133. if (self->tp_queue[qhead] == msg)
  3134. return 0;
  3135. while (self->tp_queue[qhead]) {
  3136. qhead = (qhead + 1) % N;
  3137. if (qhead == self->tp_qhead) {
  3138. msg_set_errno(msg, ENOBUFS);
  3139. return -1;
  3140. }
  3141. }
  3142. self->tp_queue[qhead] = msg_ref_create(msg);
  3143. return 0;
  3144. }
  3145. /** Send a queued message (and queue another, if required).
  3146. *
  3147. * The function tport_tqsend() sends a message to the transport.
  3148. *
  3149. * @deprecated Alternative interface will be provided in near future.
  3150. */
  3151. int tport_tqsend(tport_t *self, msg_t *msg, msg_t *next,
  3152. tag_type_t tag, tag_value_t value, ...)
  3153. {
  3154. unsigned short qhead;
  3155. ta_list ta;
  3156. int reuse, sdwn_after, close_after;
  3157. unsigned short N;
  3158. su_addrinfo_t *ai;
  3159. if (self == NULL)
  3160. return -1;
  3161. qhead = self->tp_qhead;
  3162. N = self->tp_params->tpp_qsize;
  3163. reuse = self->tp_reusable;
  3164. sdwn_after = 0;
  3165. close_after = 0;
  3166. ta_start(ta, tag, value);
  3167. tl_gets(ta_args(ta),
  3168. TPTAG_REUSE_REF(reuse),
  3169. TPTAG_SDWN_AFTER_REF(sdwn_after),
  3170. TPTAG_CLOSE_AFTER_REF(close_after),
  3171. TAG_END());
  3172. ta_end(ta);
  3173. /* If "next", make sure we can queue it */
  3174. if (next && self->tp_queue[qhead == 0 ? N - 1 : qhead - 1]) {
  3175. msg_set_errno(next, ENOBUFS);
  3176. return -1;
  3177. }
  3178. /* Prepare message for sending - i.e., encode it */
  3179. if (msg_prepare(msg) < 0) {
  3180. msg_set_errno(msg, errno);
  3181. return -1;
  3182. }
  3183. tport_peer_address(self, msg); /* Set addrinfo */
  3184. if (next == NULL) {
  3185. ai = msg_addrinfo(msg);
  3186. if (sdwn_after)
  3187. ai->ai_flags |= TP_AI_SHUTDOWN;
  3188. if (close_after)
  3189. ai->ai_flags |= TP_AI_CLOSE;
  3190. if (self->tp_queue[qhead] == msg) {
  3191. tport_send_queue(self);
  3192. tport_set_secondary_timer(self);
  3193. }
  3194. return 0;
  3195. }
  3196. ai = msg_addrinfo(next);
  3197. if (sdwn_after)
  3198. ai->ai_flags |= TP_AI_SHUTDOWN;
  3199. if (close_after)
  3200. ai->ai_flags |= TP_AI_CLOSE;
  3201. if (self->tp_queue[qhead] == msg) {
  3202. /* XXX - what about errors? */
  3203. tport_send_msg(self, msg, self->tp_name, NULL);
  3204. tport_set_secondary_timer(self);
  3205. if (!self->tp_unsent) {
  3206. msg_destroy(self->tp_queue[qhead]);
  3207. if ((self->tp_queue[qhead] = msg_ref_create(next)))
  3208. msg_unprepare(next);
  3209. return 0;
  3210. }
  3211. }
  3212. while (self->tp_queue[qhead] && self->tp_queue[qhead] != msg) {
  3213. qhead = (qhead + 1) % N;
  3214. if (qhead == self->tp_qhead)
  3215. break;
  3216. }
  3217. if (self->tp_queue[qhead] != msg) {
  3218. msg_set_errno(next, EINVAL);
  3219. return -1;
  3220. }
  3221. msg = msg_ref_create(next);
  3222. do {
  3223. qhead = (qhead + 1) % N;
  3224. next = self->tp_queue[qhead]; self->tp_queue[qhead] = msg; msg = next;
  3225. /* Above we made sure that there is an empty slot */
  3226. assert(!next || qhead != self->tp_qhead);
  3227. } while (next);
  3228. return 0;
  3229. }
  3230. /** Send event.
  3231. *
  3232. * Process SU_WAIT_OUT event.
  3233. */
  3234. void tport_send_event(tport_t *self)
  3235. {
  3236. assert(tport_is_connection_oriented(self));
  3237. SU_DEBUG_7(("tport_send_event(%p) - ready to send to (%s/%s:%s)\n",
  3238. (void *)self, self->tp_protoname, self->tp_host, self->tp_port));
  3239. tport_send_queue(self);
  3240. tport_set_secondary_timer(self);
  3241. }
  3242. /** Send queued messages */
  3243. void tport_send_queue(tport_t *self)
  3244. {
  3245. msg_t *msg;
  3246. msg_iovec_t *iov;
  3247. size_t i, iovused, n, total;
  3248. unsigned short qhead = self->tp_qhead, N = self->tp_params->tpp_qsize;
  3249. assert(self->tp_queue && self->tp_queue[qhead]);
  3250. msg = self->tp_queue[qhead];
  3251. iov = self->tp_unsent, self->tp_unsent = NULL;
  3252. iovused = self->tp_unsentlen, self->tp_unsentlen = 0;
  3253. if (iov && iovused) {
  3254. ssize_t e;
  3255. self->tp_stime = self->tp_ktime = su_now();
  3256. e = tport_vsend(self, msg, self->tp_name, iov, iovused, NULL);
  3257. if (e == -1) /* XXX */
  3258. return;
  3259. n = (size_t)e;
  3260. if (n > 0 && self->tp_master->mr_log && self->tp_slogged != msg) {
  3261. tport_log_msg(self, msg, "send", "to", self->tp_stime);
  3262. self->tp_slogged = msg;
  3263. }
  3264. for (i = 0, total = 0; i < iovused; i++) {
  3265. if (total + (size_t)iov[i].mv_len > n) {
  3266. iov[i].mv_len -= (su_ioveclen_t)(n - total);
  3267. iov[i].mv_base = (char *)iov[i].mv_base + (n - total);
  3268. self->tp_unsent = iov + i;
  3269. self->tp_unsentlen = iovused - i;
  3270. return;
  3271. }
  3272. total += iov[i].mv_len;
  3273. }
  3274. assert(total == n);
  3275. /* We have sent a complete message */
  3276. self->tp_queue[qhead] = NULL;
  3277. tport_sent_message(self, msg, 0);
  3278. msg_destroy(msg);
  3279. qhead = (qhead + 1) % N;
  3280. }
  3281. while (msg_is_prepared(msg = self->tp_queue[self->tp_qhead = qhead])) {
  3282. /* XXX - what about errors? */
  3283. tport_send_msg(self, msg, self->tp_name, NULL);
  3284. if (self->tp_unsent)
  3285. return;
  3286. msg = self->tp_queue[qhead]; /* tport_send_msg() may flush queue! */
  3287. self->tp_queue[qhead] = NULL;
  3288. msg_destroy(msg);
  3289. qhead = (qhead + 1) % N;
  3290. }
  3291. /* No more send event(s)? */
  3292. tport_set_events(self, 0, SU_WAIT_OUT);
  3293. }
  3294. static int msg_select_addrinfo(msg_t *msg, su_addrinfo_t *res);
  3295. static int
  3296. tport_resolve(tport_t *self, msg_t *msg, tp_name_t const *tpn)
  3297. {
  3298. int error;
  3299. char ipaddr[TPORT_HOSTPORTSIZE];
  3300. su_addrinfo_t *res, hints[1] = {{ 0 }};
  3301. char const *host;
  3302. su_sockaddr_t *su;
  3303. hints->ai_socktype = self->tp_addrinfo->ai_socktype;
  3304. hints->ai_protocol = self->tp_addrinfo->ai_protocol;
  3305. if (host_is_ip6_reference(tpn->tpn_host)) {
  3306. /* Remove [] around IPv6 address */
  3307. size_t len = strlen(tpn->tpn_host);
  3308. assert(len < sizeof ipaddr);
  3309. host = memcpy(ipaddr, tpn->tpn_host + 1, len - 2);
  3310. ipaddr[len - 2] = '\0';
  3311. hints->ai_flags |= AI_NUMERICHOST;
  3312. }
  3313. else {
  3314. #if HAVE_OPEN_C
  3315. if (host_is_ip_address(tpn->tpn_host))
  3316. hints->ai_flags |= AI_NUMERICHOST;
  3317. #endif
  3318. host = tpn->tpn_host;
  3319. }
  3320. if ((error = su_getaddrinfo(host, tpn->tpn_port, hints, &res))) {
  3321. SU_DEBUG_3(("tport_resolve: getaddrinfo(\"%s\":%s): %s\n",
  3322. tpn->tpn_host, tpn->tpn_port,
  3323. su_gai_strerror(error)));
  3324. msg_set_errno(msg, ENXIO);
  3325. return -1;
  3326. }
  3327. error = msg_select_addrinfo(msg, res);
  3328. su = (su_sockaddr_t *) msg_addrinfo(msg)->ai_addr;
  3329. #if SU_HAVE_IN6
  3330. SU_DEBUG_9(("tport_resolve addrinfo = %s%s%s:%d\n",
  3331. su->su_family == AF_INET6 ? "[" : "",
  3332. su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr)),
  3333. su->su_family == AF_INET6 ? "]" : "",
  3334. htons(su->su_port)));
  3335. #else
  3336. SU_DEBUG_9(("tport_resolve addrinfo = %s%s%s:%d\n",
  3337. "",
  3338. su_inet_ntop(su->su_family, SU_ADDR(su), ipaddr, sizeof(ipaddr)),
  3339. "",
  3340. htons(su->su_port)));
  3341. #endif
  3342. su_freeaddrinfo(res);
  3343. return error;
  3344. }
  3345. static int
  3346. msg_select_addrinfo(msg_t *msg, su_addrinfo_t *res)
  3347. {
  3348. su_addrinfo_t *ai, *mai = msg_addrinfo(msg);
  3349. su_sockaddr_t *su = (su_sockaddr_t *)mai->ai_addr;
  3350. for (ai = res; ai; ai = ai->ai_next) {
  3351. #if SU_HAVE_IN6
  3352. if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
  3353. continue;
  3354. #else
  3355. if (ai->ai_family != AF_INET)
  3356. continue;
  3357. #endif
  3358. if (ai->ai_protocol == 0)
  3359. continue;
  3360. if (ai->ai_addrlen > sizeof(su_sockaddr_t))
  3361. continue;
  3362. mai->ai_family = ai->ai_family;
  3363. mai->ai_socktype = ai->ai_socktype;
  3364. mai->ai_protocol = ai->ai_protocol;
  3365. if (ai->ai_addrlen < sizeof(su_sockaddr_t))
  3366. memset(su, 0, sizeof(su_sockaddr_t));
  3367. memcpy(su, ai->ai_addr, ai->ai_addrlen);
  3368. if (su_sockaddr_size(su))
  3369. mai->ai_addrlen = su_sockaddr_size(su);
  3370. else
  3371. mai->ai_addrlen = ai->ai_addrlen;
  3372. return 0;
  3373. }
  3374. msg_set_errno(msg, EAFNOSUPPORT);
  3375. return -1;
  3376. }
  3377. /** Copy peer address to msg */
  3378. void
  3379. tport_peer_address(tport_t *self, msg_t *msg)
  3380. {
  3381. su_addrinfo_t *mai = msg_addrinfo(msg);
  3382. su_addrinfo_t const *tai = self->tp_addrinfo;
  3383. void *maddr = mai->ai_addr;
  3384. int flags = mai->ai_flags;
  3385. memcpy(mai, tai, sizeof *mai);
  3386. mai->ai_addr = memcpy(maddr, tai->ai_addr, tai->ai_addrlen);
  3387. mai->ai_flags = flags;
  3388. }
  3389. /** Process error event.
  3390. *
  3391. * Return events that can be processed afterwards.
  3392. */
  3393. int tport_error_event(tport_t *self)
  3394. {
  3395. int errcode;
  3396. su_sockaddr_t name[1] = {{ 0 }};
  3397. name->su_family = AF_UNSPEC; /* 0 */
  3398. if (tport_is_udp(self)) {
  3399. errcode = tport_udp_error(self, name);
  3400. }
  3401. else {
  3402. /* Process error event for basic transport. */
  3403. errcode = su_soerror(self->tp_socket);
  3404. }
  3405. if (errcode == 0 || errcode == EPIPE)
  3406. return errcode;
  3407. tport_error_report(self, errcode, name);
  3408. return 0;
  3409. }
  3410. /** Mark message as waiting for a response.
  3411. *
  3412. * @return Positive integer, or -1 upon an error.
  3413. */
  3414. int tport_pend(tport_t *self,
  3415. msg_t *msg,
  3416. tport_pending_error_f *callback,
  3417. tp_client_t *client)
  3418. {
  3419. tport_pending_t *pending;
  3420. if (self == NULL || callback == NULL)
  3421. return -1;
  3422. if (msg == NULL && tport_is_primary(self))
  3423. return -1;
  3424. SU_DEBUG_7(("tport_pend(%p): pending %p for %s/%s:%s (already %u)\n",
  3425. (void *)self, (void *)msg,
  3426. self->tp_protoname, self->tp_host, self->tp_port,
  3427. self->tp_pused));
  3428. if (self->tp_released == NULL) {
  3429. unsigned i, len = 8;
  3430. if (self->tp_plen)
  3431. len = 2 * self->tp_plen;
  3432. pending = su_realloc(self->tp_home,
  3433. self->tp_pending, len * sizeof(*pending));
  3434. if (!pending) {
  3435. msg_set_errno(msg, errno);
  3436. return -1;
  3437. }
  3438. memset(pending + self->tp_plen, 0, (len - self->tp_plen) * sizeof(*pending));
  3439. for (i = self->tp_plen; i + 1 < len; i++)
  3440. pending[i].p_client = pending + i + 1;
  3441. self->tp_released = pending + self->tp_plen;
  3442. self->tp_pending = pending;
  3443. self->tp_plen = len;
  3444. }
  3445. pending = self->tp_released;
  3446. self->tp_released = pending->p_client;
  3447. pending->p_callback = callback;
  3448. pending->p_client = client;
  3449. pending->p_msg = msg;
  3450. pending->p_reported = self->tp_reported;
  3451. self->tp_pused++;
  3452. return (pending - self->tp_pending) + 1;
  3453. }
  3454. /** Mark message as no more pending */
  3455. int tport_release(tport_t *self,
  3456. int pendd,
  3457. msg_t *msg,
  3458. msg_t *reply,
  3459. tp_client_t *client,
  3460. int still_pending)
  3461. {
  3462. tport_pending_t *pending;
  3463. if (self == NULL || pendd <= 0 || pendd > (int)self->tp_plen)
  3464. return su_seterrno(EINVAL), -1;
  3465. pending = self->tp_pending + (pendd - 1);
  3466. if (pending->p_client != client ||
  3467. pending->p_msg != msg) {
  3468. SU_DEBUG_1(("%s(%p): %u %p by %p not pending\n",
  3469. __func__, (void *)self,
  3470. pendd, (void *)msg, (void *)client));
  3471. return su_seterrno(EINVAL), -1;
  3472. }
  3473. SU_DEBUG_7(("%s(%p): %p by %p with %p%s\n",
  3474. __func__, (void *)self,
  3475. (void *)msg, (void *)client, (void *)reply,
  3476. still_pending ? " (preliminary)" : ""));
  3477. /* sigcomp can here associate request (msg) with response (reply) */
  3478. if (still_pending)
  3479. return 0;
  3480. /* Just to make sure nobody uses stale data */
  3481. memset(pending, 0, sizeof(*pending));
  3482. pending->p_client = self->tp_released;
  3483. self->tp_released = pending;
  3484. self->tp_pused--;
  3485. return 0;
  3486. }
  3487. /** Report error to pending messages with destination */
  3488. int
  3489. tport_pending_error(tport_t *self, su_sockaddr_t const *dst, int error)
  3490. {
  3491. unsigned i, reported, callbacks;
  3492. tport_pending_t *pending;
  3493. msg_t *msg;
  3494. su_addrinfo_t const *ai;
  3495. assert(self);
  3496. callbacks = 0;
  3497. reported = ++self->tp_reported;
  3498. if (self->tp_pused == 0)
  3499. return 0;
  3500. for (i = 0; i < self->tp_plen; i++) {
  3501. pending = self->tp_pending + i;
  3502. if (!pending->p_callback)
  3503. continue;
  3504. if (pending->p_reported == reported)
  3505. continue;
  3506. msg = pending->p_msg;
  3507. if (dst && msg) {
  3508. ai = msg_addrinfo(msg);
  3509. if (su_cmp_sockaddr(dst, (su_sockaddr_t *)ai->ai_addr) != 0)
  3510. continue;
  3511. }
  3512. msg_set_errno(msg, error);
  3513. pending->p_reported = reported;
  3514. pending->p_callback(self->TP_STACK, pending->p_client, self, msg, error);
  3515. callbacks++;
  3516. }
  3517. return callbacks;
  3518. }
  3519. /** Report error via pending message */
  3520. int
  3521. tport_pending_errmsg(tport_t *self, msg_t *msg, int error)
  3522. {
  3523. unsigned i, reported, callbacks;
  3524. tport_pending_t *pending;
  3525. assert(self); assert(msg);
  3526. callbacks = 0;
  3527. reported = ++self->tp_reported;
  3528. msg_set_errno(msg, error);
  3529. if (self->tp_pused == 0)
  3530. return 0;
  3531. for (i = 0; i < self->tp_plen; i++) {
  3532. pending = self->tp_pending + i;
  3533. if (!pending->p_client ||
  3534. pending->p_msg != msg ||
  3535. pending->p_reported == reported)
  3536. continue;
  3537. pending->p_reported = reported;
  3538. pending->p_callback(self->TP_STACK, pending->p_client, self, msg, error);
  3539. callbacks++;
  3540. }
  3541. return callbacks;
  3542. }
  3543. /** Set transport magic. */
  3544. void tport_set_magic(tport_t *self, tp_magic_t *magic)
  3545. {
  3546. self->tp_magic = magic;
  3547. }
  3548. /** Get transport magic. */
  3549. tp_magic_t *tport_magic(tport_t const *self)
  3550. {
  3551. return self ? self->tp_magic : NULL;
  3552. }
  3553. /** Get primary transport (or self, if primary) */
  3554. tport_t *tport_parent(tport_t const *self)
  3555. {
  3556. return self ? self->tp_pri->pri_primary : NULL;
  3557. }
  3558. /** Get list of primary transports */
  3559. tport_t *tport_primaries(tport_t const *self)
  3560. {
  3561. if (self)
  3562. return self->tp_master->mr_primaries->pri_primary;
  3563. else
  3564. return NULL;
  3565. }
  3566. /** Get next transport */
  3567. tport_t *tport_next(tport_t const *self)
  3568. {
  3569. if (self == NULL)
  3570. return NULL;
  3571. else if (tport_is_master(self))
  3572. return ((tport_master_t *)self)->mr_primaries->pri_primary;
  3573. else if (tport_is_primary(self))
  3574. return ((tport_primary_t *)self)->pri_next->pri_primary;
  3575. else
  3576. return tprb_succ(self);
  3577. }
  3578. /** Get secondary transports. */
  3579. tport_t *tport_secondary(tport_t const *self)
  3580. {
  3581. if (tport_is_primary(self))
  3582. return self->tp_pri->pri_open;
  3583. else
  3584. return NULL;
  3585. }
  3586. #if 0
  3587. void tport_hints(tport_t const *self, su_addrinfo_t *hints)
  3588. {
  3589. hints->ai_protocol = self->tp_addrinfo->ai_protocol;
  3590. hints->ai_socktype = self->tp_addrinfo->ai_socktype;
  3591. }
  3592. #endif
  3593. /** Get transport address list. */
  3594. su_addrinfo_t const *tport_get_address(tport_t const *self)
  3595. {
  3596. return self ? self->tp_addrinfo : NULL;
  3597. }
  3598. /** Get transport name. */
  3599. tp_name_t const *tport_name(tport_t const *self)
  3600. {
  3601. return self->tp_name;
  3602. }
  3603. /** Get transport identifier. */
  3604. char const *tport_ident(tport_t const *self)
  3605. {
  3606. return self ? self->tp_ident : NULL;
  3607. }
  3608. /** Get transport by protocol name. */
  3609. tport_t *tport_by_protocol(tport_t const *self, char const *proto)
  3610. {
  3611. if (proto && strcmp(proto, tpn_any) != 0) {
  3612. for (; self; self = tport_next(self))
  3613. if (su_casematch(proto, self->tp_protoname))
  3614. break;
  3615. }
  3616. return (tport_t *)self;
  3617. }
  3618. /** Get transport by protocol name. */
  3619. tport_t *tport_primary_by_name(tport_t const *tp, tp_name_t const *tpn)
  3620. {
  3621. char const *ident = tpn->tpn_ident;
  3622. char const *proto = tpn->tpn_proto;
  3623. char const *comp = tpn->tpn_comp;
  3624. int family = 0;
  3625. tport_primary_t const *self, *nocomp = NULL;
  3626. self = tp ? tp->tp_master->mr_primaries : NULL;
  3627. if (ident && strcmp(ident, tpn_any) == 0)
  3628. ident = NULL;
  3629. if (tpn->tpn_host == NULL)
  3630. family = 0;
  3631. #if SU_HAVE_IN6
  3632. else if (host_is_ip6_address(tpn->tpn_host))
  3633. family = AF_INET6;
  3634. #endif
  3635. else if (host_is_ip4_address(tpn->tpn_host))
  3636. family = AF_INET;
  3637. else
  3638. family = 0;
  3639. if (proto && strcmp(proto, tpn_any) == 0)
  3640. proto = NULL;
  3641. if (!ident && !proto && !family && !comp)
  3642. return (tport_t *)self; /* Anything goes */
  3643. comp = tport_canonize_comp(comp);
  3644. for (; self; self = self->pri_next) {
  3645. tp = self->pri_primary;
  3646. if (ident && strcmp(ident, tp->tp_ident))
  3647. continue;
  3648. if (family) {
  3649. if (family == AF_INET && !tport_has_ip4(tp))
  3650. continue;
  3651. #if SU_HAVE_IN6
  3652. if (family == AF_INET6 && !tport_has_ip6(tp))
  3653. continue;
  3654. #endif
  3655. }
  3656. if (proto && !su_casematch(proto, tp->tp_protoname))
  3657. continue;
  3658. if (comp && comp != tp->tp_name->tpn_comp) {
  3659. if (tp->tp_name->tpn_comp == NULL && nocomp == NULL)
  3660. nocomp = self;
  3661. continue;
  3662. }
  3663. break;
  3664. }
  3665. if (self)
  3666. return (tport_t *)self;
  3667. else
  3668. return (tport_t *)nocomp;
  3669. }
  3670. /** Get transport by name. */
  3671. tport_t *tport_by_name(tport_t const *self, tp_name_t const *tpn)
  3672. {
  3673. tport_t const *sub, *next;
  3674. char const *canon, *host, *port, *comp;
  3675. #if SU_HAVE_IN6
  3676. char *end, ipaddr[TPORT_HOSTPORTSIZE];
  3677. #endif
  3678. assert(self); assert(tpn);
  3679. assert(tpn->tpn_proto); assert(tpn->tpn_host); assert(tpn->tpn_port);
  3680. assert(tpn->tpn_canon);
  3681. if (!tport_is_primary(self))
  3682. self = tport_primary_by_name(self, tpn);
  3683. host = strcmp(tpn->tpn_host, tpn_any) ? tpn->tpn_host : NULL;
  3684. port = strcmp(tpn->tpn_port, tpn_any) ? tpn->tpn_port : NULL;
  3685. canon = tpn->tpn_canon;
  3686. comp = tport_canonize_comp(tpn->tpn_comp);
  3687. if (self && host && port) {
  3688. int resolved = 0, cmp;
  3689. socklen_t sulen;
  3690. su_sockaddr_t su[1];
  3691. sub = self->tp_pri->pri_open;
  3692. memset(su, 0, sizeof su);
  3693. #if SU_HAVE_IN6
  3694. if (host_is_ip6_reference(host)) {
  3695. /* Remove [] around IPv6 address */
  3696. host = strncpy(ipaddr, host + 1, sizeof(ipaddr) - 1);
  3697. ipaddr[sizeof(ipaddr) - 1] = '\0';
  3698. if ((end = strchr(host, ']')))
  3699. *end = 0;
  3700. su->su_len = sulen = (socklen_t) sizeof (struct sockaddr_in6);
  3701. su->su_family = AF_INET6;
  3702. }
  3703. else if (host_is_ip6_address(host)) {
  3704. su->su_len = sulen = (socklen_t) sizeof (struct sockaddr_in6);
  3705. su->su_family = AF_INET6;
  3706. }
  3707. else
  3708. #endif
  3709. {
  3710. su->su_len = sulen = (socklen_t) sizeof (struct sockaddr_in);
  3711. su->su_family = AF_INET;
  3712. }
  3713. su->su_port = htons(strtoul(port, NULL, 10));
  3714. if (su_inet_pton(su->su_family, host, SU_ADDR(su)) > 0) {
  3715. resolved = 1;
  3716. next = NULL;
  3717. /* Depth-first search */
  3718. while (sub) {
  3719. cmp = (int)((size_t)sub->tp_addrlen - (size_t)sulen);
  3720. if (cmp == 0)
  3721. cmp = memcmp(sub->tp_addr, su, sulen);
  3722. if (cmp == 0) {
  3723. if (sub->tp_left) {
  3724. next = sub;
  3725. sub = sub->tp_left;
  3726. continue;
  3727. }
  3728. break;
  3729. }
  3730. else if (next) {
  3731. sub = next;
  3732. break;
  3733. }
  3734. else if (cmp > 0) {
  3735. sub = sub->tp_left;
  3736. continue;
  3737. }
  3738. else /* if (cmp < 0) */ {
  3739. sub = sub->tp_right;
  3740. continue;
  3741. }
  3742. }
  3743. }
  3744. else {
  3745. SU_DEBUG_7(("tport(%p): EXPENSIVE unresolved " TPN_FORMAT "\n",
  3746. (void *)self, TPN_ARGS(tpn)));
  3747. sub = tprb_first(sub);
  3748. }
  3749. for (; sub; sub = tprb_succ(sub)) {
  3750. if (!sub->tp_reusable)
  3751. continue;
  3752. if (!tport_is_registered(sub))
  3753. continue;
  3754. if (tport_is_shutdown(sub))
  3755. continue;
  3756. if (comp != sub->tp_name->tpn_comp)
  3757. continue;
  3758. if (resolved) {
  3759. if ((socklen_t)sub->tp_addrlen != sulen ||
  3760. memcmp(sub->tp_addr, su, sulen)) {
  3761. SU_DEBUG_7(("tport(%p): not found by name " TPN_FORMAT "\n",
  3762. (void *)self, TPN_ARGS(tpn)));
  3763. break;
  3764. }
  3765. SU_DEBUG_7(("tport(%p): found %p by name " TPN_FORMAT "\n",
  3766. (void *)self, (void *)sub, TPN_ARGS(tpn)));
  3767. }
  3768. else if (!su_casematch(port, sub->tp_port))
  3769. continue;
  3770. else if (!su_casematch(canon, sub->tp_canon) &&
  3771. !su_casematch(host, sub->tp_host))
  3772. continue;
  3773. return (tport_t *)sub;
  3774. }
  3775. }
  3776. return (tport_t *)self;
  3777. }
  3778. /** Get transport from primary by addrinfo. */
  3779. tport_t *tport_by_addrinfo(tport_primary_t const *pri,
  3780. su_addrinfo_t const *ai,
  3781. tp_name_t const *tpn)
  3782. {
  3783. tport_t const *sub, *maybe;
  3784. struct sockaddr const *sa;
  3785. int cmp;
  3786. char const *comp;
  3787. assert(pri); assert(ai);
  3788. sa = ai->ai_addr;
  3789. sub = pri->pri_open, maybe = NULL;
  3790. comp = tport_canonize_comp(tpn->tpn_comp);
  3791. /* Find leftmost (prevmost) matching tport */
  3792. while (sub) {
  3793. cmp = (int)(sub->tp_addrlen - ai->ai_addrlen);
  3794. if (cmp == 0)
  3795. cmp = memcmp(sub->tp_addr, sa, ai->ai_addrlen);
  3796. if (cmp == 0) {
  3797. if (sub->tp_left) {
  3798. maybe = sub;
  3799. sub = sub->tp_left;
  3800. continue;
  3801. }
  3802. break;
  3803. }
  3804. else if (maybe) {
  3805. sub = maybe;
  3806. break;
  3807. }
  3808. else if (cmp > 0) {
  3809. sub = sub->tp_left;
  3810. continue;
  3811. }
  3812. else /* if (cmp < 0) */ {
  3813. sub = sub->tp_right;
  3814. continue;
  3815. }
  3816. }
  3817. for (; sub; sub = tprb_succ(sub)) {
  3818. if (!sub->tp_reusable)
  3819. continue;
  3820. if (!tport_is_registered(sub))
  3821. continue;
  3822. if (tport_is_shutdown(sub))
  3823. continue;
  3824. if (tport_has_tls(sub) && !su_casematch(tpn->tpn_canon, sub->tp_name->tpn_canon)) {
  3825. if (!tport_is_verified(sub))
  3826. continue;
  3827. if (!tport_subject_search(tpn->tpn_canon, sub->tp_subjects))
  3828. continue;
  3829. }
  3830. if (comp != sub->tp_name->tpn_comp)
  3831. continue;
  3832. if (sub->tp_addrlen != ai->ai_addrlen
  3833. || memcmp(sub->tp_addr, sa, ai->ai_addrlen)) {
  3834. sub = NULL;
  3835. break;
  3836. }
  3837. break;
  3838. }
  3839. if (sub)
  3840. SU_DEBUG_7(("%s(%p): found %p by name " TPN_FORMAT "\n",
  3841. __func__, (void *)pri, (void *)sub, TPN_ARGS(tpn)));
  3842. else
  3843. SU_DEBUG_7(("%s(%p): not found by name " TPN_FORMAT "\n",
  3844. __func__, (void *)pri, TPN_ARGS(tpn)));
  3845. return (tport_t *)sub;
  3846. }
  3847. /** Get transport name from URL. */
  3848. int tport_name_by_url(su_home_t *home,
  3849. tp_name_t *tpn,
  3850. url_string_t const *us)
  3851. {
  3852. size_t n;
  3853. url_t url[1];
  3854. char *b;
  3855. n = url_xtra(us->us_url);
  3856. b = su_alloc(home, n);
  3857. if (b == NULL || url_dup(b, n, url, us->us_url) < 0) {
  3858. su_free(home, b);
  3859. return -1;
  3860. }
  3861. tpn->tpn_proto = url_tport_default((enum url_type_e)url->url_type);
  3862. tpn->tpn_canon = url->url_host;
  3863. tpn->tpn_host = url->url_host;
  3864. tpn->tpn_port = url_port(url);
  3865. if (tpn->tpn_host == NULL || tpn->tpn_host[0] == '\0' ||
  3866. tpn->tpn_port == NULL || tpn->tpn_port[0] == '\0') {
  3867. su_free(home, b);
  3868. return -1;
  3869. }
  3870. if (url->url_params) {
  3871. for (b = (char *)url->url_params; b[0]; b += n) {
  3872. n = strcspn(b, ";");
  3873. if (n > 10 && su_casenmatch(b, "transport=", 10))
  3874. tpn->tpn_proto = b + 10;
  3875. else if (n > 6 && su_casenmatch(b, "maddr=", 6))
  3876. tpn->tpn_host = b + 6;
  3877. if (b[n])
  3878. b[n++] = '\0';
  3879. }
  3880. }
  3881. return 0;
  3882. }
  3883. /** Check if transport named is already resolved */
  3884. int tport_name_is_resolved(tp_name_t const *tpn)
  3885. {
  3886. if (!tpn->tpn_host)
  3887. return 0;
  3888. return host_is_ip_address(tpn->tpn_host);
  3889. }
  3890. /** Duplicate name.
  3891. *
  3892. * The tport_name_dup() function copies strings belonging to the transport
  3893. * name. It returns the copied strings via the @a dst transport name
  3894. * structure. The memory block required for copies is allocated from the
  3895. * memory @a home. Please note that only one memory block is allocated, so
  3896. * the memory can be reclainmed only by deinitializing the memory home
  3897. * itself.
  3898. *
  3899. * @retval 0 when successful
  3900. * @retval -1 upon an error
  3901. */
  3902. int tport_name_dup(su_home_t *home,
  3903. tp_name_t *dst,
  3904. tp_name_t const *src)
  3905. {
  3906. size_t n_proto, n_host, n_port, n_canon, n_comp = 0;
  3907. char *s;
  3908. if (!src->tpn_proto || !src->tpn_host || !src->tpn_port || !src->tpn_canon)
  3909. return -1;
  3910. if (strcmp(src->tpn_proto, tpn_any))
  3911. n_proto = strlen(src->tpn_proto) + 1;
  3912. else
  3913. n_proto = 0;
  3914. n_host = strlen(src->tpn_host) + 1;
  3915. n_port = strlen(src->tpn_port) + 1;
  3916. if (src->tpn_comp != NULL)
  3917. n_comp = strlen(src->tpn_comp) + 1;
  3918. if (src->tpn_canon != src->tpn_host &&
  3919. strcmp(src->tpn_canon, src->tpn_host))
  3920. n_canon = strlen(src->tpn_canon) + 1;
  3921. else
  3922. n_canon = 0;
  3923. s = su_alloc(home, n_proto + n_canon + n_host + n_port + n_comp);
  3924. if (s == NULL)
  3925. return -1;
  3926. if (n_proto)
  3927. dst->tpn_proto = memcpy(s, src->tpn_proto, n_proto), s += n_proto;
  3928. else
  3929. dst->tpn_proto = tpn_any;
  3930. dst->tpn_host = memcpy(s, src->tpn_host, n_host), s += n_host;
  3931. dst->tpn_port = memcpy(s, src->tpn_port, n_port), s += n_port;
  3932. if (n_canon)
  3933. dst->tpn_canon = memcpy(s, src->tpn_canon, n_canon), s += n_canon;
  3934. else
  3935. dst->tpn_canon = dst->tpn_host;
  3936. if (n_comp)
  3937. dst->tpn_comp = memcpy(s, src->tpn_comp, n_comp);
  3938. else
  3939. dst->tpn_comp = NULL;
  3940. return 0;
  3941. }
  3942. /** Convert a sockaddr structure into printable form. */
  3943. char *tport_hostport(char buf[], isize_t bufsize,
  3944. su_sockaddr_t const *su,
  3945. int with_port_and_brackets)
  3946. {
  3947. char *b = buf;
  3948. size_t n;
  3949. #if SU_HAVE_IN6
  3950. if (with_port_and_brackets > 1 || su->su_family == AF_INET6) {
  3951. *b++ = '['; bufsize--;
  3952. }
  3953. #endif
  3954. if (su_inet_ntop(su->su_family, SU_ADDR(su), b, bufsize) == NULL)
  3955. return NULL;
  3956. n = strlen(b);
  3957. if (bufsize < n + 2)
  3958. return NULL;
  3959. bufsize -= n; b += n;
  3960. #if SU_HAVE_IN6
  3961. if (with_port_and_brackets > 1 || su->su_family == AF_INET6) {
  3962. *b++ = ']'; bufsize--;
  3963. }
  3964. if (with_port_and_brackets) {
  3965. unsigned short port = ntohs(su->su_port);
  3966. if (port != 0) {
  3967. n = snprintf(b, bufsize, ":%u", port);
  3968. if (n <= 0)
  3969. return NULL;
  3970. b += n;
  3971. if (bufsize > n)
  3972. bufsize -= n;
  3973. else
  3974. bufsize = 0;
  3975. }
  3976. }
  3977. #endif
  3978. if (bufsize)
  3979. *b++ = 0;
  3980. return buf;
  3981. }
  3982. /** @internal Update receive statistics. */
  3983. void tport_recv_bytes(tport_t *self, ssize_t bytes, ssize_t on_line)
  3984. {
  3985. self->tp_stats.recv_bytes += bytes;
  3986. self->tp_stats.recv_on_line += on_line;
  3987. if (self != self->tp_pri->pri_primary) {
  3988. self = self->tp_pri->pri_primary;
  3989. self->tp_stats.recv_bytes += bytes;
  3990. self->tp_stats.recv_on_line += on_line;
  3991. }
  3992. self = self->tp_master->mr_master;
  3993. self->tp_stats.recv_bytes += bytes;
  3994. self->tp_stats.recv_on_line += on_line;
  3995. }
  3996. /** @internal Update message-based receive statistics. */
  3997. void tport_recv_message(tport_t *self, msg_t *msg, int error)
  3998. {
  3999. error = error != 0;
  4000. self->tp_stats.recv_msgs++;
  4001. self->tp_stats.recv_errors += error;
  4002. if (self != self->tp_pri->pri_primary) {
  4003. self = self->tp_pri->pri_primary;
  4004. self->tp_stats.recv_msgs++;
  4005. self->tp_stats.recv_errors += error;
  4006. }
  4007. self = self->tp_master->mr_master;
  4008. self->tp_stats.recv_msgs++;
  4009. self->tp_stats.recv_errors += error;
  4010. }
  4011. /** @internal Update send statistics. */
  4012. void tport_sent_bytes(tport_t *self, ssize_t bytes, ssize_t on_line)
  4013. {
  4014. self->tp_stats.sent_bytes += bytes;
  4015. self->tp_stats.sent_on_line += on_line;
  4016. if (self != self->tp_pri->pri_primary) {
  4017. self = self->tp_pri->pri_primary;
  4018. self->tp_stats.sent_bytes += bytes;
  4019. self->tp_stats.sent_on_line += on_line;
  4020. }
  4021. self = self->tp_master->mr_master;
  4022. self->tp_stats.sent_bytes += bytes;
  4023. self->tp_stats.sent_on_line += on_line;
  4024. }
  4025. /** @internal Update message-based send statistics. */
  4026. void tport_sent_message(tport_t *self, msg_t *msg, int error)
  4027. {
  4028. self->tp_slogged = NULL;
  4029. error = error != 0;
  4030. self->tp_stats.sent_msgs++;
  4031. self->tp_stats.sent_errors += error;
  4032. if (self != self->tp_pri->pri_primary) {
  4033. self = self->tp_pri->pri_primary;
  4034. self->tp_stats.sent_msgs++;
  4035. self->tp_stats.sent_errors += error;
  4036. }
  4037. self = self->tp_master->mr_master;
  4038. self->tp_stats.sent_msgs++;
  4039. self->tp_stats.sent_errors += error;
  4040. }