dns_cache.c 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050
  1. /*
  2. * $Id$
  3. *
  4. * resolver related functions
  5. *
  6. * Copyright (C) 2006 iptelorg GmbH
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  28. */
  29. /* History:
  30. * --------
  31. * 2006-07-13 created by andrei
  32. * 2006-10-06 port fix (andrei)
  33. * 2007-06-14 dns iterate through A & AAAA records fix (andrei)
  34. * 2007-06-15 srv rr weight based load balancing support (andrei)
  35. * 2007-06-16 naptr support (andrei)
  36. * 2008-07-18 DNS watchdog support -- can be used to inform the core
  37. * that the DNS servers are down (Miklos)
  38. * 2008-07-25 various rpc commands to manipulate the content
  39. * of the cache (Miklos)
  40. * 2007-07-30 DNS cache measurements added (Gergo)
  41. * 2007-08-17 dns_cache_del_nonexp config option is introduced (Miklos)
  42. * 2008-02-04 DNS cache options are adapted for the configuration
  43. * framework (Miklos)
  44. * 2008-02-11 dns_cache_init cfg parameter is introduced (Miklos)
  45. * 2008-10-17 fixed srv continue with 0 hostname (when falling back to
  46. aaaa) (andrei)
  47. */
  48. #ifdef USE_DNS_CACHE
  49. #ifdef DNS_SRV_LB
  50. #include <stdlib.h> /* FIXME: rand() */
  51. #endif
  52. #include "globals.h"
  53. #include "cfg_core.h"
  54. #include "dns_cache.h"
  55. #include "dns_wrappers.h"
  56. #include "compiler_opt.h"
  57. #include "mem/shm_mem.h"
  58. #include "hashes.h"
  59. #include "clist.h"
  60. #include "locking.h"
  61. #include "atomic_ops.h"
  62. #include "ut.h"
  63. #include "timer.h"
  64. #include "timer_ticks.h"
  65. #include "error.h"
  66. #include "rpc.h"
  67. #include "rand/fastrand.h"
  68. #ifdef USE_DNS_CACHE_STATS
  69. #include "pt.h"
  70. #endif
  71. #define DNS_CACHE_DEBUG /* extra sanity checks and debugging */
  72. #ifndef MAX
  73. #define MAX(a,b) ( ((a)>(b))?(a):(b))
  74. #endif
  75. #define MAX_DNS_RECORDS 255 /* maximum dns records number received in a
  76. dns answer*/
  77. #define DNS_HASH_SIZE 1024 /* must be <= 65535 */
  78. #define DEFAULT_DNS_TIMER_INTERVAL 120 /* 2 min. */
  79. #define DNS_HE_MAX_ADDR 10 /* maxium addresses returne in a hostent struct */
  80. #define MAX_CNAME_CHAIN 10
  81. #define SPACE_FORMAT " " /* format of view output */
  82. int dns_cache_init=1; /* if 0, the DNS cache is not initialized at startup */
  83. static gen_lock_t* dns_hash_lock=0;
  84. static volatile unsigned int *dns_cache_mem_used=0; /* current mem. use */
  85. unsigned int dns_timer_interval=DEFAULT_DNS_TIMER_INTERVAL; /* in s */
  86. int dns_flags=0; /* default flags used for the dns_*resolvehost
  87. (compatibility wrappers) */
  88. #ifdef USE_DNS_CACHE_STATS
  89. struct t_dns_cache_stats* dns_cache_stats=0;
  90. #endif
  91. #define LOCK_DNS_HASH() lock_get(dns_hash_lock)
  92. #define UNLOCK_DNS_HASH() lock_release(dns_hash_lock)
  93. #define FIX_TTL(t) \
  94. (((t)<cfg_get(core, core_cfg, dns_cache_min_ttl))? \
  95. cfg_get(core, core_cfg, dns_cache_min_ttl): \
  96. (((t)>cfg_get(core, core_cfg, dns_cache_max_ttl))? \
  97. cfg_get(core, core_cfg, dns_cache_max_ttl): \
  98. (t)))
  99. struct dns_hash_head{
  100. struct dns_hash_entry* next;
  101. struct dns_hash_entry* prev;
  102. };
  103. #ifdef DNS_LU_LST
  104. struct dns_lu_lst* dns_last_used_lst=0;
  105. #endif
  106. static struct dns_hash_head* dns_hash=0;
  107. static struct timer_ln* dns_timer_h=0;
  108. #ifdef DNS_WATCHDOG_SUPPORT
  109. static atomic_t *dns_servers_up = NULL;
  110. #endif
  111. static const char* dns_str_errors[]={
  112. "no error",
  113. "no more records", /* not an error, but and end condition */
  114. "unknown error",
  115. "internal error",
  116. "bad SRV entry",
  117. "unresolvable SRV request",
  118. "bad A or AAAA entry",
  119. "unresolvable A or AAAA request",
  120. "invalid ip in A or AAAA record",
  121. "blacklisted ip",
  122. "name too long ", /* try again with a shorter name */
  123. "ip AF mismatch", /* address family mismatch */
  124. "unresolvable NAPTR request",
  125. "bug - critical error"
  126. };
  127. /* param: err (negative error number) */
  128. const char* dns_strerror(int err)
  129. {
  130. err=-err;
  131. if ((err>=0) && (err<sizeof(dns_str_errors)/sizeof(char*)))
  132. return dns_str_errors[err];
  133. return "bug -- bad error number";
  134. }
  135. /* "internal" only, don't use unless you really know waht you're doing */
  136. inline static void dns_destroy_entry(struct dns_hash_entry* e)
  137. {
  138. #ifdef DNS_CACHE_DEBUG
  139. memset(e, 0, e->total_size);
  140. #endif
  141. shm_free(e); /* nice having it in one block isn't it? :-) */
  142. }
  143. /* "internal" only, same as above, asumes shm_lock() held (tm optimization) */
  144. inline static void dns_destroy_entry_shm_unsafe(struct dns_hash_entry* e)
  145. {
  146. #ifdef DNS_CACHE_DEBUG
  147. memset(e, 0, e->total_size);
  148. #endif
  149. shm_free_unsafe(e); /* nice having it in one block isn't it? :-) */
  150. }
  151. /* dec. the internal refcnt and if 0 deletes the entry */
  152. void dns_hash_put(struct dns_hash_entry* e)
  153. {
  154. if(e && atomic_dec_and_test(&e->refcnt)){
  155. /* atomic_sub_long(dns_cache_total_used, e->total_size); */
  156. dns_destroy_entry(e);
  157. }
  158. }
  159. /* same as above but uses dns_destroy_unsafe (assumes shm_lock held -- tm
  160. * optimization) */
  161. void dns_hash_put_shm_unsafe(struct dns_hash_entry* e)
  162. {
  163. if(e && atomic_dec_and_test(&e->refcnt)){
  164. /* atomic_sub_long(dns_cache_total_used, e->total_size); */
  165. dns_destroy_entry_shm_unsafe(e);
  166. }
  167. }
  168. inline static int dns_cache_clean(unsigned int no, int expired_only);
  169. inline static int dns_cache_free_mem(unsigned int target, int expired_only);
  170. static ticks_t dns_timer(ticks_t ticks, struct timer_ln* tl, void* data)
  171. {
  172. #ifdef DNS_WATCHDOG_SUPPORT
  173. /* do not clean the hash table if the servers are down */
  174. if (atomic_get(dns_servers_up) == 0)
  175. return (ticks_t)(-1);
  176. #endif
  177. if (*dns_cache_mem_used>12*(cfg_get(core, core_cfg, dns_cache_max_mem)/16)){ /* ~ 75% used */
  178. dns_cache_free_mem(cfg_get(core, core_cfg, dns_cache_max_mem)/2, 1);
  179. }else{
  180. dns_cache_clean(-1, 1); /* all the table, only expired entries */
  181. /* TODO: better strategy? */
  182. }
  183. return (ticks_t)(-1);
  184. }
  185. void destroy_dns_cache()
  186. {
  187. if (dns_timer_h){
  188. timer_del(dns_timer_h);
  189. timer_free(dns_timer_h);
  190. dns_timer_h=0;
  191. }
  192. #ifdef DNS_WATCHDOG_SUPPORT
  193. if (dns_servers_up){
  194. shm_free(dns_servers_up);
  195. dns_servers_up=0;
  196. }
  197. #endif
  198. if (dns_hash_lock){
  199. lock_destroy(dns_hash_lock);
  200. lock_dealloc(dns_hash_lock);
  201. dns_hash_lock=0;
  202. }
  203. if (dns_hash){
  204. shm_free(dns_hash);
  205. dns_hash=0;
  206. }
  207. #ifdef DNS_LU_LST
  208. if (dns_last_used_lst){
  209. shm_free(dns_last_used_lst);
  210. dns_last_used_lst=0;
  211. }
  212. #endif
  213. #ifdef USE_DNS_CACHE_STATS
  214. if (dns_cache_stats)
  215. shm_free(dns_cache_stats);
  216. #endif
  217. if (dns_cache_mem_used){
  218. shm_free((void*)dns_cache_mem_used);
  219. dns_cache_mem_used=0;
  220. }
  221. }
  222. /* set the value of dns_flags */
  223. void fix_dns_flags(str *gname, str *name)
  224. {
  225. /* restore the original value of dns_cache_flags first
  226. * (DNS_IPV4_ONLY may have been set only because dns_try_ipv6
  227. * was disabled, and the flag must be cleared when
  228. * dns_try_ipv6 is enabled) (Miklos)
  229. */
  230. dns_flags = cfg_get(core, core_cfg, dns_cache_flags) & 7;
  231. if (cfg_get(core, core_cfg, dns_try_ipv6)==0){
  232. dns_flags|=DNS_IPV4_ONLY;
  233. }
  234. if (dns_flags & DNS_IPV4_ONLY){
  235. dns_flags&=~(DNS_IPV6_ONLY|DNS_IPV6_FIRST);
  236. }
  237. if (cfg_get(core, core_cfg, dns_srv_lb)){
  238. #ifdef DNS_SRV_LB
  239. dns_flags|=DNS_SRV_RR_LB;
  240. #else
  241. LOG(L_WARN, "WARNING: fix_dns_flags: SRV loadbalaning is set, but"
  242. " support for it is not compiled -- ignoring\n");
  243. #endif
  244. }
  245. if (cfg_get(core, core_cfg, dns_try_naptr)) {
  246. #ifndef USE_NAPTR
  247. LOG(L_WARN, "WARNING: fix_dns_flags: NAPTR support is enabled, but"
  248. " support for it is not compiled -- ignoring\n");
  249. #endif
  250. dns_flags|=DNS_TRY_NAPTR;
  251. }
  252. }
  253. /* fixup function for use_dns_failover
  254. * verifies that use_dns_cache is set to 1
  255. */
  256. int use_dns_failover_fixup(void *handle, str *gname, str *name, void **val)
  257. {
  258. if ((int)(long)(*val) && !cfg_get(core, handle, use_dns_cache)) {
  259. LOG(L_ERR, "ERROR: use_dns_failover_fixup(): "
  260. "DNS cache is turned off, failover cannot be enabled. "
  261. "(set use_dns_cache to 1)\n");
  262. return -1;
  263. }
  264. return 0;
  265. }
  266. /* fixup function for use_dns_cache
  267. * verifies that dns_cache_init is set to 1
  268. */
  269. int use_dns_cache_fixup(void *handle, str *gname, str *name, void **val)
  270. {
  271. if ((int)(long)(*val) && !dns_cache_init) {
  272. LOG(L_ERR, "ERROR: use_dns_cache_fixup(): "
  273. "DNS cache is turned off by dns_cache_init=0, "
  274. "it cannot be enabled runtime.\n");
  275. return -1;
  276. }
  277. if (((int)(long)(*val)==0) && cfg_get(core, handle, use_dns_failover)) {
  278. LOG(L_ERR, "ERROR: use_dns_failover_fixup(): "
  279. "DNS failover depends on use_dns_cache, set use_dns_failover "
  280. "to 0 before disabling the DNS cache\n");
  281. return -1;
  282. }
  283. return 0;
  284. }
  285. /* KByte to Byte conversion */
  286. int dns_cache_max_mem_fixup(void *handle, str *gname, str *name, void **val)
  287. {
  288. unsigned int u;
  289. u = ((unsigned int)(long)(*val))<<10;
  290. (*val) = (void *)(long)u;
  291. return 0;
  292. }
  293. int init_dns_cache()
  294. {
  295. int r;
  296. int ret;
  297. if (dns_cache_init==0) {
  298. /* the DNS cache is turned off */
  299. default_core_cfg.use_dns_cache=0;
  300. default_core_cfg.use_dns_failover=0;
  301. return 0;
  302. }
  303. ret=0;
  304. /* sanity check */
  305. if (E_DNS_CRITICAL>=sizeof(dns_str_errors)/sizeof(char*)){
  306. LOG(L_CRIT, "BUG: dns_cache_init: bad dns error table\n");
  307. ret=E_BUG;
  308. goto error;
  309. }
  310. dns_cache_mem_used=shm_malloc(sizeof(*dns_cache_mem_used));
  311. if (dns_cache_mem_used==0){
  312. ret=E_OUT_OF_MEM;
  313. goto error;
  314. }
  315. #ifdef DNS_LU_LST
  316. dns_last_used_lst=shm_malloc(sizeof(*dns_last_used_lst));
  317. if (dns_last_used_lst==0){
  318. ret=E_OUT_OF_MEM;
  319. goto error;
  320. }
  321. clist_init(dns_last_used_lst, next, prev);
  322. #endif
  323. dns_hash=shm_malloc(sizeof(struct dns_hash_head)*DNS_HASH_SIZE);
  324. if (dns_hash==0){
  325. ret=E_OUT_OF_MEM;
  326. goto error;
  327. }
  328. for (r=0; r<DNS_HASH_SIZE; r++)
  329. clist_init(&dns_hash[r], next, prev);
  330. dns_hash_lock=lock_alloc();
  331. if (dns_hash_lock==0){
  332. ret=E_OUT_OF_MEM;
  333. goto error;
  334. }
  335. if (lock_init(dns_hash_lock)==0){
  336. lock_dealloc(dns_hash_lock);
  337. dns_hash_lock=0;
  338. ret=-1;
  339. goto error;
  340. }
  341. #ifdef DNS_WATCHDOG_SUPPORT
  342. dns_servers_up=shm_malloc(sizeof(atomic_t));
  343. if (dns_servers_up==0){
  344. ret=E_OUT_OF_MEM;
  345. goto error;
  346. }
  347. atomic_set(dns_servers_up, 1);
  348. #endif
  349. /* fix options */
  350. default_core_cfg.dns_cache_max_mem<<=10; /* Kb */ /* TODO: test with 0 */
  351. if (default_core_cfg.use_dns_cache==0)
  352. default_core_cfg.use_dns_failover=0; /* cannot work w/o dns_cache support */
  353. /* fix flags */
  354. fix_dns_flags(NULL, NULL);
  355. dns_timer_h=timer_alloc();
  356. if (dns_timer_h==0){
  357. ret=E_OUT_OF_MEM;
  358. goto error;
  359. }
  360. if (dns_timer_interval){
  361. timer_init(dns_timer_h, dns_timer, 0, 0); /* "slow" timer */
  362. if (timer_add(dns_timer_h, S_TO_TICKS(dns_timer_interval))<0){
  363. LOG(L_CRIT, "BUG: dns_cache_init: failed to add the timer\n");
  364. timer_free(dns_timer_h);
  365. dns_timer_h=0;
  366. goto error;
  367. }
  368. }
  369. return 0;
  370. error:
  371. destroy_dns_cache();
  372. return ret;
  373. }
  374. #ifdef USE_DNS_CACHE_STATS
  375. int init_dns_cache_stats(int iproc_num)
  376. {
  377. /* do not initialize the stats array if the DNS cache will not be used */
  378. if (dns_cache_init==0) return 0;
  379. /* if it is already initialized */
  380. if (dns_cache_stats)
  381. shm_free(dns_cache_stats);
  382. dns_cache_stats=shm_malloc(sizeof(*dns_cache_stats) * iproc_num);
  383. if (dns_cache_stats==0){
  384. return E_OUT_OF_MEM;
  385. }
  386. memset(dns_cache_stats, 0, sizeof(*dns_cache_stats) * iproc_num);
  387. return 0;
  388. }
  389. #endif
  390. /* hash function, type is not used (obsolete)
  391. * params: char* s, int len, int type
  392. * returns the hash value
  393. */
  394. #define dns_hash_no(s, len, type) \
  395. (get_hash1_case_raw((s),(len)) % DNS_HASH_SIZE)
  396. #ifdef DNS_CACHE_DEBUG
  397. #define DEBUG_LU_LST
  398. #ifdef DEBUG_LU_LST
  399. #include <stdlib.h> /* abort() */
  400. #define check_lu_lst(l) ((((l)->next==(l)) || ((l)->prev==(l))) && \
  401. ((l)!=dns_last_used_lst))
  402. #define dbg_lu_lst(txt, l) \
  403. LOG(L_CRIT, "BUG: %s: crt(%p, %p, %p)," \
  404. " prev(%p, %p, %p), next(%p, %p, %p)\n", txt, \
  405. (l), (l)->next, (l)->prev, \
  406. (l)->prev, (l)->prev->next, (l)->prev->prev, \
  407. (l)->next, (l)->next->next, (l)->next->prev \
  408. )
  409. #define debug_lu_lst( txt, l) \
  410. do{ \
  411. if (check_lu_lst((l))){ \
  412. dbg_lu_lst(txt " crt:", (l)); \
  413. abort(); \
  414. } \
  415. if (check_lu_lst((l)->next)){ \
  416. dbg_lu_lst(txt " next:", (l)); \
  417. abort(); \
  418. } \
  419. if (check_lu_lst((l)->prev)){ \
  420. dbg_lu_lst(txt " prev:", (l)); \
  421. abort(); \
  422. } \
  423. }while(0)
  424. #endif
  425. #endif /* DNS_CACHE_DEBUG */
  426. /* must be called with the DNS_LOCK hold
  427. * remove and entry from the hash, dec. its refcnt and if not referenced
  428. * anymore deletes it */
  429. inline static void _dns_hash_remove(struct dns_hash_entry* e)
  430. {
  431. clist_rm(e, next, prev);
  432. #ifdef DNS_CACHE_DEBUG
  433. e->next=e->prev=0;
  434. #endif
  435. #ifdef DNS_LU_LST
  436. #ifdef DEBUG_LU_LST
  437. debug_lu_lst("_dns_hash_remove: pre rm:", &e->last_used_lst);
  438. #endif
  439. clist_rm(&e->last_used_lst, next, prev);
  440. #ifdef DEBUG_LU_LST
  441. debug_lu_lst("_dns_hash_remove: post rm:", &e->last_used_lst);
  442. #endif
  443. #ifdef DNS_CACHE_DEBUG
  444. e->last_used_lst.next=e->last_used_lst.prev=0;
  445. #endif
  446. #endif
  447. *dns_cache_mem_used-=e->total_size;
  448. dns_hash_put(e);
  449. }
  450. /* non locking version (the dns hash must _be_ locked externally)
  451. * returns 0 when not found, or the entry on success (an entry with a
  452. * similar name but with a CNAME type will always match).
  453. * it doesn't increase the internal refcnt
  454. * returns the entry when found, 0 when not found and sets *err to !=0
  455. * on error (e.g. recursive cnames)
  456. * WARNING: - internal use only
  457. * - always check if the returned entry type is CNAME */
  458. inline static struct dns_hash_entry* _dns_hash_find(str* name, int type,
  459. int* h, int* err)
  460. {
  461. struct dns_hash_entry* e;
  462. struct dns_hash_entry* tmp;
  463. struct dns_hash_entry* ret;
  464. ticks_t now;
  465. int cname_chain;
  466. str cname;
  467. #ifdef DNS_WATCHDOG_SUPPORT
  468. int servers_up;
  469. servers_up = atomic_get(dns_servers_up);
  470. #endif
  471. cname_chain=0;
  472. ret=0;
  473. now=get_ticks_raw();
  474. *err=0;
  475. again:
  476. *h=dns_hash_no(name->s, name->len, type);
  477. #ifdef DNS_CACHE_DEBUG
  478. DBG("dns_hash_find(%.*s(%d), %d), h=%d\n", name->len, name->s,
  479. name->len, type, *h);
  480. #endif
  481. clist_foreach_safe(&dns_hash[*h], e, tmp, next){
  482. if (
  483. #ifdef DNS_WATCHDOG_SUPPORT
  484. /* remove expired elements only when the dns servers are up */
  485. servers_up &&
  486. #endif
  487. /* automatically remove expired elements */
  488. ((s_ticks_t)(now-e->expire)>=0)
  489. ) {
  490. _dns_hash_remove(e);
  491. }else if ((e->type==type) && (e->name_len==name->len) &&
  492. (strncasecmp(e->name, name->s, e->name_len)==0)){
  493. e->last_used=now;
  494. #ifdef DNS_LU_LST
  495. /* add it at the end */
  496. #ifdef DEBUG_LU_LST
  497. debug_lu_lst("_dns_hash_find: pre rm:", &e->last_used_lst);
  498. #endif
  499. clist_rm(&e->last_used_lst, next, prev);
  500. clist_append(dns_last_used_lst, &e->last_used_lst, next, prev);
  501. #ifdef DEBUG_LU_LST
  502. debug_lu_lst("_dns_hash_find: post append:", &e->last_used_lst);
  503. #endif
  504. #endif
  505. return e;
  506. }else if ((e->type==T_CNAME) && !((e->rr_lst==0) || e->err_flags) &&
  507. (e->name_len==name->len) &&
  508. (strncasecmp(e->name, name->s, e->name_len)==0)){
  509. /*if CNAME matches and CNAME is entry is not a neg. cache entry
  510. (could be produced by a specific CNAME lookup)*/
  511. e->last_used=now;
  512. #ifdef DNS_LU_LST
  513. /* add it at the end */
  514. #ifdef DEBUG_LU_LST
  515. debug_lu_lst("_dns_hash_find: cname: pre rm:", &e->last_used_lst);
  516. #endif
  517. clist_rm(&e->last_used_lst, next, prev);
  518. clist_append(dns_last_used_lst, &e->last_used_lst, next, prev);
  519. #ifdef DEBUG_LU_LST
  520. debug_lu_lst("_dns_hash_find: cname: post append:",
  521. &e->last_used_lst);
  522. #endif
  523. #endif
  524. ret=e; /* if this is an unfinished cname chain, we try to
  525. return the last cname */
  526. /* this is a cname => retry using its value */
  527. if (cname_chain> MAX_CNAME_CHAIN){
  528. LOG(L_ERR, "ERROR: _dns_hash_find: cname chain too long "
  529. "or recursive (\"%.*s\")\n", name->len, name->s);
  530. ret=0; /* error*/
  531. *err=-1;
  532. break;
  533. }
  534. cname_chain++;
  535. cname.s=((struct cname_rdata*)e->rr_lst->rdata)->name;
  536. cname.len= ((struct cname_rdata*)e->rr_lst->rdata)->name_len;
  537. name=&cname;
  538. goto again;
  539. }
  540. }
  541. return ret;
  542. }
  543. /* frees cache entries, if expired_only=0 only expired entries will be
  544. * removed, else all of them
  545. * it will process maximum no entries (to process all of them use -1)
  546. * returns the number of deleted entries
  547. * This should be called from a timer process*/
  548. inline static int dns_cache_clean(unsigned int no, int expired_only)
  549. {
  550. struct dns_hash_entry* e;
  551. ticks_t now;
  552. unsigned int n;
  553. unsigned int deleted;
  554. #ifdef DNS_LU_LST
  555. struct dns_lu_lst* l;
  556. struct dns_lu_lst* tmp;
  557. #else
  558. struct dns_hash_entry* t;
  559. unsigned int h;
  560. static unsigned int start=0;
  561. #endif
  562. n=0;
  563. deleted=0;
  564. now=get_ticks_raw();
  565. LOCK_DNS_HASH();
  566. #ifdef DNS_LU_LST
  567. clist_foreach_safe(dns_last_used_lst, l, tmp, next){
  568. e=(struct dns_hash_entry*)(((char*)l)-
  569. (char*)&((struct dns_hash_entry*)(0))->last_used_lst);
  570. if (!expired_only || ((s_ticks_t)(now-e->expire)>=0)){
  571. _dns_hash_remove(e);
  572. deleted++;
  573. }
  574. n++;
  575. if (n>=no) break;
  576. }
  577. #else
  578. for(h=start; h!=(start+DNS_HASH_SIZE); h++){
  579. clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
  580. if ((s_ticks_t)(now-e->expire)>=0){
  581. _dns_hash_remove(e);
  582. deleted++;
  583. }
  584. n++;
  585. if (n>=no) break;
  586. }
  587. }
  588. /* not fair, but faster then random() */
  589. if (!expired_only){
  590. for(h=start; h!=(start+DNS_HASH_SIZE); h++){
  591. clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
  592. _dns_hash_remove(e);
  593. deleted++;
  594. n++;
  595. if (n>=no) goto skip;
  596. }
  597. }
  598. }
  599. skip:
  600. start=h;
  601. #endif
  602. UNLOCK_DNS_HASH();
  603. return deleted;
  604. }
  605. /* frees cache entries, if expired_only=0 only expired entries will be
  606. * removed, else all of them
  607. * it will stop when the dns cache used memory reaches target (to process all
  608. * of them use 0)
  609. * returns the number of deleted entries */
  610. inline static int dns_cache_free_mem(unsigned int target, int expired_only)
  611. {
  612. struct dns_hash_entry* e;
  613. ticks_t now;
  614. unsigned int deleted;
  615. #ifdef DNS_LU_LST
  616. struct dns_lu_lst* l;
  617. struct dns_lu_lst* tmp;
  618. #else
  619. struct dns_hash_entry* t;
  620. unsigned int h;
  621. static unsigned int start=0;
  622. #endif
  623. deleted=0;
  624. now=get_ticks_raw();
  625. LOCK_DNS_HASH();
  626. #ifdef DNS_LU_LST
  627. clist_foreach_safe(dns_last_used_lst, l, tmp, next){
  628. if (*dns_cache_mem_used<=target) break;
  629. e=(struct dns_hash_entry*)(((char*)l)-
  630. (char*)&((struct dns_hash_entry*)(0))->last_used_lst);
  631. if (!expired_only || ((s_ticks_t)(now-e->expire)>=0)){
  632. _dns_hash_remove(e);
  633. deleted++;
  634. }
  635. }
  636. #else
  637. for(h=start; h!=(start+DNS_HASH_SIZE); h++){
  638. clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
  639. if (*dns_cache_mem_used<=target)
  640. goto skip;
  641. if ((s_ticks_t)(now-e->expire)>=0){
  642. _dns_hash_remove(e);
  643. deleted++;
  644. }
  645. }
  646. }
  647. /* not fair, but faster then random() */
  648. if (!expired_only){
  649. for(h=start; h!=(start+DNS_HASH_SIZE); h++){
  650. clist_foreach_safe(&dns_hash[h%DNS_HASH_SIZE], e, t, next){
  651. if (*dns_cache_mem_used<=target)
  652. goto skip;
  653. if ((s_ticks_t)(now-e->expire)>=0){
  654. _dns_hash_remove(e);
  655. deleted++;
  656. }
  657. }
  658. }
  659. }
  660. skip:
  661. start=h;
  662. #endif
  663. UNLOCK_DNS_HASH();
  664. return deleted;
  665. }
  666. /* locking version (the dns hash must _not_be locked externally)
  667. * returns 0 when not found, the searched entry on success (with CNAMEs
  668. * followed) or the last CNAME entry from an unfinished CNAME chain,
  669. * if the search matches a CNAME. On error sets *err (e.g. recursive CNAMEs).
  670. * it increases the internal refcnt => when finished dns_hash_put() must
  671. * be called on the returned entry
  672. * WARNING: - the return might be a CNAME even if type!=CNAME, see above */
  673. inline static struct dns_hash_entry* dns_hash_get(str* name, int type, int* h,
  674. int* err)
  675. {
  676. struct dns_hash_entry* e;
  677. LOCK_DNS_HASH();
  678. e=_dns_hash_find(name, type, h, err);
  679. if (e){
  680. atomic_inc(&e->refcnt);
  681. }
  682. UNLOCK_DNS_HASH();
  683. return e;
  684. }
  685. /* adds a fully created and init. entry (see dns_cache_mk_entry()) to the hash
  686. * table
  687. * returns 0 on success, -1 on error */
  688. inline static int dns_cache_add(struct dns_hash_entry* e)
  689. {
  690. int h;
  691. /* check space */
  692. /* atomic_add_long(dns_cache_total_used, e->size); */
  693. if ((*dns_cache_mem_used+e->total_size)>=cfg_get(core, core_cfg, dns_cache_max_mem)){
  694. #ifdef USE_DNS_CACHE_STATS
  695. dns_cache_stats[process_no].dc_lru_cnt++;
  696. #endif
  697. LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
  698. /* free ~ 12% of the cache */
  699. dns_cache_free_mem(*dns_cache_mem_used/16*14,
  700. !cfg_get(core, core_cfg, dns_cache_del_nonexp));
  701. if ((*dns_cache_mem_used+e->total_size)>=cfg_get(core, core_cfg, dns_cache_max_mem)){
  702. LOG(L_ERR, "ERROR: dns_cache_add: max. cache mem size exceeded\n");
  703. return -1;
  704. }
  705. }
  706. atomic_inc(&e->refcnt);
  707. h=dns_hash_no(e->name, e->name_len, e->type);
  708. #ifdef DNS_CACHE_DEBUG
  709. DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
  710. e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
  711. #endif
  712. LOCK_DNS_HASH();
  713. *dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
  714. only from within a lock */
  715. clist_append(&dns_hash[h], e, next, prev);
  716. #ifdef DNS_LU_LST
  717. clist_append(dns_last_used_lst, &e->last_used_lst, next, prev);
  718. #endif
  719. UNLOCK_DNS_HASH();
  720. return 0;
  721. }
  722. /* same as above, but it must be called with the dns hash lock held
  723. * returns 0 on success, -1 on error */
  724. inline static int dns_cache_add_unsafe(struct dns_hash_entry* e)
  725. {
  726. int h;
  727. /* check space */
  728. /* atomic_add_long(dns_cache_total_used, e->size); */
  729. if ((*dns_cache_mem_used+e->total_size)>=cfg_get(core, core_cfg, dns_cache_max_mem)){
  730. #ifdef USE_DNS_CACHE_STATS
  731. dns_cache_stats[process_no].dc_lru_cnt++;
  732. #endif
  733. LOG(L_WARN, "WARNING: dns_cache_add: cache full, trying to free...\n");
  734. /* free ~ 12% of the cache */
  735. UNLOCK_DNS_HASH();
  736. dns_cache_free_mem(*dns_cache_mem_used/16*14,
  737. !cfg_get(core, core_cfg, dns_cache_del_nonexp));
  738. LOCK_DNS_HASH();
  739. if ((*dns_cache_mem_used+e->total_size)>=cfg_get(core, core_cfg, dns_cache_max_mem)){
  740. LOG(L_ERR, "ERROR: dns_cache_add: max. cache mem size exceeded\n");
  741. return -1;
  742. }
  743. }
  744. atomic_inc(&e->refcnt);
  745. h=dns_hash_no(e->name, e->name_len, e->type);
  746. #ifdef DNS_CACHE_DEBUG
  747. DBG("dns_cache_add: adding %.*s(%d) %d (flags=%0x) at %d\n",
  748. e->name_len, e->name, e->name_len, e->type, e->err_flags, h);
  749. #endif
  750. *dns_cache_mem_used+=e->total_size; /* no need for atomic ops, written
  751. only from within a lock */
  752. clist_append(&dns_hash[h], e, next, prev);
  753. #ifdef DNS_LU_LST
  754. clist_append(dns_last_used_lst, &e->last_used_lst, next, prev);
  755. #endif
  756. return 0;
  757. }
  758. /* creates a "negative" entry which will be valid for ttl seconds */
  759. inline static struct dns_hash_entry* dns_cache_mk_bad_entry(str* name,
  760. int type,
  761. int ttl,
  762. int flags)
  763. {
  764. struct dns_hash_entry* e;
  765. int size;
  766. ticks_t now;
  767. #ifdef DNS_CACHE_DEBUG
  768. DBG("dns_cache_mk_bad_entry(%.*s, %d, %d, %d)\n", name->len, name->s,
  769. type, ttl, flags);
  770. #endif
  771. size=sizeof(struct dns_hash_entry)+name->len-1+1;
  772. e=shm_malloc(size);
  773. if (e==0){
  774. LOG(L_ERR, "ERROR: dns_cache_mk_ip_entry: out of memory\n");
  775. return 0;
  776. }
  777. memset(e, 0, size); /* init with 0*/
  778. e->total_size=size;
  779. e->name_len=name->len;
  780. e->type=type;
  781. now=get_ticks_raw();
  782. e->last_used=now;
  783. e->expire=now+S_TO_TICKS(ttl);
  784. memcpy(e->name, name->s, name->len);
  785. e->err_flags=flags;
  786. return e;
  787. }
  788. /* create a a/aaaa hash entry from a name and ip address
  789. * returns 0 on error */
  790. inline static struct dns_hash_entry* dns_cache_mk_ip_entry(str* name,
  791. struct ip_addr* ip)
  792. {
  793. struct dns_hash_entry* e;
  794. int size;
  795. ticks_t now;
  796. /* everything is allocated in one block: dns_hash_entry + name +
  797. * + dns_rr + rdata; dns_rr must start at an aligned adress,
  798. * hence we need to round dns_hash_entry+name size to a sizeof(long)
  799. * multiple.
  800. * Memory image:
  801. * struct dns_hash_entry
  802. * name (name_len+1 bytes)
  803. * padding to multiple of sizeof(long)
  804. * dns_rr
  805. * rdata (no padding needed, since for ip is just an array of chars)
  806. */
  807. size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1)+
  808. sizeof(struct dns_rr)+ ip->len;
  809. e=shm_malloc(size);
  810. if (e==0){
  811. LOG(L_ERR, "ERROR: dns_cache_mk_ip_entry: out of memory\n");
  812. return 0;
  813. }
  814. memset(e, 0, size); /* init with 0*/
  815. e->total_size=size;
  816. e->name_len=name->len;
  817. e->type=(ip->af==AF_INET)?T_A:T_AAAA;
  818. now=get_ticks_raw();
  819. e->last_used=now;
  820. e->expire=now-1; /* maximum expire */
  821. memcpy(e->name, name->s, name->len); /* memset makes sure is 0-term. */
  822. e->rr_lst=(void*)((char*)e+
  823. ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1));
  824. e->rr_lst->rdata=(void*)((char*)e->rr_lst+sizeof(struct dns_rr));
  825. e->rr_lst->expire=now-1; /* maximum expire */
  826. /* no need to align rr_lst->rdata for a or aaaa records */
  827. memcpy(e->rr_lst->rdata, ip->u.addr, ip->len);
  828. return e;
  829. }
  830. /* creates an srv hash entry from the given parameters
  831. * returns 0 on error */
  832. static struct dns_hash_entry* dns_cache_mk_srv_entry(str* name,
  833. unsigned short priority,
  834. unsigned short weight,
  835. unsigned short port,
  836. str* rr_name,
  837. int ttl)
  838. {
  839. struct dns_hash_entry* e;
  840. int size;
  841. ticks_t now;
  842. /* everything is allocated in one block: dns_hash_entry + name +
  843. * + dns_rr + rdata; dns_rr must start at an aligned adress,
  844. * hence we need to round dns_hash_entry+name size to a sizeof(long),
  845. * and similarly, dns_rr must be rounded to sizeof(short).
  846. * multiple.
  847. * Memory image:
  848. * struct dns_hash_entry
  849. * name (name_len+1 bytes)
  850. * padding to multiple of sizeof(long)
  851. * dns_rr
  852. * padding to multiple of sizeof(short)
  853. * rdata
  854. */
  855. size=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1) +
  856. ROUND_SHORT(sizeof(struct dns_rr)) +
  857. sizeof(struct srv_rdata)-1 +
  858. rr_name->len+1;
  859. e=shm_malloc(size);
  860. if (e==0){
  861. LOG(L_ERR, "ERROR: dns_cache_srv_ip_entry: out of memory\n");
  862. return 0;
  863. }
  864. memset(e, 0, size); /* init with 0*/
  865. e->total_size=size;
  866. e->name_len=name->len;
  867. e->type=T_SRV;
  868. now=get_ticks_raw();
  869. e->last_used=now;
  870. e->expire=now+S_TO_TICKS(ttl);
  871. memcpy(e->name, name->s, name->len); /* memset makes sure is 0-term. */
  872. e->rr_lst=(void*)((char*)e+
  873. ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1));
  874. e->rr_lst->rdata=(void*)((char*)e->rr_lst+ROUND_SHORT(sizeof(struct dns_rr)));
  875. e->rr_lst->expire=e->expire;
  876. ((struct srv_rdata*)e->rr_lst->rdata)->priority = priority;
  877. ((struct srv_rdata*)e->rr_lst->rdata)->weight = weight;
  878. ((struct srv_rdata*)e->rr_lst->rdata)->port = port;
  879. ((struct srv_rdata*)e->rr_lst->rdata)->name_len = rr_name->len;
  880. memcpy(((struct srv_rdata*)e->rr_lst->rdata)->name, rr_name->s, rr_name->len);
  881. return e;
  882. }
  883. /* create a dns hash entry from a name and a rdata list (pkg_malloc'ed)
  884. * (it will use only the type records with the name "name" from the
  885. * rdata list with one exception: if a matching CNAME with the same
  886. * name is found, the search will stop and this will be the record used)
  887. * returns 0 on error and removes the used elements from the rdata list*/
  888. inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
  889. struct rdata** rd_lst)
  890. {
  891. struct dns_hash_entry* e;
  892. struct dns_rr* rr;
  893. struct dns_rr** tail_rr;
  894. struct rdata** p;
  895. struct rdata* tmp_lst;
  896. struct rdata** tail;
  897. struct rdata* l;
  898. int size;
  899. ticks_t now;
  900. unsigned int max_ttl;
  901. unsigned int ttl;
  902. #define rec_matches(rec, t, n) /*(struct rdata* record, int type, str* name)*/\
  903. ( ((rec)->name_len==(n)->len) && ((rec)->type==(t)) && \
  904. (strncasecmp((rec)->name, (n)->s, (n)->len)==0))
  905. /* init */
  906. tmp_lst=0;
  907. tail=&tmp_lst;
  908. /* everything is allocated in one block: dns_hash_entry + name +
  909. * + dns_rr + rdata_raw+ ....; dns_rr must start at an aligned adress,
  910. * hence we need to round dns_hash_entry+name size to a sizeof(long)
  911. * multiple. If rdata type requires it, rdata_raw might need to be also
  912. * aligned.
  913. * Memory image:
  914. * struct dns_hash_entry (e)
  915. * name (name_len+1 bytes) (&e->name[0])
  916. * padding to multiple of sizeof(char*)
  917. * dns_rr1 (e->rr_lst)
  918. * possible padding: no padding for a_rdata or aaaa_rdata,
  919. * multipe of sizeof(short) for srv_rdata,
  920. * multiple of sizeof(long) for naptr_rdata and others
  921. * dns_rr1->rdata (e->rr_lst->rdata)
  922. * padding to multipe of sizeof long
  923. * dns_rr2 (e->rr_lst->next)
  924. * ....
  925. *
  926. */
  927. size=0;
  928. if (*rd_lst==0)
  929. return 0;
  930. /* find the first matching rr, if it's a CNAME use CNAME as type,
  931. * if not continue with the original type */
  932. for(p=rd_lst; *p; p=&(*p)->next){
  933. if (((*p)->name_len==name->len) &&
  934. (((*p)->type==type) || ((*p)->type==T_CNAME)) &&
  935. (strncasecmp((*p)->name, name->s, name->len)==0)){
  936. type=(*p)->type;
  937. break;
  938. }
  939. }
  940. /* continue, we found the type we are looking for */
  941. switch(type){
  942. case T_A:
  943. for(; *p;){
  944. if (!rec_matches((*p), type, name)){
  945. /* skip this record */
  946. p=&(*p)->next; /* advance */
  947. continue;
  948. }
  949. size+=ROUND_POINTER(sizeof(struct dns_rr)+
  950. sizeof(struct a_rdata));
  951. /* add it to our tmp. lst */
  952. *tail=*p;
  953. tail=&(*p)->next;
  954. /* detach it from the rd list */
  955. *p=(*p)->next;
  956. /* don't advance p, because the crt. elem. has
  957. * just been elimintated */
  958. }
  959. break;
  960. case T_AAAA:
  961. for(; *p;){
  962. if (!rec_matches((*p), type, name)){
  963. /* skip this record */
  964. p=&(*p)->next; /* advance */
  965. continue;
  966. }
  967. /* no padding */
  968. size+=ROUND_POINTER(sizeof(struct dns_rr)+
  969. sizeof(struct aaaa_rdata));
  970. /* add it to our tmp. lst */
  971. *tail=*p;
  972. tail=&(*p)->next;
  973. /* detach it from the rd list */
  974. *p=(*p)->next;
  975. /* don't advance p, because the crt. elem. has
  976. * just been elimintated */
  977. }
  978. break;
  979. case T_SRV:
  980. for(; *p;){
  981. if (!rec_matches((*p), type, name)){
  982. /* skip this record */
  983. p=&(*p)->next; /* advance */
  984. continue;
  985. }
  986. /* padding to short */
  987. size+=ROUND_POINTER(ROUND_SHORT(sizeof(struct dns_rr))+
  988. SRV_RDATA_SIZE(*(struct srv_rdata*)(*p)->rdata));
  989. /* add it to our tmp. lst */
  990. *tail=*p;
  991. tail=&(*p)->next;
  992. /* detach it from the rd list */
  993. *p=(*p)->next;
  994. /* don't advance p, because the crt. elem. has
  995. * just been elimintated */
  996. }
  997. break;
  998. case T_NAPTR:
  999. for(; *p;){
  1000. if (!rec_matches((*p), type, name)){
  1001. /* skip this record */
  1002. p=&(*p)->next; /* advance */
  1003. continue;
  1004. }
  1005. /* padding to char* */
  1006. size+=ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
  1007. NAPTR_RDATA_SIZE(*(struct naptr_rdata*)(*p)->rdata));
  1008. /* add it to our tmp. lst */
  1009. *tail=*p;
  1010. tail=&(*p)->next;
  1011. /* detach it from the rd list */
  1012. *p=(*p)->next;
  1013. /* don't advance p, because the crt. elem. has
  1014. * just been elimintated */
  1015. }
  1016. break;
  1017. case T_CNAME:
  1018. for(; *p;){
  1019. if (!rec_matches((*p), type, name)){
  1020. /* skip this record */
  1021. p=&(*p)->next; /* advance */
  1022. continue;
  1023. }
  1024. /* no padding */
  1025. size+=ROUND_POINTER(sizeof(struct dns_rr)+
  1026. CNAME_RDATA_SIZE(*(struct cname_rdata*)(*p)->rdata));
  1027. /* add it to our tmp. lst */
  1028. *tail=*p;
  1029. tail=&(*p)->next;
  1030. /* detach it from the rd list */
  1031. *p=(*p)->next;
  1032. /* don't advance p, because the crt. elem. has
  1033. * just been elimintated */
  1034. }
  1035. break;
  1036. default:
  1037. LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
  1038. "supported\n", type);
  1039. /* we don't know what to do with it, so don't
  1040. * add it to the tmp_lst */
  1041. return 0; /* error */
  1042. }
  1043. *tail=0; /* mark the end of our tmp_lst */
  1044. if (size==0){
  1045. #ifdef DNS_CACHE_DEBUG
  1046. DBG("dns_cache_mk_rd_entry: entry %.*s (%d) not found\n",
  1047. name->len, name->s, type);
  1048. #endif
  1049. return 0;
  1050. }
  1051. /* compute size */
  1052. size+=ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1);
  1053. e=shm_malloc(size);
  1054. if (e==0){
  1055. LOG(L_ERR, "ERROR: dns_cache_mk_ip_entry: out of memory\n");
  1056. return 0;
  1057. }
  1058. memset(e, 0, size); /* init with 0 */
  1059. clist_init(e, next, prev);
  1060. e->total_size=size;
  1061. e->name_len=name->len;
  1062. e->type=type;
  1063. now=get_ticks_raw();
  1064. e->last_used=now;
  1065. memcpy(e->name, name->s, name->len); /* memset makes sure is 0-term. */
  1066. e->rr_lst=(struct dns_rr*)((char*)e+
  1067. ROUND_POINTER(sizeof(struct dns_hash_entry)+name->len-1+1));
  1068. tail_rr=&(e->rr_lst);
  1069. rr=e->rr_lst;
  1070. max_ttl=0;
  1071. /* copy the actual data */
  1072. switch(type){
  1073. case T_A:
  1074. for(l=tmp_lst; l; l=l->next){
  1075. ttl=FIX_TTL(l->ttl);
  1076. rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1077. max_ttl=MAX(max_ttl, ttl);
  1078. rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
  1079. memcpy(rr->rdata, l->rdata, sizeof(struct a_rdata));
  1080. rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
  1081. sizeof(struct a_rdata)));
  1082. tail_rr=&(rr->next);
  1083. rr=rr->next;
  1084. }
  1085. break;
  1086. case T_AAAA:
  1087. for(l=tmp_lst; l; l=l->next){
  1088. ttl=FIX_TTL(l->ttl);
  1089. rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1090. max_ttl=MAX(max_ttl, ttl);
  1091. rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
  1092. memcpy(rr->rdata, l->rdata, sizeof(struct aaaa_rdata));
  1093. rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
  1094. sizeof(struct aaaa_rdata)));
  1095. tail_rr=&(rr->next);
  1096. rr=rr->next;
  1097. }
  1098. break;
  1099. case T_SRV:
  1100. for(l=tmp_lst; l; l=l->next){
  1101. ttl=FIX_TTL(l->ttl);
  1102. rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1103. max_ttl=MAX(max_ttl, ttl);
  1104. rr->rdata=(void*)((char*)rr+
  1105. ROUND_SHORT(sizeof(struct dns_rr)));
  1106. /* copy the whole srv_rdata block*/
  1107. memcpy(rr->rdata, l->rdata,
  1108. SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
  1109. rr->next=(void*)((char*)rr+
  1110. ROUND_POINTER( ROUND_SHORT(sizeof(struct dns_rr))+
  1111. SRV_RDATA_SIZE(
  1112. *(struct srv_rdata*)l->rdata)));
  1113. tail_rr=&(rr->next);
  1114. rr=rr->next;
  1115. }
  1116. break;
  1117. case T_NAPTR:
  1118. for(l=tmp_lst; l; l=l->next){
  1119. ttl=FIX_TTL(l->ttl);
  1120. rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1121. max_ttl=MAX(max_ttl, ttl);
  1122. rr->rdata=(void*)((char*)rr+
  1123. ROUND_POINTER(sizeof(struct dns_rr)));
  1124. /* copy the whole naptr_rdata block*/
  1125. memcpy(rr->rdata, l->rdata,
  1126. NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
  1127. /* adjust the string pointer */
  1128. ((struct naptr_rdata*)rr->rdata)->flags=
  1129. translate_pointer((char*)rr->rdata, (char*)l->rdata,
  1130. (((struct naptr_rdata*)l->rdata)->flags));
  1131. ((struct naptr_rdata*)rr->rdata)->services=
  1132. translate_pointer((char*)rr->rdata, (char*)l->rdata,
  1133. (((struct naptr_rdata*)l->rdata)->services));
  1134. ((struct naptr_rdata*)rr->rdata)->regexp=
  1135. translate_pointer((char*)rr->rdata, (char*)l->rdata,
  1136. (((struct naptr_rdata*)l->rdata)->regexp));
  1137. ((struct naptr_rdata*)rr->rdata)->repl=
  1138. translate_pointer((char*)rr->rdata, (char*)l->rdata,
  1139. (((struct naptr_rdata*)l->rdata)->repl));
  1140. rr->next=(void*)((char*)rr+
  1141. ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
  1142. NAPTR_RDATA_SIZE(
  1143. *(struct naptr_rdata*)l->rdata)));
  1144. tail_rr=&(rr->next);
  1145. rr=rr->next;
  1146. }
  1147. break;
  1148. case T_CNAME:
  1149. for(l=tmp_lst; l; l=l->next){
  1150. ttl=FIX_TTL(l->ttl);
  1151. rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1152. max_ttl=MAX(max_ttl, ttl);
  1153. rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
  1154. memcpy(rr->rdata, l->rdata,
  1155. CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
  1156. rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
  1157. CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata)));
  1158. tail_rr=&(rr->next);
  1159. rr=rr->next;
  1160. }
  1161. break;
  1162. default:
  1163. /* do nothing */
  1164. LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: create: type %d not "
  1165. "supported\n", type);
  1166. ;
  1167. }
  1168. *tail_rr=0; /* terminate the list */
  1169. e->expire=now+S_TO_TICKS(max_ttl);
  1170. free_rdata_list(tmp_lst);
  1171. return e;
  1172. }
  1173. /* structure used only inside dns_cache_mk_rd_entry2 to break
  1174. * the list of records into records of the same type */
  1175. struct tmp_rec{
  1176. struct rdata* rd;
  1177. struct dns_hash_entry* e;
  1178. struct dns_rr* rr;
  1179. struct dns_rr** tail_rr;
  1180. int max_ttl;
  1181. int size;
  1182. };
  1183. /* create several dns hash entries from a list of rdata structs
  1184. * returns 0 on error */
  1185. inline static struct dns_hash_entry* dns_cache_mk_rd_entry2(struct rdata* rd)
  1186. {
  1187. struct rdata* l;
  1188. ticks_t now;
  1189. struct tmp_rec rec[MAX_DNS_RECORDS];
  1190. int rec_idx[MAX_DNS_RECORDS];
  1191. int r, i;
  1192. int no_records; /* number of different records */
  1193. unsigned int ttl;
  1194. no_records=0;
  1195. rec[0].e=0;
  1196. /* everything is allocated in one block: dns_hash_entry + name +
  1197. * + dns_rr + rdata_raw+ ....; dns_rr must start at an aligned adress,
  1198. * hence we need to round dns_hash_entry+name size to a sizeof(long)
  1199. * multiple. If rdata type requires it, rdata_raw might need to be also
  1200. * aligned.
  1201. * Memory image:
  1202. * struct dns_hash_entry (e)
  1203. * name (name_len+1 bytes) (&e->name[0])
  1204. * padding to multiple of sizeof(char*)
  1205. * dns_rr1 (e->rr_lst)
  1206. * possible padding: no padding for a_rdata or aaaa_rdata,
  1207. * multipe of sizeof(short) for srv_rdata,
  1208. * multiple of sizeof(long) for naptr_rdata and others
  1209. * dns_rr1->rdata (e->rr_lst->rdata)
  1210. * padding to multipe of sizeof long
  1211. * dns_rr2 (e->rr_lst->next)
  1212. * ....
  1213. *
  1214. */
  1215. /* compute size */
  1216. for(l=rd, i=0; l && (i<MAX_DNS_RECORDS); l=l->next, i++){
  1217. for (r=0; r<no_records; r++){
  1218. if ((l->type==rec[r].rd->type) &&
  1219. (l->name_len==rec[r].rd->name_len)
  1220. && (strncasecmp(l->name, rec[r].rd->name, l->name_len)==0)){
  1221. /* found */
  1222. goto found;
  1223. }
  1224. }
  1225. /* not found, create new */
  1226. if (no_records<MAX_DNS_RECORDS){
  1227. rec[r].rd=l;
  1228. rec[r].e=0;
  1229. rec[r].size=ROUND_POINTER(sizeof(struct dns_hash_entry)+
  1230. rec[r].rd->name_len-1+1);
  1231. no_records++;
  1232. }else{
  1233. LOG(L_ERR, "ERROR: dns_cache_mk_rd_entry2: too many records: %d\n",
  1234. no_records);
  1235. /* skip */
  1236. continue;
  1237. }
  1238. found:
  1239. rec_idx[i]=r;
  1240. switch(l->type){
  1241. case T_A:
  1242. /* no padding */
  1243. rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
  1244. sizeof(struct a_rdata));
  1245. break;
  1246. case T_AAAA:
  1247. /* no padding */
  1248. rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
  1249. sizeof(struct aaaa_rdata));
  1250. break;
  1251. case T_SRV:
  1252. /* padding to short */
  1253. rec[r].size+=ROUND_POINTER(ROUND_SHORT(sizeof(struct dns_rr))+
  1254. SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata));
  1255. break;
  1256. case T_NAPTR:
  1257. /* padding to char* */
  1258. rec[r].size+=ROUND_POINTER(ROUND_POINTER(
  1259. sizeof(struct dns_rr))+
  1260. NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata));
  1261. break;
  1262. case T_CNAME:
  1263. /* no padding */
  1264. rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
  1265. CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
  1266. break;
  1267. default:
  1268. LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
  1269. "supported\n", l->type);
  1270. }
  1271. }
  1272. now=get_ticks_raw();
  1273. /* alloc & init the entries */
  1274. for (r=0; r<no_records; r++){
  1275. rec[r].e=shm_malloc(rec[r].size);
  1276. if (rec[r].e==0){
  1277. LOG(L_ERR, "ERROR: dns_cache_mk_ip_entry: out of memory\n");
  1278. goto error;
  1279. }
  1280. memset(rec[r].e, 0, rec[r].size); /* init with 0*/
  1281. rec[r].e->total_size=rec[r].size;
  1282. rec[r].e->name_len=rec[r].rd->name_len;
  1283. rec[r].e->type=rec[r].rd->type;
  1284. rec[r].e->last_used=now;
  1285. /* memset makes sure is 0-term. */
  1286. memcpy(rec[r].e->name, rec[r].rd->name, rec[r].rd->name_len);
  1287. rec[r].e->rr_lst=(struct dns_rr*)((char*)rec[r].e+
  1288. ROUND_POINTER(sizeof(struct dns_hash_entry)+rec[r].e->name_len
  1289. -1+1));
  1290. rec[r].tail_rr=&(rec[r].e->rr_lst);
  1291. rec[r].rr=rec[r].e->rr_lst;
  1292. rec[r].max_ttl=0;
  1293. /* link them in a list */
  1294. if (r==0){
  1295. clist_init(rec[r].e, next, prev);
  1296. }else{
  1297. clist_append(rec[0].e, rec[r].e, next, prev);
  1298. }
  1299. }
  1300. /* copy the actual data */
  1301. for(l=rd, i=0; l && (i<MAX_DNS_RECORDS); l=l->next, i++){
  1302. r=rec_idx[i];
  1303. ttl=FIX_TTL(l->ttl);
  1304. switch(l->type){
  1305. case T_A:
  1306. rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1307. rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
  1308. rec[r].rr->rdata=(void*)((char*)rec[r].rr+
  1309. sizeof(struct dns_rr));
  1310. memcpy(rec[r].rr->rdata, l->rdata, sizeof(struct a_rdata));
  1311. rec[r].rr->next=(void*)((char*)rec[r].rr+
  1312. ROUND_POINTER(sizeof(struct dns_rr)+
  1313. sizeof(struct a_rdata)));
  1314. rec[r].tail_rr=&(rec[r].rr->next);
  1315. rec[r].rr=rec[r].rr->next;
  1316. break;
  1317. case T_AAAA:
  1318. rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1319. rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
  1320. rec[r].rr->rdata=(void*)((char*)rec[r].rr+
  1321. sizeof(struct dns_rr));
  1322. memcpy(rec[r].rr->rdata, l->rdata, sizeof(struct aaaa_rdata));
  1323. rec[r].rr->next=(void*)((char*)rec[r].rr+
  1324. ROUND_POINTER(sizeof(struct dns_rr)+
  1325. sizeof(struct aaaa_rdata)));
  1326. rec[r].tail_rr=&(rec[r].rr->next);
  1327. rec[r].rr=rec[r].rr->next;
  1328. break;
  1329. case T_SRV:
  1330. rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1331. rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
  1332. rec[r].rr->rdata=(void*)((char*)rec[r].rr+
  1333. ROUND_SHORT(sizeof(struct dns_rr)));
  1334. /* copy the whole srv_rdata block*/
  1335. memcpy(rec[r].rr->rdata, l->rdata,
  1336. SRV_RDATA_SIZE(*(struct srv_rdata*)l->rdata) );
  1337. rec[r].rr->next=(void*)((char*)rec[r].rr+
  1338. ROUND_POINTER( ROUND_SHORT(sizeof(struct dns_rr))+
  1339. SRV_RDATA_SIZE(
  1340. *(struct srv_rdata*)l->rdata)));
  1341. rec[r].tail_rr=&(rec[r].rr->next);
  1342. rec[r].rr=rec[r].rr->next;
  1343. break;
  1344. case T_NAPTR:
  1345. rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1346. rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
  1347. rec[r].rr->rdata=(void*)((char*)rec[r].rr+
  1348. ROUND_POINTER(sizeof(struct dns_rr)));
  1349. /* copy the whole srv_rdata block*/
  1350. memcpy(rec[r].rr->rdata, l->rdata,
  1351. NAPTR_RDATA_SIZE(*(struct naptr_rdata*)l->rdata) );
  1352. /* adjust the string pointer */
  1353. ((struct naptr_rdata*)rec[r].rr->rdata)->flags=
  1354. translate_pointer((char*)rec[r].rr->rdata, (char*)l->rdata,
  1355. (((struct naptr_rdata*)l->rdata)->flags));
  1356. ((struct naptr_rdata*)rec[r].rr->rdata)->services=
  1357. translate_pointer((char*)rec[r].rr->rdata, (char*)l->rdata,
  1358. (((struct naptr_rdata*)l->rdata)->services));
  1359. ((struct naptr_rdata*)rec[r].rr->rdata)->regexp=
  1360. translate_pointer((char*)rec[r].rr->rdata, (char*)l->rdata,
  1361. (((struct naptr_rdata*)l->rdata)->regexp));
  1362. ((struct naptr_rdata*)rec[r].rr->rdata)->repl=
  1363. translate_pointer((char*)rec[r].rr->rdata, (char*)l->rdata,
  1364. (((struct naptr_rdata*)l->rdata)->repl));
  1365. rec[r].rr->next=(void*)((char*)rec[r].rr+
  1366. ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
  1367. NAPTR_RDATA_SIZE(
  1368. *(struct naptr_rdata*)l->rdata)));
  1369. rec[r].tail_rr=&(rec[r].rr->next);
  1370. rec[r].rr=rec[r].rr->next;
  1371. break;
  1372. case T_CNAME:
  1373. rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
  1374. rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
  1375. rec[r].rr->rdata=(void*)((char*)rec[r].rr
  1376. +sizeof(struct dns_rr));
  1377. memcpy(rec[r].rr->rdata, l->rdata,
  1378. CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
  1379. rec[r].rr->next=(void*)((char*)rec[r].rr+
  1380. ROUND_POINTER(sizeof(struct dns_rr)+
  1381. CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata)));
  1382. rec[r].tail_rr=&(rec[r].rr->next);
  1383. rec[r].rr=rec[r].rr->next;
  1384. break;
  1385. default:
  1386. /* do nothing */
  1387. ;
  1388. }
  1389. }
  1390. for (r=0; r<no_records; r++){
  1391. *rec[r].tail_rr=0; /* terminate the list */
  1392. rec[r].e->expire=now+S_TO_TICKS(rec[r].max_ttl);
  1393. }
  1394. return rec[0].e;
  1395. error:
  1396. for (r=0; r<no_records; r++){
  1397. dns_destroy_entry(rec[r].e);
  1398. }
  1399. return 0;
  1400. }
  1401. inline static struct dns_hash_entry* dns_get_entry(str* name, int type);
  1402. #define CACHE_RELEVANT_RECS_ONLY
  1403. #ifdef CACHE_RELEVANT_RECS_ONLY
  1404. /* internal only: gets related entries from a rdata list, appends them
  1405. * to e (list) and returns:
  1406. * - e if e is of the requested type
  1407. * - if e is a CNAME, tries to get to the end of the CNAME chain and returns
  1408. * the final entry if the types match or 0 if the chain is unfinished
  1409. * - 0 on error/not found
  1410. * records is modified (the used records are removed from the list and freed)
  1411. *
  1412. * WARNING: - records must be pkg_malloc'ed
  1413. * Notes: - if the return is 0 and e->type==T_CNAME, the list will contain
  1414. * the CNAME chain (the last element being the last CNAME)
  1415. * */
  1416. inline static struct dns_hash_entry* dns_get_related(struct dns_hash_entry* e,
  1417. int type,
  1418. struct rdata** records)
  1419. {
  1420. struct dns_hash_entry* ret;
  1421. struct dns_hash_entry* l;
  1422. struct dns_hash_entry* t;
  1423. struct dns_hash_entry* lst_end;
  1424. struct dns_rr* rr;
  1425. static int cname_chain_len=0;
  1426. str tmp;
  1427. ret=0;
  1428. l=e;
  1429. #ifdef DNS_CACHE_DEBUG
  1430. DBG("dns_get_related(%p (%.*s, %d), %d, *%p) (%d)\n", e,
  1431. e->name_len, e->name, e->type, type, *records, cname_chain_len);
  1432. #endif
  1433. clist_init(l, next, prev);
  1434. if (type==e->type){
  1435. ret=e;
  1436. switch(e->type){
  1437. case T_SRV:
  1438. for (rr=e->rr_lst; rr && *records; rr=rr->next){
  1439. tmp.s=((struct srv_rdata*)rr->rdata)->name;
  1440. tmp.len=((struct srv_rdata*)rr->rdata)->name_len;
  1441. if (!(dns_flags&DNS_IPV6_ONLY)){
  1442. t=dns_cache_mk_rd_entry(&tmp, T_A, records);
  1443. if (t){
  1444. if ((t->type==T_CNAME) && *records)
  1445. dns_get_related(t, T_A, records);
  1446. lst_end=t->prev; /* needed for clist_append*/
  1447. clist_append_sublist(l, t, lst_end, next, prev);
  1448. }
  1449. }
  1450. if (!(dns_flags&DNS_IPV4_ONLY)){
  1451. t=dns_cache_mk_rd_entry(&tmp, T_AAAA, records);
  1452. if (t){
  1453. if ((t->type==T_CNAME) && *records)
  1454. dns_get_related(t, T_AAAA, records);
  1455. lst_end=t->prev; /* needed for clist_append*/
  1456. clist_append_sublist(l, t, lst_end, next, prev);
  1457. }
  1458. }
  1459. }
  1460. break;
  1461. #ifdef USE_NAPTR
  1462. case T_NAPTR:
  1463. #ifdef NAPTR_CACHE_ALL_ARS
  1464. if (*records)
  1465. dns_cache_mk_rd_entry2(*records);
  1466. #else
  1467. for (rr=e->rr_lst; rr && *records; rr=rr->next){
  1468. if (naptr_get_sip_proto((struct naptr_rdata*)rr->rdata)>0){
  1469. tmp.s=((struct naptr_rdata*)rr->rdata)->repl;
  1470. tmp.len=((struct naptr_rdata*)rr->rdata)->repl_len;
  1471. t=dns_cache_mk_rd_entry(&tmp, T_SRV, records);
  1472. if (t){
  1473. if (*records)
  1474. dns_get_related(t, T_SRV, records);
  1475. lst_end=t->prev; /* needed for clist_append*/
  1476. clist_append_sublist(l, t, lst_end, next, prev);
  1477. }
  1478. }
  1479. }
  1480. #endif /* NAPTR_CACHE_ALL_ARS */
  1481. #endif /* USE_NAPTR */
  1482. break;
  1483. default:
  1484. /* nothing extra */
  1485. break;
  1486. }
  1487. }else if ((e->type==T_CNAME) && (cname_chain_len<MAX_CNAME_CHAIN)){
  1488. /* only one cname is allowed (rfc2181), so we ignore
  1489. * the others (we take only the first one) */
  1490. tmp.s=((struct cname_rdata*)e->rr_lst->rdata)->name;
  1491. tmp.len=((struct cname_rdata*)e->rr_lst->rdata)->name_len;
  1492. t=dns_cache_mk_rd_entry(&tmp, type, records);
  1493. if (t){
  1494. if (*records){
  1495. cname_chain_len++;
  1496. ret=dns_get_related(t, type, records);
  1497. cname_chain_len--;
  1498. lst_end=t->prev;
  1499. clist_append_sublist(l, t, lst_end, next, prev);
  1500. }else{
  1501. /* if no more recs, but we found the orig. target anyway,
  1502. * return it (e.g. recs are only CNAME x & x A 1.2.3.4 or
  1503. * CNAME & SRV) */
  1504. if (t->type==type)
  1505. ret=t;
  1506. clist_append(l, t, next, prev);
  1507. }
  1508. }
  1509. }
  1510. return ret;
  1511. }
  1512. #endif
  1513. /* calls the external resolver and populates the cache with the result
  1514. * returns: 0 on error, pointer to hash entry on success
  1515. * WARNING: make sure you use dns_hash_entry_put() when you're
  1516. * finished with the result)
  1517. * */
  1518. inline static struct dns_hash_entry* dns_cache_do_request(str* name, int type)
  1519. {
  1520. struct rdata* records;
  1521. struct dns_hash_entry* e;
  1522. struct dns_hash_entry* l;
  1523. struct dns_hash_entry* r;
  1524. struct dns_hash_entry* t;
  1525. struct ip_addr* ip;
  1526. str cname_val;
  1527. char name_buf[MAX_DNS_NAME];
  1528. e=0;
  1529. l=0;
  1530. cname_val.s=0;
  1531. #ifdef USE_DNS_CACHE_STATS
  1532. if (dns_cache_stats)
  1533. dns_cache_stats[process_no].dns_req_cnt++;
  1534. #endif /* USE_DNS_CACHE_STATS */
  1535. if (type==T_A){
  1536. if ((ip=str2ip(name))!=0){
  1537. e=dns_cache_mk_ip_entry(name, ip);
  1538. if (e)
  1539. atomic_set(&e->refcnt, 1);/* because we ret. a ref. to it*/
  1540. goto end; /* we do not cache obvious stuff */
  1541. }
  1542. }
  1543. #ifdef USE_IPV6
  1544. else if (type==T_AAAA){
  1545. if ((ip=str2ip6(name))!=0){
  1546. e=dns_cache_mk_ip_entry(name, ip);
  1547. if (e)
  1548. atomic_set(&e->refcnt, 1);/* because we ret. a ref. to it*/
  1549. goto end;/* we do not cache obvious stuff */
  1550. }
  1551. }
  1552. #endif /* USE_IPV6 */
  1553. #ifdef DNS_WATCHDOG_SUPPORT
  1554. if (atomic_get(dns_servers_up)==0)
  1555. goto end; /* the servers are down, needless to perform the query */
  1556. #endif
  1557. if (name->len>=MAX_DNS_NAME){
  1558. LOG(L_ERR, "ERROR: dns_cache_do_request: name too long (%d chars)\n",
  1559. name->len);
  1560. goto end;
  1561. }
  1562. /* null terminate the string, needed by get_record */
  1563. memcpy(name_buf, name->s, name->len);
  1564. name_buf[name->len]=0;
  1565. records=get_record(name_buf, type, RES_AR);
  1566. if (records){
  1567. #ifdef CACHE_RELEVANT_RECS_ONLY
  1568. e=dns_cache_mk_rd_entry(name, type, &records);
  1569. if (e){
  1570. l=e;
  1571. e=dns_get_related(l, type, &records);
  1572. /* e should contain the searched entry (if found) and l
  1573. * all the entries (e and related) */
  1574. if (e){
  1575. atomic_set(&e->refcnt, 1); /* 1 because we return a
  1576. ref. to it */
  1577. }else{
  1578. /* e==0 => l contains a cname list => we use the last
  1579. * cname from the chain for a new resolve attempt (l->prev) */
  1580. /* only one cname record is allowed (rfc2181), so we ignore
  1581. * the others (we take only the first one) */
  1582. cname_val.s=
  1583. ((struct cname_rdata*)l->prev->rr_lst->rdata)->name;
  1584. cname_val.len=
  1585. ((struct cname_rdata*)l->prev->rr_lst->rdata)->name_len;
  1586. DBG("dns_cache_do_request: cname detected: %.*s (%d)\n",
  1587. cname_val.len, cname_val.s, cname_val.len);
  1588. }
  1589. /* add all the records to the hash */
  1590. l->prev->next=0; /* we break the double linked list for easier
  1591. searching */
  1592. LOCK_DNS_HASH(); /* optimization */
  1593. for (r=l; r; r=t){
  1594. t=r->next;
  1595. dns_cache_add_unsafe(r); /* refcnt++ inside */
  1596. if (atomic_get(&r->refcnt)==0){
  1597. /* if cache adding failed and nobody else is interested
  1598. * destroy this entry */
  1599. dns_destroy_entry(r);
  1600. }
  1601. }
  1602. UNLOCK_DNS_HASH();
  1603. /* if only cnames found => try to resolve the last one */
  1604. if (cname_val.s){
  1605. DBG("dns_cache_do_request: dns_get_entry(cname: %.*s (%d))\n",
  1606. cname_val.len, cname_val.s, cname_val.len);
  1607. e=dns_get_entry(&cname_val, type);
  1608. }
  1609. }
  1610. #else
  1611. l=dns_cache_mk_rd_entry2(records);
  1612. #endif
  1613. free_rdata_list(records);
  1614. }else if (cfg_get(core, core_cfg, dns_neg_cache_ttl)){
  1615. e=dns_cache_mk_bad_entry(name, type, cfg_get(core, core_cfg, dns_neg_cache_ttl), DNS_BAD_NAME);
  1616. atomic_set(&e->refcnt, 1); /* 1 because we return a ref. to it */
  1617. dns_cache_add(e); /* refcnt++ inside*/
  1618. goto end;
  1619. }
  1620. #ifndef CACHE_RELEVANT_RECS_ONLY
  1621. if (l){
  1622. /* add all the records to the cache, but return only the record
  1623. * we are looking for */
  1624. l->prev->next=0; /* we break the double linked list for easier
  1625. searching */
  1626. LOCK_DNS_HASH(); /* optimization */
  1627. for (r=l; r; r=t){
  1628. t=r->next;
  1629. if (e==0){ /* no entry found yet */
  1630. if (r->type==T_CNAME){
  1631. if ((r->name_len==name->len) && (r->rr_lst) &&
  1632. (strncasecmp(r->name, name->s, name->len)==0)){
  1633. /* update the name with the name from the cname rec. */
  1634. cname_val.s=
  1635. ((struct cname_rdata*)r->rr_lst->rdata)->name;
  1636. cname_val.len=
  1637. ((struct cname_rdata*)r->rr_lst->rdata)->name_len;
  1638. name=&cname_val;
  1639. }
  1640. }else if ((r->type==type) && (r->name_len==name->len) &&
  1641. (strncasecmp(r->name, name->s, name->len)==0)){
  1642. e=r;
  1643. atomic_set(&e->refcnt, 1); /* 1 because we return a ref.
  1644. to it */
  1645. }
  1646. }
  1647. dns_cache_add_unsafe(r); /* refcnt++ inside */
  1648. if (atomic_get(&r->refcnt)==0){
  1649. /* if cache adding failed and nobody else is interested
  1650. * destroy this entry */
  1651. dns_destroy_entry(r);
  1652. }
  1653. }
  1654. UNLOCK_DNS_HASH();
  1655. if ((e==0) && (cname_val.s)){ /* not found, but found a cname */
  1656. /* only one cname is allowed (rfc2181), so we ignore the
  1657. * others (we take only the first one) */
  1658. e=dns_get_entry(&cname_val, type);
  1659. }
  1660. }
  1661. #endif
  1662. end:
  1663. return e;
  1664. }
  1665. /* tries to lookup (name, type) in the hash and if not found tries to make
  1666. * a dns request
  1667. * return: 0 on error, pointer to a dns_hash_entry on success
  1668. * WARNING: when not needed anymore dns_hash_put() must be called! */
  1669. inline static struct dns_hash_entry* dns_get_entry(str* name, int type)
  1670. {
  1671. int h;
  1672. struct dns_hash_entry* e;
  1673. str cname_val;
  1674. int err;
  1675. static int rec_cnt=0; /* recursion protection */
  1676. e=0;
  1677. if (rec_cnt>MAX_CNAME_CHAIN){
  1678. LOG(L_WARN, "WARNING: dns_get_entry: CNAME chain too long or"
  1679. " recursive CNAMEs (\"%.*s\")\n", name->len, name->s);
  1680. goto error;
  1681. }
  1682. rec_cnt++;
  1683. e=dns_hash_get(name, type, &h, &err);
  1684. #ifdef USE_DNS_CACHE_STATS
  1685. if (e) {
  1686. if (e->err_flags==DNS_BAD_NAME && dns_cache_stats)
  1687. /* negative DNS cache hit */
  1688. dns_cache_stats[process_no].dc_neg_hits_cnt++;
  1689. else if (!e->err_flags && dns_cache_stats) /* DNS cache hit */
  1690. dns_cache_stats[process_no].dc_hits_cnt++;
  1691. if (dns_cache_stats)
  1692. dns_cache_stats[process_no].dns_req_cnt++;
  1693. }
  1694. #endif /* USE_DNS_CACHE_STATS */
  1695. if ((e==0) && ((err) || ((e=dns_cache_do_request(name, type))==0))){
  1696. goto error;
  1697. }else if ((e->type==T_CNAME) && (type!=T_CNAME)){
  1698. /* cname found instead which couldn't be resolved with the cached
  1699. * info => try a dns request */
  1700. /* only one cname record is allowed (rfc2181), so we ignore
  1701. * the others (we take only the first one) */
  1702. cname_val.s= ((struct cname_rdata*)e->rr_lst->rdata)->name;
  1703. cname_val.len=((struct cname_rdata*)e->rr_lst->rdata)->name_len;
  1704. dns_hash_put(e); /* not interested in the cname anymore */
  1705. if ((e=dns_cache_do_request(&cname_val, type))==0)
  1706. goto error; /* could not resolve cname */
  1707. }
  1708. /* found */
  1709. if ((e->rr_lst==0) || e->err_flags){
  1710. /* negative cache => not resolvable */
  1711. dns_hash_put(e);
  1712. e=0;
  1713. }
  1714. error:
  1715. rec_cnt--;
  1716. return e;
  1717. }
  1718. /* gets the first non-expired, good record starting with record no
  1719. * from the dns_hash_entry struct e
  1720. * params: e - dns_hash_entry struct
  1721. * *no - it must contain the start record number (0 initially);
  1722. * it will be filled with the returned record number
  1723. * now - current time/ticks value
  1724. * returns pointer to the rr on success and sets no to the rr number
  1725. * 0 on error and fills the error flags
  1726. *
  1727. * Example usage:
  1728. * list all non-expired non-bad-marked ips for name:
  1729. * e=dns_get_entry(name, T_A);
  1730. * if (e){
  1731. * *no=0;
  1732. * now=get_ticks_raw();
  1733. * while(rr=dns_entry_get_rr(e, no, now){
  1734. * DBG("address %d\n", *no);
  1735. * *no++; ( get the next address next time )
  1736. * }
  1737. * }
  1738. */
  1739. inline static struct dns_rr* dns_entry_get_rr( struct dns_hash_entry* e,
  1740. unsigned char* no, ticks_t now)
  1741. {
  1742. struct dns_rr* rr;
  1743. int n;
  1744. int flags;
  1745. #ifdef DNS_WATCHDOG_SUPPORT
  1746. int servers_up;
  1747. servers_up = atomic_get(dns_servers_up);
  1748. #endif
  1749. flags=0;
  1750. for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
  1751. for(;rr;rr=rr->next){
  1752. if (
  1753. #ifdef DNS_WATCHDOG_SUPPORT
  1754. /* check the expiration time only when the servers are up */
  1755. servers_up &&
  1756. #endif
  1757. ((s_ticks_t)(now-rr->expire)>=0) /* expired rr */
  1758. )
  1759. continue;
  1760. if (rr->err_flags){ /* bad rr */
  1761. continue;
  1762. }
  1763. /* everything is ok now */
  1764. *no=n;
  1765. return rr;
  1766. }
  1767. *no=n;
  1768. return 0;
  1769. }
  1770. #ifdef DNS_SRV_LB
  1771. #define srv_reset_tried(p) (*(p)=0)
  1772. #define srv_marked(p, i) (*(p)&(1UL<<(i)))
  1773. #define srv_mark_tried(p, i) \
  1774. do{ \
  1775. (*(p)|=(1UL<<(i))); \
  1776. }while(0)
  1777. #define srv_next_rr(n, f, i) srv_mark_tried(f, i)
  1778. /* returns a random number between 0 and max inclusive (0<=r<=max) */
  1779. inline static unsigned dns_srv_random(unsigned max)
  1780. {
  1781. return fastrand_max(max);
  1782. }
  1783. /* for a SRV record it will return the next entry to be tried according
  1784. * to the RFC2782 server selection mechanism
  1785. * params:
  1786. * e is a dns srv hash entry
  1787. * no is the start index of the current group (a group is a set of SRV
  1788. * rrs with the same priority)
  1789. * tried is a bitmap where the tried srv rrs of the same priority are
  1790. * marked
  1791. * now - current time/ticks value
  1792. * returns pointer to the rr on success and sets no to the rr number
  1793. * 0 on error and fills the error flags
  1794. * WARNING: unlike dns_entry_get_rr() this will always return another
  1795. * another rr automatically (*no must not be incremented)
  1796. *
  1797. * Example usage:
  1798. * list all non-expired, non-bad-marked, never tried before srv records
  1799. * using the rfc2782 algo:
  1800. * e=dns_get_entry(name, T_SRV);
  1801. * if (e){
  1802. * no=0;
  1803. * srv_reset_tried(&tried);
  1804. * now=get_ticks_raw();
  1805. * while(rr=dns_srv_get_nxt_rr(e, &tried, &no, now){
  1806. * DBG("address %d\n", *no);
  1807. * }
  1808. * }
  1809. *
  1810. */
  1811. inline static struct dns_rr* dns_srv_get_nxt_rr(struct dns_hash_entry* e,
  1812. srv_flags_t* tried,
  1813. unsigned char* no, ticks_t now)
  1814. {
  1815. #define MAX_SRV_GRP_IDX (sizeof(srv_flags_t)*8)
  1816. struct dns_rr* rr;
  1817. struct dns_rr* start_grp;
  1818. int n;
  1819. unsigned sum;
  1820. unsigned prio;
  1821. unsigned rand_w;
  1822. int found;
  1823. int saved_idx;
  1824. int i, idx;
  1825. struct r_sums_entry{
  1826. unsigned r_sum;
  1827. struct dns_rr* rr;
  1828. }r_sums[MAX_SRV_GRP_IDX];
  1829. #ifdef DNS_WATCHDOG_SUPPORT
  1830. int servers_up;
  1831. servers_up = atomic_get(dns_servers_up);
  1832. #endif
  1833. rand_w=0;
  1834. for(rr=e->rr_lst, n=0;rr && (n<*no);rr=rr->next, n++);/* skip *no records*/
  1835. retry:
  1836. if (unlikely(rr==0))
  1837. goto no_more_rrs;
  1838. start_grp=rr;
  1839. prio=((struct srv_rdata*)start_grp->rdata)->priority;
  1840. sum=0;
  1841. saved_idx=-1;
  1842. found=0;
  1843. for (idx=0;rr && (prio==((struct srv_rdata*)rr->rdata)->priority) &&
  1844. (idx < MAX_SRV_GRP_IDX); idx++, rr=rr->next){
  1845. if ((
  1846. #ifdef DNS_WATCHDOG_SUPPORT
  1847. /* check the expiration time only when the servers are up */
  1848. servers_up &&
  1849. #endif
  1850. ((s_ticks_t)(now-rr->expire)>=0) /* expired entry */) ||
  1851. (rr->err_flags) /* bad rr */ ||
  1852. (srv_marked(tried, idx)) ) /* already tried */{
  1853. r_sums[idx].r_sum=0; /* 0 sum, to skip over it */
  1854. r_sums[idx].rr=0; /* debug: mark it as unused */
  1855. continue;
  1856. }
  1857. /* special case, 0 weight records should be "first":
  1858. * remember the first rr int the "virtual" list: A 0 weight must
  1859. * come first if present, else get the first one */
  1860. if ((saved_idx==-1) || (((struct srv_rdata*)rr->rdata)->weight==0)){
  1861. saved_idx=idx;
  1862. }
  1863. sum+=((struct srv_rdata*)rr->rdata)->weight;
  1864. r_sums[idx].r_sum=sum;
  1865. r_sums[idx].rr=rr;
  1866. found++;
  1867. }
  1868. if (found==0){
  1869. /* try in the next priority group */
  1870. n+=idx; /* next group start idx, last rr */
  1871. srv_reset_tried(tried);
  1872. goto retry;
  1873. }else if ((found==1) || ((rand_w=dns_srv_random(sum))==0)){
  1874. /* 1. if only one found, avoid a useless random() call or
  1875. * 2. if rand_w==0, immediately select a 0 weight record if present,
  1876. * or else the first record found
  1877. * (this takes care of the 0-weight at the beginning requirement) */
  1878. i=saved_idx; /* saved idx contains either first 0 weight or first
  1879. valid record */
  1880. goto found;
  1881. }
  1882. /* if we are here => rand_w is not 0 and we have at least 2 valid options
  1883. * => we can safely iterate on the whole r_sums[] whithout any other
  1884. * extra checks */
  1885. for (i=0; (i<idx) && (r_sums[i].r_sum<rand_w); i++);
  1886. found:
  1887. #ifdef DNS_CACHE_DEBUG
  1888. DBG("dns_srv_get_nxt_rr(%p, %lx, %d, %u): selected %d/%d in grp. %d"
  1889. " (rand_w=%d, rr=%p p=%d w=%d rsum=%d)\n",
  1890. e, (unsigned long)*tried, *no, now, i, idx, n, rand_w, r_sums[i].rr,
  1891. ((struct srv_rdata*)r_sums[i].rr->rdata)->priority,
  1892. ((struct srv_rdata*)r_sums[i].rr->rdata)->weight, r_sums[i].r_sum);
  1893. #endif
  1894. /* i is the winner */
  1895. *no=n; /* grp. start */
  1896. srv_mark_tried(tried, i); /* mark it */
  1897. return r_sums[i].rr;
  1898. no_more_rrs:
  1899. *no=n;
  1900. return 0;
  1901. }
  1902. #endif /* DNS_SRV_LB */
  1903. /* gethostbyname compatibility: converts a dns_hash_entry structure
  1904. * to a statical internal hostent structure
  1905. * returns a pointer to the internal hostent structure on success or
  1906. * 0 on error
  1907. */
  1908. inline static struct hostent* dns_entry2he(struct dns_hash_entry* e)
  1909. {
  1910. static struct hostent he;
  1911. static char hostname[256];
  1912. static char* p_aliases[1];
  1913. static char* p_addr[DNS_HE_MAX_ADDR+1];
  1914. static char address[16*DNS_HE_MAX_ADDR]; /* max 10 ipv6 addresses */
  1915. int af, len;
  1916. struct dns_rr* rr;
  1917. unsigned char rr_no;
  1918. ticks_t now;
  1919. int i;
  1920. switch(e->type){
  1921. case T_A:
  1922. af=AF_INET;
  1923. len=4;
  1924. break;
  1925. case T_AAAA:
  1926. #ifdef USE_IPV6
  1927. af=AF_INET6;
  1928. len=16;
  1929. break;
  1930. #else /* USE_IPV6 */
  1931. LOG(L_ERR, "ERROR: dns_entry2he: IPv6 dns cache entry, but "
  1932. "IPv6 support disabled at compile time"
  1933. " (recompile with -DUSE_IPV6)\n");
  1934. return 0;
  1935. #endif /* USE_IPV6 */
  1936. default:
  1937. LOG(L_CRIT, "BUG: dns_entry2he: wrong entry type %d for %.*s\n",
  1938. e->type, e->name_len, e->name);
  1939. return 0;
  1940. }
  1941. rr_no=0;
  1942. now=get_ticks_raw();
  1943. /* if the entry has already expired use the time at the end of lifetime */
  1944. if (unlikely((s_ticks_t)(now-e->expire)>=0)) now=e->expire-1;
  1945. rr=dns_entry_get_rr(e, &rr_no, now);
  1946. for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++,
  1947. rr=dns_entry_get_rr(e, &rr_no, now)){
  1948. p_addr[i]=&address[i*len];
  1949. memcpy(p_addr[i], ((struct a_rdata*)rr->rdata)->ip, len);
  1950. }
  1951. if (i==0){
  1952. DBG("DEBUG: dns_entry2he: no good records found (%d) for %.*s (%d)\n",
  1953. rr_no, e->name_len, e->name, e->type);
  1954. return 0; /* no good record found */
  1955. }
  1956. p_addr[i]=0; /* mark the end of the addresses */
  1957. p_aliases[0]=0; /* no aliases */
  1958. memcpy(hostname, e->name, e->name_len);
  1959. hostname[e->name_len]=0;
  1960. he.h_addrtype=af;
  1961. he.h_length=len;
  1962. he.h_addr_list=p_addr;
  1963. he.h_aliases=p_aliases;
  1964. he.h_name=hostname;
  1965. return &he;
  1966. }
  1967. /* gethostbyname compatibility: performs an a_lookup and returns a pointer
  1968. * to a statical internal hostent structure
  1969. * returns 0 on success, <0 on error (see the error codes)
  1970. */
  1971. inline static struct hostent* dns_a_get_he(str* name)
  1972. {
  1973. struct dns_hash_entry* e;
  1974. struct ip_addr* ip;
  1975. struct hostent* he;
  1976. e=0;
  1977. if ((ip=str2ip(name))!=0){
  1978. return ip_addr2he(name, ip);
  1979. }
  1980. if ((e=dns_get_entry(name, T_A))==0)
  1981. return 0;
  1982. /* found */
  1983. he=dns_entry2he(e);
  1984. dns_hash_put(e);
  1985. return he;
  1986. }
  1987. #ifdef USE_IPV6
  1988. /* gethostbyname compatibility: performs an aaaa_lookup and returns a pointer
  1989. * to a statical internal hostent structure
  1990. * returns 0 on success, <0 on error (see the error codes)
  1991. */
  1992. inline static struct hostent* dns_aaaa_get_he(str* name)
  1993. {
  1994. struct dns_hash_entry* e;
  1995. struct ip_addr* ip;
  1996. struct hostent* he;
  1997. e=0;
  1998. if ((ip=str2ip6(name))!=0){
  1999. return ip_addr2he(name, ip);
  2000. }
  2001. if ((e=dns_get_entry(name, T_AAAA))==0)
  2002. return 0;
  2003. /* found */
  2004. he=dns_entry2he(e);
  2005. dns_hash_put(e);
  2006. return he;
  2007. }
  2008. #endif
  2009. /* returns 0 on success, -1 on error (rr type does not contain an ip) */
  2010. inline static int dns_rr2ip(int type, struct dns_rr* rr, struct ip_addr* ip)
  2011. {
  2012. switch(type){
  2013. case T_A:
  2014. ip->af=AF_INET;
  2015. ip->len=4;
  2016. memcpy(ip->u.addr, ((struct a_rdata*)rr->rdata)->ip, 4);
  2017. return 0;
  2018. break;
  2019. case T_AAAA:
  2020. #ifdef USE_IPV6
  2021. ip->af=AF_INET6;
  2022. ip->len=16;
  2023. memcpy(ip->u.addr, ((struct aaaa_rdata*)rr->rdata)->ip6, 16);
  2024. return 0;
  2025. #else /* USE_IPV6 */
  2026. LOG(L_ERR, "ERROR: dns_rr2ip: IPv6 dns rr, but IPv6 support"
  2027. "disabled at compile time (recompile with "
  2028. "-DUSE_IPV6)\n" );
  2029. #endif /*USE_IPV6 */
  2030. break;
  2031. }
  2032. return -1;
  2033. }
  2034. /* gethostbyname compatibility:
  2035. * performs an a or aaaa dns lookup, returns 0 on error and a pointer to a
  2036. * static hostent structure on success
  2037. * flags: - none set: tries first an a_lookup and if it fails an aaaa_lookup
  2038. * - DNS_IPV6_FIRST: tries first an aaaa_lookup and then an a_lookup
  2039. * - DNS_IPV4_ONLY: tries only an a_lookup
  2040. * - DNS_IPV6_ONLY: tries only an aaaa_lookup
  2041. */
  2042. struct hostent* dns_get_he(str* name, int flags)
  2043. {
  2044. #ifdef USE_IPV6
  2045. struct hostent* he;
  2046. if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
  2047. he=dns_aaaa_get_he(name);
  2048. if (he) return he;
  2049. }else{
  2050. he=dns_a_get_he(name);
  2051. if (he) return he;
  2052. }
  2053. if (flags&DNS_IPV6_FIRST){
  2054. he=dns_a_get_he(name);
  2055. }else if (!(flags&(DNS_IPV6_ONLY|DNS_IPV4_ONLY))){
  2056. he=dns_aaaa_get_he(name);
  2057. }
  2058. return he;
  2059. #else /* USE_IPV6 */
  2060. return dns_a_get_he(name);
  2061. #endif /* USE_IPV6 */
  2062. }
  2063. /* sip_resolvehost helper: gets the first good hostent/port combination
  2064. * returns 0 on error, pointer to static hostent structure on success
  2065. * (and sets port)*/
  2066. struct hostent* dns_srv_get_he(str* name, unsigned short* port, int flags)
  2067. {
  2068. struct dns_hash_entry* e;
  2069. struct dns_rr* rr;
  2070. str rr_name;
  2071. struct hostent* he;
  2072. ticks_t now;
  2073. unsigned char rr_no;
  2074. rr=0;
  2075. he=0;
  2076. now=get_ticks_raw();
  2077. if ((e=dns_get_entry(name, T_SRV))==0)
  2078. goto error;
  2079. /* look inside the RRs for a good one (not expired or marked bad) */
  2080. rr_no=0;
  2081. while( (rr=dns_entry_get_rr(e, &rr_no, now))!=0){
  2082. /* everything is ok now, we can try to resolve the ip */
  2083. rr_name.s=((struct srv_rdata*)rr->rdata)->name;
  2084. rr_name.len=((struct srv_rdata*)rr->rdata)->name_len;
  2085. if ((he=dns_get_he(&rr_name, flags))!=0){
  2086. /* success, at least one good ip found */
  2087. *port=((struct srv_rdata*)rr->rdata)->port;
  2088. goto end;
  2089. }
  2090. rr_no++; /* try from the next record, the current one was not good */
  2091. }
  2092. /* if we reach this point => error, we couldn't find any good rr */
  2093. end:
  2094. if (e) dns_hash_put(e);
  2095. error:
  2096. return he;
  2097. }
  2098. struct hostent* dns_resolvehost(char* name)
  2099. {
  2100. str host;
  2101. if ((cfg_get(core, core_cfg, use_dns_cache)==0) || (dns_hash==0)){ /* not init yet */
  2102. return _resolvehost(name);
  2103. }
  2104. host.s=name;
  2105. host.len=strlen(name);
  2106. return dns_get_he(&host, dns_flags);
  2107. }
  2108. #if 0
  2109. /* resolves a host name trying NAPTR, SRV, A & AAAA lookups, for details
  2110. * see dns_sip_resolve()
  2111. * FIXME: this version will return only the first ip
  2112. * returns: hostent struct & *port filled with the port from the SRV record;
  2113. * 0 on error
  2114. */
  2115. struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
  2116. char* proto)
  2117. {
  2118. struct dns_srv_handle h;
  2119. struct ip_addr ip;
  2120. int ret;
  2121. if ((cfg_get(core, core_cfg, use_dns_cache==0)) || (dns_hash==0)){
  2122. /* not init or off => use normal, non-cached version */
  2123. return _sip_resolvehost(name, port, proto);
  2124. }
  2125. dns_srv_handle_init(&h);
  2126. ret=dns_sip_resolve(&h, name, &ip, port, proto, dns_flags);
  2127. dns_srv_handle_put(&h);
  2128. if (ret>=0)
  2129. return ip_addr2he(name, &ip);
  2130. return 0;
  2131. }
  2132. #endif
  2133. /* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
  2134. * if *port!=0.
  2135. * when performing SRV lookup (*port==0) it will use proto to look for
  2136. * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
  2137. * returns: hostent struct & *port filled with the port from the SRV record;
  2138. * 0 on error
  2139. */
  2140. struct hostent* dns_srv_sip_resolvehost(str* name, unsigned short* port,
  2141. char* proto)
  2142. {
  2143. struct hostent* he;
  2144. struct ip_addr* ip;
  2145. static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
  2146. int len;
  2147. str srv_name;
  2148. char srv_proto;
  2149. if ((cfg_get(core, core_cfg, use_dns_cache)==0) || (dns_hash==0)){
  2150. /* not init or off => use normal, non-cached version */
  2151. return _sip_resolvehost(name, port, proto);
  2152. }
  2153. len=0;
  2154. if (proto){ /* makes sure we have a protocol set*/
  2155. if (*proto==0)
  2156. *proto=srv_proto=PROTO_UDP; /* default */
  2157. else
  2158. srv_proto=*proto;
  2159. }else{
  2160. srv_proto=PROTO_UDP;
  2161. }
  2162. /* try SRV if no port specified (draft-ietf-sip-srv-06) */
  2163. if ((port)&&(*port==0)){
  2164. *port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
  2165. don't find another */
  2166. if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
  2167. LOG(L_WARN, "WARNING: dns_sip_resolvehost: domain name too long"
  2168. " (%d), unable to perform SRV lookup\n", name->len);
  2169. }else{
  2170. /* check if it's an ip address */
  2171. if ( ((ip=str2ip(name))!=0)
  2172. #ifdef USE_IPV6
  2173. || ((ip=str2ip6(name))!=0)
  2174. #endif
  2175. ){
  2176. /* we are lucky, this is an ip address */
  2177. return ip_addr2he(name,ip);
  2178. }
  2179. switch(srv_proto){
  2180. case PROTO_NONE: /* no proto specified, use udp */
  2181. if (proto)
  2182. *proto=PROTO_UDP;
  2183. /* no break */
  2184. case PROTO_UDP:
  2185. memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
  2186. memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
  2187. tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
  2188. len=SRV_UDP_PREFIX_LEN + name->len;
  2189. break;
  2190. case PROTO_TCP:
  2191. memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
  2192. memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
  2193. tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
  2194. len=SRV_TCP_PREFIX_LEN + name->len;
  2195. break;
  2196. case PROTO_TLS:
  2197. memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
  2198. memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
  2199. tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
  2200. len=SRV_TLS_PREFIX_LEN + name->len;
  2201. break;
  2202. case PROTO_SCTP:
  2203. memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
  2204. memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
  2205. tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
  2206. len=SRV_SCTP_PREFIX_LEN + name->len;
  2207. break;
  2208. default:
  2209. LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
  2210. (int)srv_proto);
  2211. return 0;
  2212. }
  2213. srv_name.s=tmp;
  2214. srv_name.len=len;
  2215. if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0)
  2216. return he;
  2217. }
  2218. }
  2219. /*skip_srv:*/
  2220. if (name->len >= MAX_DNS_NAME) {
  2221. LOG(L_ERR, "dns_sip_resolvehost: domain name too long\n");
  2222. return 0;
  2223. }
  2224. he=dns_get_he(name, dns_flags);
  2225. return he;
  2226. }
  2227. #ifdef USE_NAPTR
  2228. /* iterates over a naptr rr list, returning each time a "good" naptr record
  2229. * is found.( srv type, no regex and a supported protocol)
  2230. * params:
  2231. * naptr_head - naptr dns_rr list head
  2232. * tried - bitmap used to keep track of the already tried records
  2233. * (no more then sizeof(tried)*8 valid records are
  2234. * ever walked
  2235. * srv_name - if succesfull, it will be set to the selected record
  2236. * srv name (naptr repl.)
  2237. * proto - if succesfull it will be set to the selected record
  2238. * protocol
  2239. * returns 0 if no more records found or a pointer to the selected record
  2240. * and sets protocol and srv_name
  2241. * WARNING: when calling first time make sure you run first
  2242. * naptr_iterate_init(&tried)
  2243. */
  2244. struct naptr_rdata* dns_naptr_sip_iterate(struct dns_rr* naptr_head,
  2245. naptr_bmp_t* tried,
  2246. str* srv_name, char* proto)
  2247. {
  2248. int i, idx;
  2249. struct dns_rr* l;
  2250. struct naptr_rdata* naptr;
  2251. struct naptr_rdata* naptr_saved;
  2252. char saved_proto;
  2253. char naptr_proto;
  2254. idx=0;
  2255. naptr_proto=PROTO_NONE;
  2256. naptr_saved=0;
  2257. saved_proto=0;
  2258. i=0;
  2259. for(l=naptr_head; l && (i<MAX_NAPTR_RRS); l=l->next){
  2260. naptr=(struct naptr_rdata*) l->rdata;
  2261. if (naptr==0){
  2262. LOG(L_CRIT, "naptr_iterate: BUG: null rdata\n");
  2263. goto end;
  2264. }
  2265. /* check if valid and get proto */
  2266. if ((naptr_proto=naptr_get_sip_proto(naptr))<=0) continue;
  2267. if (*tried& (1<<i)){
  2268. i++;
  2269. continue; /* already tried */
  2270. }
  2271. #ifdef DNS_CACHE_DEBUG
  2272. DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
  2273. " proto %d\n", naptr->repl_len, naptr->repl,
  2274. (int)naptr_proto);
  2275. #endif
  2276. if ((naptr_proto_supported(naptr_proto))){
  2277. if (naptr_choose(&naptr_saved, &saved_proto,
  2278. naptr, naptr_proto))
  2279. idx=i;
  2280. }
  2281. i++;
  2282. }
  2283. if (naptr_saved){
  2284. /* found something */
  2285. #ifdef DNS_CACHE_DEBUG
  2286. DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
  2287. " tried: 0x%x\n", naptr_saved->repl_len,
  2288. naptr_saved->repl, (int)saved_proto, *tried);
  2289. #endif
  2290. *tried|=1<<idx;
  2291. *proto=saved_proto;
  2292. srv_name->s=naptr_saved->repl;
  2293. srv_name->len=naptr_saved->repl_len;
  2294. return naptr_saved;
  2295. }
  2296. end:
  2297. return 0;
  2298. }
  2299. /* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
  2300. * lookup if *port==0 or normal A/AAAA lookup
  2301. * if *port!=0.
  2302. * when performing SRV lookup (*port==0) it will use proto to look for
  2303. * tcp or udp hosts; if proto==0 => no SRV lookup
  2304. * returns: hostent struct & *port filled with the port from the SRV record;
  2305. * 0 on error
  2306. */
  2307. struct hostent* dns_naptr_sip_resolvehost(str* name, unsigned short* port,
  2308. char* proto)
  2309. {
  2310. struct hostent* he;
  2311. struct ip_addr* tmp_ip;
  2312. naptr_bmp_t tried_bmp;
  2313. struct dns_hash_entry* e;
  2314. char n_proto;
  2315. str srv_name;
  2316. he=0;
  2317. if (dns_hash==0){ /* not init => use normal, non-cached version */
  2318. LOG(L_WARN, "WARNING: dns_sip_resolvehost: called before dns cache"
  2319. " initialization\n");
  2320. return _sip_resolvehost(name, port, proto);
  2321. }
  2322. if (proto && port && (*proto==0) && (*port==0)){
  2323. *proto=PROTO_UDP; /* just in case we don't find another */
  2324. /* check if it's an ip address */
  2325. if ( ((tmp_ip=str2ip(name))!=0)
  2326. #ifdef USE_IPV6
  2327. || ((tmp_ip=str2ip6(name))!=0)
  2328. #endif
  2329. ){
  2330. /* we are lucky, this is an ip address */
  2331. #ifdef USE_IPV6
  2332. if (((dns_flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
  2333. ((dns_flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
  2334. return 0;
  2335. }
  2336. #endif
  2337. *port=SIP_PORT;
  2338. return ip_addr2he(name, tmp_ip);
  2339. }
  2340. /* do naptr lookup */
  2341. if ((e=dns_get_entry(name, T_NAPTR))==0)
  2342. goto naptr_not_found;
  2343. naptr_iterate_init(&tried_bmp);
  2344. while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
  2345. &srv_name, &n_proto)){
  2346. if ((he=dns_srv_get_he(&srv_name, port, dns_flags))!=0){
  2347. #ifdef DNS_CACHE_DEBUG
  2348. DBG("dns_naptr_sip_resolvehost(%.*s, %d, %d) srv, ret=%p\n",
  2349. name->len, name->s, (int)*port, (int)*proto, he);
  2350. #endif
  2351. dns_hash_put(e);
  2352. *proto=n_proto;
  2353. return he;
  2354. }
  2355. }
  2356. /* no acceptable naptr record found, fallback to srv */
  2357. dns_hash_put(e);
  2358. }
  2359. naptr_not_found:
  2360. return dns_srv_sip_resolvehost(name, port, proto);
  2361. }
  2362. #endif /* USE_NAPTR */
  2363. /* resolves a host name trying NAPTR lookup if *proto==0 and *port==0, SRV
  2364. * lookup if *port==0 or normal A/AAAA lookup
  2365. * if *port!=0.
  2366. * when performing SRV lookup (*port==0) it will use proto to look for
  2367. * tcp or udp hosts; if proto==0 => no SRV lookup
  2368. * returns: hostent struct & *port filled with the port from the SRV record;
  2369. * 0 on error
  2370. */
  2371. struct hostent* dns_sip_resolvehost(str* name, unsigned short* port,
  2372. char* proto)
  2373. {
  2374. #ifdef USE_NAPTR
  2375. if (dns_flags&DNS_TRY_NAPTR)
  2376. return dns_naptr_sip_resolvehost(name, port, proto);
  2377. #endif
  2378. return dns_srv_sip_resolvehost(name, port, proto);
  2379. }
  2380. /* performs an a lookup, fills the dns_entry pointer and the ip addr.
  2381. * (with the first good ip). if *e ==0 does the a lookup, and changes it
  2382. * to the result, if not it uses the current value and tries to use
  2383. * the rr_no record from it.
  2384. * params: e - must contain the "in-use" dns_hash_entry pointer (from
  2385. * a previous call) or *e==0 (for the first call)
  2386. * name - host name for which we do the lookup (required only
  2387. * when *e==0)
  2388. * ip - will be filled with the first good resolved ip started
  2389. * at *rr_no
  2390. * rr_no - record number to start searching for a good ip from
  2391. * (e.g. value from previous call + 1), filled on return
  2392. * with the number of the record corresponding to the
  2393. * returned ip
  2394. * returns 0 on success, <0 on error (see the error codes),
  2395. * fills e, ip and rr_no
  2396. * On end of records (when used to iterate on all the ips) it
  2397. * will return E_DNS_EOR (you should not log an error for this
  2398. * value, is just a signal that the address list end has been reached)
  2399. * Note: either e or name must be different from 0 (name.s !=0 also)
  2400. * WARNING: dns_hash_put(*e) must be called when you don't need
  2401. * the entry anymore and *e!=0 (failling to do so => mem. leak)
  2402. * Example:
  2403. * dns_entry=0;
  2404. * ret=dns_a_get_ip(&dns_entry, name, &ip, &rr_no); -- get the first rr.
  2405. * ...
  2406. * rr_no++;
  2407. * while((ret>=0) && dns_entry)
  2408. * dns_a_get_ip(&dns_entry, name, &ip, &rr_no); -- get the next rr
  2409. * if (ret!=-E_DNS_EOR) ERROR(....);
  2410. * ...
  2411. * dns_hash_put(dns_entry); -- finished with the entry
  2412. */
  2413. inline static int dns_a_resolve( struct dns_hash_entry** e,
  2414. unsigned char* rr_no,
  2415. str* name,
  2416. struct ip_addr* ip)
  2417. {
  2418. struct dns_rr* rr;
  2419. int ret;
  2420. ticks_t now;
  2421. struct ip_addr* tmp;
  2422. rr=0;
  2423. ret=-E_DNS_NO_IP;
  2424. if (*e==0){ /* do lookup */
  2425. /* if ip don't set *e */
  2426. if ((tmp=str2ip(name))!=0){
  2427. *ip=*tmp;
  2428. *rr_no=0;
  2429. return 0;
  2430. }
  2431. if ((*e=dns_get_entry(name, T_A))==0)
  2432. goto error;
  2433. /* found */
  2434. *rr_no=0;
  2435. ret=-E_DNS_BAD_IP_ENTRY;
  2436. }
  2437. now=get_ticks_raw();
  2438. /* if the entry has already expired use the time at the end of lifetime */
  2439. if (unlikely((s_ticks_t)(now-(*e)->expire)>=0)) now=(*e)->expire-1;
  2440. rr=dns_entry_get_rr(*e, rr_no, now);
  2441. if (rr){
  2442. /* everything is ok now, we can try to "convert" the ip */
  2443. dns_rr2ip((*e)->type, rr, ip);
  2444. ret=0;
  2445. }else{
  2446. ret=-E_DNS_EOR;
  2447. }
  2448. error:
  2449. DBG("dns_a_resovle(%.*s, %d) returning %d\n",
  2450. name->len, name->s, *rr_no, ret);
  2451. return ret;
  2452. }
  2453. #ifdef USE_IPV6
  2454. /* lookup, fills the dns_entry pointer and the ip addr.
  2455. * (with the first good ip). if *e ==0 does the a lookup, and changes it
  2456. * to the result, if not it uses the current value and tries to use
  2457. * Same as dns_a_resolve but for aaaa records (see above).
  2458. */
  2459. inline static int dns_aaaa_resolve( struct dns_hash_entry** e,
  2460. unsigned char* rr_no,
  2461. str* name,
  2462. struct ip_addr* ip)
  2463. {
  2464. struct dns_rr* rr;
  2465. int ret;
  2466. ticks_t now;
  2467. struct ip_addr* tmp;
  2468. rr=0;
  2469. ret=-E_DNS_NO_IP;
  2470. if (*e==0){ /* do lookup */
  2471. /* if ip don't set *e */
  2472. if ((tmp=str2ip6(name))!=0){
  2473. *ip=*tmp;
  2474. *rr_no=0;
  2475. return 0;
  2476. }
  2477. if ((*e=dns_get_entry(name, T_AAAA))==0)
  2478. goto error;
  2479. /* found */
  2480. *rr_no=0;
  2481. ret=-E_DNS_BAD_IP_ENTRY;
  2482. }
  2483. now=get_ticks_raw();
  2484. /* if the entry has already expired use the time at the end of lifetime */
  2485. if (unlikely((s_ticks_t)(now-(*e)->expire)>=0)) now=(*e)->expire-1;
  2486. rr=dns_entry_get_rr(*e, rr_no, now);
  2487. if (rr){
  2488. /* everything is ok now, we can try to "convert" the ip */
  2489. dns_rr2ip((*e)->type, rr, ip);
  2490. ret=0;
  2491. }else{
  2492. ret=-E_DNS_EOR; /* no more records */
  2493. }
  2494. error:
  2495. return ret;
  2496. }
  2497. #endif /* USE_IPV6 */
  2498. /* performs an a or aaaa dns lookup, returns <0 on error (see the
  2499. * dns error codes) and 0 on success
  2500. * flags: - none set: tries first an a_lookup and if it fails an aaaa_lookup
  2501. * - DNS_IPV6_FIRST: tries first an aaaa_lookup and then an a_lookup
  2502. * - DNS_IPV4_ONLY: tries only an a_lookup
  2503. * - DNS_IPV6_ONLY: tries only an aaaa_lookup
  2504. * see dns_a_resolve() for the rest of the params., examples a.s.o
  2505. * WARNING: don't forget dns_hash_put(*e) when e is not needed anymore
  2506. */
  2507. inline static int dns_ip_resolve( struct dns_hash_entry** e,
  2508. unsigned char* rr_no,
  2509. str* name,
  2510. struct ip_addr* ip,
  2511. int flags)
  2512. {
  2513. int ret;
  2514. str host;
  2515. struct dns_hash_entry* orig;
  2516. ret=-E_DNS_NO_IP;
  2517. if (*e==0){ /* first call */
  2518. #ifdef USE_IPV6
  2519. if ((flags&(DNS_IPV6_FIRST|DNS_IPV6_ONLY))){
  2520. ret=dns_aaaa_resolve(e, rr_no, name, ip);
  2521. if (ret>=0) return ret;
  2522. }else{
  2523. ret=dns_a_resolve(e, rr_no, name, ip);
  2524. if (ret>=0) return ret;
  2525. }
  2526. if (flags&DNS_IPV6_FIRST){
  2527. ret=dns_a_resolve(e, rr_no, name, ip);
  2528. }else if (!(flags&(DNS_IPV6_ONLY|DNS_IPV4_ONLY))){
  2529. ret=dns_aaaa_resolve(e, rr_no, name, ip);
  2530. }
  2531. #else /* USE_IPV6 */
  2532. ret=dns_a_resolve(e, rr_no, name, ip);
  2533. #endif /* USE_IPV6 */
  2534. }else if ((*e)->type==T_A){
  2535. /* continue A resolving */
  2536. /* retrieve host name from the hash entry (ignore name which might
  2537. be null when continuing a srv lookup) */
  2538. host.s=(*e)->name;
  2539. host.len=(*e)->name_len;
  2540. ret=dns_a_resolve(e, rr_no, &host, ip);
  2541. #ifdef USE_IPV6
  2542. if (ret>=0) return ret;
  2543. if (!(flags&(DNS_IPV6_ONLY|DNS_IPV6_FIRST|DNS_IPV4_ONLY))){
  2544. /* not found, try with AAAA */
  2545. orig=*e;
  2546. *e=0;
  2547. *rr_no=0;
  2548. ret=dns_aaaa_resolve(e, rr_no, &host, ip);
  2549. /* delay original record release until we're finished with host*/
  2550. dns_hash_put(orig);
  2551. }
  2552. #endif /* USE_IPV6 */
  2553. }else if ((*e)->type==T_AAAA){
  2554. /* retrieve host name from the hash entry (ignore name which might
  2555. be null when continuing a srv lookup) */
  2556. host.s=(*e)->name;
  2557. host.len=(*e)->name_len;
  2558. #ifdef USE_IPV6
  2559. /* continue AAAA resolving */
  2560. ret=dns_aaaa_resolve(e, rr_no, &host, ip);
  2561. if (ret>=0) return ret;
  2562. if ((flags&DNS_IPV6_FIRST) && !(flags&DNS_IPV6_ONLY)){
  2563. /* not found, try with A */
  2564. orig=*e;
  2565. *e=0;
  2566. *rr_no=0;
  2567. ret=dns_a_resolve(e, rr_no, &host, ip);
  2568. /* delay original record release until we're finished with host*/
  2569. dns_hash_put(orig);
  2570. }
  2571. #else /* USE_IPV6 */
  2572. /* ipv6 disabled, try with A */
  2573. orig=*e;
  2574. *e=0;
  2575. *rr_no=0;
  2576. ret=dns_a_resolve(e, rr_no, &host, ip);
  2577. /* delay original record release until we're finished with host*/
  2578. dns_hash_put(orig);
  2579. #endif /* USE_IPV6 */
  2580. }else{
  2581. LOG(L_CRIT, "BUG: dns_ip_resolve: invalid record type %d\n",
  2582. (*e)->type);
  2583. }
  2584. return ret;
  2585. }
  2586. /* gets the first srv record starting at rr_no
  2587. * Next call will return the next record a.s.o.
  2588. * (similar to dns_a_resolve but for srv, sets host, port and automatically
  2589. * switches to the next record in the future)
  2590. *
  2591. * if DNS_SRV_LB and tried!=NULL will do random weight based selection
  2592. * for choosing between SRV RRs with the same priority (as described in
  2593. * RFC2782).
  2594. * If tried==NULL or DNS_SRV_LB is not defined => always returns next
  2595. * record in the priority order and for records with the same priority
  2596. * the record with the higher weight (from the remaining ones)
  2597. */
  2598. inline static int dns_srv_resolve_nxt(struct dns_hash_entry** e,
  2599. #ifdef DNS_SRV_LB
  2600. srv_flags_t* tried,
  2601. #endif
  2602. unsigned char* rr_no,
  2603. str* name, str* host, unsigned short* port)
  2604. {
  2605. struct dns_rr* rr;
  2606. int ret;
  2607. ticks_t now;
  2608. rr=0;
  2609. ret=-E_DNS_NO_SRV;
  2610. if (*e==0){
  2611. if ((*e=dns_get_entry(name, T_SRV))==0)
  2612. goto error;
  2613. /* found it */
  2614. *rr_no=0;
  2615. #ifdef DNS_SRV_LB
  2616. if (tried)
  2617. srv_reset_tried(tried);
  2618. #endif
  2619. ret=-E_DNS_BAD_SRV_ENTRY;
  2620. }
  2621. now=get_ticks_raw();
  2622. /* if the entry has already expired use the time at the end of lifetime */
  2623. if (unlikely((s_ticks_t)(now-(*e)->expire)>=0)) now=(*e)->expire-1;
  2624. #ifdef DNS_SRV_LB
  2625. if (tried){
  2626. rr=dns_srv_get_nxt_rr(*e, tried, rr_no, now);
  2627. }else
  2628. #endif
  2629. {
  2630. rr=dns_entry_get_rr(*e, rr_no, now);
  2631. (*rr_no)++; /* try next record next time */
  2632. }
  2633. if (rr){
  2634. host->s=((struct srv_rdata*)rr->rdata)->name;
  2635. host->len=((struct srv_rdata*)rr->rdata)->name_len;
  2636. *port=((struct srv_rdata*)rr->rdata)->port;
  2637. ret=0;
  2638. }else{
  2639. ret=-E_DNS_EOR; /* no more records */
  2640. }
  2641. error:
  2642. return ret;
  2643. }
  2644. /* gets the first srv record starting at h->srv_no, resolve it
  2645. * and get the first ip address (starting at h->ip_no)
  2646. * (similar to dns_a_resolve but for srv, sets host, port)
  2647. * WARNING: don't forget to init h prior to calling this function the first
  2648. * time and dns_srv_handle_put(h), even if error is returned
  2649. */
  2650. inline static int dns_srv_resolve_ip(struct dns_srv_handle* h,
  2651. str* name, struct ip_addr* ip, unsigned short* port,
  2652. int flags)
  2653. {
  2654. int ret;
  2655. str host;
  2656. host.len=0;
  2657. host.s=0;
  2658. do{
  2659. if (h->a==0){
  2660. #ifdef DNS_SRV_LB
  2661. if ((ret=dns_srv_resolve_nxt(&h->srv,
  2662. (flags & DNS_SRV_RR_LB)?&h->srv_tried_rrs:0,
  2663. &h->srv_no,
  2664. name, &host, port))<0)
  2665. goto error;
  2666. #else
  2667. if ((ret=dns_srv_resolve_nxt(&h->srv, &h->srv_no,
  2668. name, &host, port))<0)
  2669. goto error;
  2670. #endif
  2671. h->port=*port; /* store new port */
  2672. }else{
  2673. *port=h->port; /* return the stored port */
  2674. }
  2675. if ((ret=dns_ip_resolve(&h->a, &h->ip_no, &host, ip, flags))<0){
  2676. /* couldn't find any good ip for this record, try the next one */
  2677. if (h->a){
  2678. dns_hash_put(h->a);
  2679. h->a=0;
  2680. }
  2681. }else if (h->a==0){
  2682. /* this was an ip, try the next srv record in the future */
  2683. }
  2684. }while(ret<0);
  2685. error:
  2686. #ifdef DNS_CACHE_DEBUG
  2687. DBG("dns_srv_resolve_ip(\"%.*s\", %d, %d), ret=%d, ip=%s\n",
  2688. name->len, name->s, h->srv_no, h->ip_no, ret,
  2689. ip?ZSW(ip_addr2a(ip)):"");
  2690. #endif
  2691. return ret;
  2692. }
  2693. /* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
  2694. * if *port!=0.
  2695. * when performing SRV lookup (*port==0) it will use proto to look for
  2696. * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
  2697. * h must be initialized prior to calling this function and can be used to
  2698. * get the subsequent ips
  2699. * returns: <0 on error
  2700. * 0 on success and it fills *ip, *port, dns_sip_resolve_h
  2701. * WARNING: when finished, dns_sip_resolve_put(h) must be called!
  2702. */
  2703. inline static int dns_srv_sip_resolve(struct dns_srv_handle* h, str* name,
  2704. struct ip_addr* ip, unsigned short* port, char* proto,
  2705. int flags)
  2706. {
  2707. static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
  2708. int len;
  2709. str srv_name;
  2710. struct ip_addr* tmp_ip;
  2711. int ret;
  2712. struct hostent* he;
  2713. char srv_proto;
  2714. if (dns_hash==0){ /* not init => use normal, non-cached version */
  2715. LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
  2716. " initialization\n");
  2717. h->srv=h->a=0;
  2718. he=_sip_resolvehost(name, port, proto);
  2719. if (he){
  2720. hostent2ip_addr(ip, he, 0);
  2721. return 0;
  2722. }
  2723. return -E_DNS_NO_SRV;
  2724. }
  2725. len=0;
  2726. if ((h->srv==0) && (h->a==0)){ /* first call */
  2727. if (proto){ /* makes sure we have a protocol set*/
  2728. if (*proto==0)
  2729. *proto=srv_proto=PROTO_UDP; /* default */
  2730. else
  2731. srv_proto=*proto;
  2732. }else{
  2733. srv_proto=PROTO_UDP;
  2734. }
  2735. h->port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
  2736. don't find another */
  2737. h->proto=srv_proto; /* store initial protocol */
  2738. if (port){
  2739. if (*port==0){
  2740. /* try SRV if initial call & no port specified
  2741. * (draft-ietf-sip-srv-06) */
  2742. if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
  2743. LOG(L_WARN, "WARNING: dns_sip_resolvehost: domain name too"
  2744. " long (%d), unable to perform SRV lookup\n",
  2745. name->len);
  2746. }else{
  2747. /* check if it's an ip address */
  2748. if ( ((tmp_ip=str2ip(name))!=0)
  2749. #ifdef USE_IPV6
  2750. || ((tmp_ip=str2ip6(name))!=0)
  2751. #endif
  2752. ){
  2753. /* we are lucky, this is an ip address */
  2754. #ifdef USE_IPV6
  2755. if (((flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
  2756. ((flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
  2757. return -E_DNS_AF_MISMATCH;
  2758. }
  2759. #endif
  2760. *ip=*tmp_ip;
  2761. *port=h->port;
  2762. /* proto already set */
  2763. return 0;
  2764. }
  2765. switch(srv_proto){
  2766. case PROTO_NONE: /* no proto specified, use udp */
  2767. if (proto)
  2768. *proto=PROTO_UDP;
  2769. /* no break */
  2770. case PROTO_UDP:
  2771. memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
  2772. memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
  2773. tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
  2774. len=SRV_UDP_PREFIX_LEN + name->len;
  2775. break;
  2776. case PROTO_TCP:
  2777. memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
  2778. memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
  2779. tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
  2780. len=SRV_TCP_PREFIX_LEN + name->len;
  2781. break;
  2782. case PROTO_TLS:
  2783. memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
  2784. memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
  2785. tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
  2786. len=SRV_TLS_PREFIX_LEN + name->len;
  2787. break;
  2788. case PROTO_SCTP:
  2789. memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
  2790. memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
  2791. tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
  2792. len=SRV_SCTP_PREFIX_LEN + name->len;
  2793. break;
  2794. default:
  2795. LOG(L_CRIT, "BUG: sip_resolvehost: "
  2796. "unknown proto %d\n", (int)srv_proto);
  2797. return -E_DNS_CRITICAL;
  2798. }
  2799. srv_name.s=tmp;
  2800. srv_name.len=len;
  2801. if ((ret=dns_srv_resolve_ip(h, &srv_name, ip,
  2802. port, flags))>=0)
  2803. {
  2804. #ifdef DNS_CACHE_DEBUG
  2805. DBG("dns_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
  2806. name->len, name->s, h->srv_no, h->ip_no, ret);
  2807. #endif
  2808. /* proto already set */
  2809. return ret;
  2810. }
  2811. }
  2812. }else{ /* if (*port==0) */
  2813. h->port=*port; /* store initial port */
  2814. /* proto already set */
  2815. }
  2816. } /* if (port) */
  2817. }else if (h->srv){
  2818. srv_name.s=h->srv->name;
  2819. srv_name.len=h->srv->name_len;
  2820. /* continue srv resolving */
  2821. ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags);
  2822. if (proto)
  2823. *proto=h->proto;
  2824. DBG("dns_sip_resolve(%.*s, %d, %d), srv, ret=%d\n",
  2825. name->len, name->s, h->srv_no, h->ip_no, ret);
  2826. return ret;
  2827. }
  2828. /*skip_srv:*/
  2829. if (name->len >= MAX_DNS_NAME) {
  2830. LOG(L_ERR, "dns_sip_resolve: domain name too long\n");
  2831. return -E_DNS_NAME_TOO_LONG;
  2832. }
  2833. ret=dns_ip_resolve(&h->a, &h->ip_no, name, ip, flags);
  2834. if (port)
  2835. *port=h->port;
  2836. if (proto)
  2837. *proto=h->proto;
  2838. #ifdef DNS_CACHE_DEBUG
  2839. DBG("dns_sip_resolve(%.*s, %d, %d), ip, ret=%d\n",
  2840. name->len, name->s, h->srv_no, h->ip_no, ret);
  2841. #endif
  2842. return ret;
  2843. }
  2844. #ifdef USE_NAPTR
  2845. /* resolves a host name trying:
  2846. * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
  2847. * *port==0 and *proto=0 and if flags allow NAPTR lookups
  2848. * -SRV lookup if port!=0 and *port==0
  2849. * - normal A/AAAA lookup if *port!=0, or port==0
  2850. * when performing SRV lookup (*port==0) it will use proto to look for
  2851. * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
  2852. * h must be initialized prior to calling this function and can be used to
  2853. * get the subsequent ips
  2854. * returns: <0 on error
  2855. * 0 on success and it fills *ip, *port, dns_sip_resolve_h
  2856. * WARNING: when finished, dns_sip_resolve_put(h) must be called!
  2857. */
  2858. inline static int dns_naptr_sip_resolve(struct dns_srv_handle* h, str* name,
  2859. struct ip_addr* ip, unsigned short* port, char* proto,
  2860. int flags)
  2861. {
  2862. struct hostent* he;
  2863. struct ip_addr* tmp_ip;
  2864. naptr_bmp_t tried_bmp;
  2865. struct dns_hash_entry* e;
  2866. char n_proto;
  2867. str srv_name;
  2868. int ret;
  2869. ret=-E_DNS_NO_NAPTR;
  2870. if (dns_hash==0){ /* not init => use normal, non-cached version */
  2871. LOG(L_WARN, "WARNING: dns_sip_resolve: called before dns cache"
  2872. " initialization\n");
  2873. h->srv=h->a=0;
  2874. he=_sip_resolvehost(name, port, proto);
  2875. if (he){
  2876. hostent2ip_addr(ip, he, 0);
  2877. return 0;
  2878. }
  2879. return -E_DNS_NO_NAPTR;
  2880. }
  2881. if (((h->srv==0) && (h->a==0)) && /* first call */
  2882. proto && port && (*proto==0) && (*port==0)){
  2883. *proto=PROTO_UDP; /* just in case we don't find another */
  2884. /* check if it's an ip address */
  2885. if ( ((tmp_ip=str2ip(name))!=0)
  2886. #ifdef USE_IPV6
  2887. || ((tmp_ip=str2ip6(name))!=0)
  2888. #endif
  2889. ){
  2890. /* we are lucky, this is an ip address */
  2891. #ifdef USE_IPV6
  2892. if (((flags&DNS_IPV4_ONLY) && (tmp_ip->af==AF_INET6))||
  2893. ((flags&DNS_IPV6_ONLY) && (tmp_ip->af==AF_INET))){
  2894. return -E_DNS_AF_MISMATCH;
  2895. }
  2896. #endif
  2897. *ip=*tmp_ip;
  2898. h->port=SIP_PORT;
  2899. h->proto=*proto;
  2900. *port=h->port;
  2901. return 0;
  2902. }
  2903. /* do naptr lookup */
  2904. if ((e=dns_get_entry(name, T_NAPTR))==0)
  2905. goto naptr_not_found;
  2906. naptr_iterate_init(&tried_bmp);
  2907. while(dns_naptr_sip_iterate(e->rr_lst, &tried_bmp,
  2908. &srv_name, &n_proto)){
  2909. dns_srv_handle_init(h); /* make sure h does not contain garbage
  2910. from previous dns_srv_sip_resolve calls */
  2911. if ((ret=dns_srv_resolve_ip(h, &srv_name, ip, port, flags))>=0){
  2912. #ifdef DNS_CACHE_DEBUG
  2913. DBG("dns_naptr_sip_resolve(%.*s, %d, %d), srv0, ret=%d\n",
  2914. name->len, name->s, h->srv_no, h->ip_no, ret);
  2915. #endif
  2916. dns_hash_put(e);
  2917. *proto=n_proto;
  2918. h->proto=*proto;
  2919. return ret;
  2920. }
  2921. }
  2922. /* no acceptable naptr record found, fallback to srv */
  2923. dns_hash_put(e);
  2924. dns_srv_handle_init(h); /* make sure h does not contain garbage
  2925. from previous dns_srv_sip_resolve calls */
  2926. }
  2927. naptr_not_found:
  2928. return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
  2929. }
  2930. #endif /* USE_NAPTR */
  2931. /* resolves a host name trying:
  2932. * - NAPTR lookup if the address is not an ip and proto!=0, port!=0
  2933. * *port==0 and *proto=0 and if flags allow NAPTR lookups
  2934. * -SRV lookup if port!=0 and *port==0
  2935. * - normal A/AAAA lookup if *port!=0, or port==0
  2936. * when performing SRV lookup (*port==0) it will use proto to look for
  2937. * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
  2938. * h must be initialized prior to calling this function and can be used to
  2939. * get the subsequent ips
  2940. * returns: <0 on error
  2941. * 0 on success and it fills *ip, *port, dns_sip_resolve_h
  2942. * WARNING: when finished, dns_sip_resolve_put(h) must be called!
  2943. */
  2944. int dns_sip_resolve(struct dns_srv_handle* h, str* name,
  2945. struct ip_addr* ip, unsigned short* port, char* proto,
  2946. int flags)
  2947. {
  2948. #ifdef USE_NAPTR
  2949. if (flags&DNS_TRY_NAPTR)
  2950. return dns_naptr_sip_resolve(h, name, ip, port, proto, flags);
  2951. #endif
  2952. return dns_srv_sip_resolve(h, name, ip, port, proto, flags);
  2953. }
  2954. /* performs an a lookup and fills ip with the first good ip address
  2955. * returns 0 on success, <0 on error (see the error codes)
  2956. */
  2957. inline static int dns_a_get_ip(str* name, struct ip_addr* ip)
  2958. {
  2959. struct dns_hash_entry* e;
  2960. int ret;
  2961. unsigned char rr_no;
  2962. e=0;
  2963. rr_no=0;
  2964. ret=dns_a_resolve(&e, &rr_no, name, ip);
  2965. if (e) dns_hash_put(e);
  2966. return ret;
  2967. }
  2968. #ifdef USE_IPV6
  2969. inline static int dns_aaaa_get_ip(str* name, struct ip_addr* ip)
  2970. {
  2971. struct dns_hash_entry* e;
  2972. int ret;
  2973. unsigned char rr_no;
  2974. e=0;
  2975. rr_no=0;
  2976. ret=dns_aaaa_resolve(&e, &rr_no, name, ip);
  2977. if (e) dns_hash_put(e);
  2978. return ret;
  2979. }
  2980. #endif /* USE_IPV6 */
  2981. /* performs an a or aaaa dns lookup, returns <0 on error (see the
  2982. * dns error codes) and 0 on success
  2983. * flags: - none set: tries first an a_lookup and if it fails an aaaa_lookup
  2984. * - DNS_IPV6_FIRST: tries first an aaaa_lookup and then an a_lookup
  2985. * - DNS_IPV4_ONLY: tries only an a_lookup
  2986. * - DNS_IPV6_ONLY: tries only an aaaa_lookup
  2987. */
  2988. int dns_get_ip(str* name, struct ip_addr* ip, int flags)
  2989. {
  2990. int ret;
  2991. struct dns_hash_entry* e;
  2992. unsigned char rr_no;
  2993. e=0;
  2994. rr_no=0;
  2995. ret=dns_ip_resolve(&e, &rr_no, name, ip, flags);
  2996. if (e)
  2997. dns_hash_put(e);
  2998. return ret;
  2999. }
  3000. /* fast "inline" version, gets the first good ip:port */
  3001. int dns_srv_get_ip(str* name, struct ip_addr* ip, unsigned short* port,
  3002. int flags)
  3003. {
  3004. int ret;
  3005. struct dns_srv_handle h;
  3006. dns_srv_handle_init(&h);
  3007. ret=dns_srv_resolve_ip(&h, name, ip, port, flags);
  3008. dns_srv_handle_put(&h);
  3009. return ret;
  3010. }
  3011. #ifdef DNS_WATCHDOG_SUPPORT
  3012. /* sets the state of the DNS servers:
  3013. * 1: at least one server is up
  3014. * 0: all the servers are down
  3015. */
  3016. void dns_set_server_state(int state)
  3017. {
  3018. atomic_set(dns_servers_up, state);
  3019. }
  3020. /* returns the state of the DNS servers */
  3021. int dns_get_server_state(void)
  3022. {
  3023. return atomic_get(dns_servers_up);
  3024. }
  3025. #endif /* DNS_WATCHDOG_SUPPORT */
  3026. /* rpc functions */
  3027. void dns_cache_mem_info(rpc_t* rpc, void* ctx)
  3028. {
  3029. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3030. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3031. return;
  3032. }
  3033. rpc->add(ctx, "dd", *dns_cache_mem_used, cfg_get(core, core_cfg, dns_cache_max_mem));
  3034. }
  3035. void dns_cache_debug(rpc_t* rpc, void* ctx)
  3036. {
  3037. int h;
  3038. struct dns_hash_entry* e;
  3039. ticks_t now;
  3040. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3041. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3042. return;
  3043. }
  3044. now=get_ticks_raw();
  3045. LOCK_DNS_HASH();
  3046. for (h=0; h<DNS_HASH_SIZE; h++){
  3047. clist_foreach(&dns_hash[h], e, next){
  3048. rpc->add(ctx, "sdddddd",
  3049. e->name, e->type, e->total_size, e->refcnt.val,
  3050. (s_ticks_t)(e->expire-now)<0?-1:
  3051. TICKS_TO_S(e->expire-now),
  3052. TICKS_TO_S(now-e->last_used),
  3053. e->err_flags);
  3054. }
  3055. }
  3056. UNLOCK_DNS_HASH();
  3057. }
  3058. #ifdef USE_DNS_CACHE_STATS
  3059. static unsigned long stat_sum(int ivar, int breset)
  3060. {
  3061. unsigned long isum=0;
  3062. int i1=0;
  3063. for (; i1 < get_max_procs(); i1++)
  3064. switch (ivar) {
  3065. case 0:
  3066. isum+=dns_cache_stats[i1].dns_req_cnt;
  3067. if (breset)
  3068. dns_cache_stats[i1].dns_req_cnt=0;
  3069. break;
  3070. case 1:
  3071. isum+=dns_cache_stats[i1].dc_hits_cnt;
  3072. if (breset)
  3073. dns_cache_stats[i1].dc_hits_cnt=0;
  3074. break;
  3075. case 2:
  3076. isum+=dns_cache_stats[i1].dc_neg_hits_cnt;
  3077. if (breset)
  3078. dns_cache_stats[i1].dc_neg_hits_cnt=0;
  3079. break;
  3080. case 3:
  3081. isum+=dns_cache_stats[i1].dc_lru_cnt;
  3082. if (breset)
  3083. dns_cache_stats[i1].dc_lru_cnt=0;
  3084. break;
  3085. }
  3086. return isum;
  3087. }
  3088. void dns_cache_stats_get(rpc_t* rpc, void* c)
  3089. {
  3090. char *name=NULL;
  3091. void *handle;
  3092. int found=0,i=0;
  3093. int reset=0;
  3094. char* dns_cache_stats_names[] = {
  3095. "dns_req_cnt",
  3096. "dc_hits_cnt",
  3097. "dc_neg_hits_cnt",
  3098. "dc_lru_cnt",
  3099. NULL
  3100. };
  3101. if (!cfg_get(core, core_cfg, use_dns_cache)) {
  3102. rpc->fault(c, 500, "dns cache support disabled");
  3103. return;
  3104. }
  3105. if (rpc->scan(c, "s", &name) < 0)
  3106. return;
  3107. if (rpc->scan(c, "d", &reset) < 0)
  3108. return;
  3109. if (!strcasecmp(name, DNS_CACHE_ALL_STATS)) {
  3110. /* dump all the dns cache stat values */
  3111. rpc->add(c, "{", &handle);
  3112. for (i=0; dns_cache_stats_names[i]; i++)
  3113. rpc->struct_add(handle, "d",
  3114. dns_cache_stats_names[i],
  3115. stat_sum(i, reset));
  3116. found=1;
  3117. } else {
  3118. for (i=0; dns_cache_stats_names[i]; i++)
  3119. if (!strcasecmp(dns_cache_stats_names[i], name)) {
  3120. rpc->add(c, "{", &handle);
  3121. rpc->struct_add(handle, "d",
  3122. dns_cache_stats_names[i],
  3123. stat_sum(i, reset));
  3124. found=1;
  3125. break;
  3126. }
  3127. }
  3128. if(!found)
  3129. rpc->fault(c, 500, "unknown dns cache stat parameter");
  3130. return;
  3131. }
  3132. #endif /* USE_DNS_CACHE_STATS */
  3133. /* rpc functions */
  3134. void dns_cache_debug_all(rpc_t* rpc, void* ctx)
  3135. {
  3136. int h;
  3137. struct dns_hash_entry* e;
  3138. struct dns_rr* rr;
  3139. struct ip_addr ip;
  3140. int i;
  3141. ticks_t now;
  3142. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3143. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3144. return;
  3145. }
  3146. now=get_ticks_raw();
  3147. LOCK_DNS_HASH();
  3148. for (h=0; h<DNS_HASH_SIZE; h++){
  3149. clist_foreach(&dns_hash[h], e, next){
  3150. for (i=0, rr=e->rr_lst; rr; i++, rr=rr->next){
  3151. rpc->add(ctx, "sddddddd",
  3152. e->name, (int)e->type, i, (int)e->total_size,
  3153. (int)e->refcnt.val,
  3154. (int)(s_ticks_t)(e->expire-now)<0?-1:
  3155. TICKS_TO_S(e->expire-now),
  3156. (int)TICKS_TO_S(now-e->last_used),
  3157. (int)e->err_flags);
  3158. switch(e->type){
  3159. case T_A:
  3160. case T_AAAA:
  3161. if (dns_rr2ip(e->type, rr, &ip)==0){
  3162. rpc->add(ctx, "ss", "ip", ip_addr2a(&ip) );
  3163. }else{
  3164. rpc->add(ctx, "ss", "ip", "<error: bad rr>");
  3165. }
  3166. break;
  3167. case T_SRV:
  3168. rpc->add(ctx, "ss", "srv",
  3169. ((struct srv_rdata*)(rr->rdata))->name);
  3170. break;
  3171. case T_NAPTR:
  3172. rpc->add(ctx, "ss", "naptr ",
  3173. ((struct naptr_rdata*)(rr->rdata))->flags);
  3174. break;
  3175. case T_CNAME:
  3176. rpc->add(ctx, "ss", "cname",
  3177. ((struct cname_rdata*)(rr->rdata))->name);
  3178. break;
  3179. default:
  3180. rpc->add(ctx, "ss", "unknown", "?");
  3181. }
  3182. rpc->add(ctx, "dd",
  3183. (int)(s_ticks_t)(rr->expire-now)<0?-1:
  3184. TICKS_TO_S(rr->expire-now),
  3185. (int)rr->err_flags);
  3186. }
  3187. }
  3188. }
  3189. UNLOCK_DNS_HASH();
  3190. }
  3191. static char *print_type(unsigned short type)
  3192. {
  3193. switch (type) {
  3194. case T_A:
  3195. return "A";
  3196. case T_AAAA:
  3197. return "AAAA";
  3198. case T_SRV:
  3199. return "SRV";
  3200. case T_NAPTR:
  3201. return "NAPTR";
  3202. case T_CNAME:
  3203. return "CNAME";
  3204. default:
  3205. return "unkown";
  3206. }
  3207. }
  3208. /* dumps the content of the cache in a human-readable format */
  3209. void dns_cache_view(rpc_t* rpc, void* ctx)
  3210. {
  3211. int h;
  3212. int expires;
  3213. struct dns_hash_entry* e;
  3214. struct dns_rr* rr;
  3215. struct ip_addr ip;
  3216. ticks_t now;
  3217. str s;
  3218. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3219. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3220. return;
  3221. }
  3222. now=get_ticks_raw();
  3223. LOCK_DNS_HASH();
  3224. for (h=0; h<DNS_HASH_SIZE; h++){
  3225. clist_foreach(&dns_hash[h], e, next){
  3226. expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
  3227. if (expires < 0) {
  3228. continue;
  3229. }
  3230. rpc->printf(ctx, "{\n%sname: %s", SPACE_FORMAT, e->name);
  3231. rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
  3232. rpc->printf(ctx, "%ssize (bytes): %d", SPACE_FORMAT,
  3233. e->total_size);
  3234. rpc->printf(ctx, "%sreference counter: %d", SPACE_FORMAT,
  3235. e->refcnt.val);
  3236. rpc->printf(ctx, "%sexpires in (s): %d", SPACE_FORMAT, expires);
  3237. rpc->printf(ctx, "%slast used (s): %d", SPACE_FORMAT,
  3238. TICKS_TO_S(now-e->last_used));
  3239. rpc->printf(ctx, "%serror flags: %d", SPACE_FORMAT, e->err_flags);
  3240. for (rr=e->rr_lst; rr; rr=rr->next) {
  3241. switch(e->type) {
  3242. case T_A:
  3243. case T_AAAA:
  3244. if (dns_rr2ip(e->type, rr, &ip)==0){
  3245. rpc->printf(ctx, "%srr ip: %s", SPACE_FORMAT,
  3246. ip_addr2a(&ip) );
  3247. }else{
  3248. rpc->printf(ctx, "%srr ip: <error: bad rr>",
  3249. SPACE_FORMAT);
  3250. }
  3251. break;
  3252. case T_SRV:
  3253. rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
  3254. ((struct srv_rdata*)(rr->rdata))->name);
  3255. rpc->printf(ctx, "%srr port: %d", SPACE_FORMAT,
  3256. ((struct srv_rdata*)(rr->rdata))->port);
  3257. rpc->printf(ctx, "%srr priority: %d", SPACE_FORMAT,
  3258. ((struct srv_rdata*)(rr->rdata))->priority);
  3259. rpc->printf(ctx, "%srr weight: %d", SPACE_FORMAT,
  3260. ((struct srv_rdata*)(rr->rdata))->weight);
  3261. break;
  3262. case T_NAPTR:
  3263. rpc->printf(ctx, "%srr order: %d", SPACE_FORMAT,
  3264. ((struct naptr_rdata*)(rr->rdata))->order);
  3265. rpc->printf(ctx, "%srr preference: %d", SPACE_FORMAT,
  3266. ((struct naptr_rdata*)(rr->rdata))->pref);
  3267. s.s = ((struct naptr_rdata*)(rr->rdata))->flags;
  3268. s.len = ((struct naptr_rdata*)(rr->rdata))->flags_len;
  3269. rpc->printf(ctx, "%srr flags: %.*s", SPACE_FORMAT,
  3270. s.len, s.s);
  3271. s.s=((struct naptr_rdata*)(rr->rdata))->services;
  3272. s.len=((struct naptr_rdata*)(rr->rdata))->services_len;
  3273. rpc->printf(ctx, "%srr service: %.*s", SPACE_FORMAT,
  3274. s.len, s.s);
  3275. s.s = ((struct naptr_rdata*)(rr->rdata))->regexp;
  3276. s.len = ((struct naptr_rdata*)(rr->rdata))->regexp_len;
  3277. rpc->printf(ctx, "%srr regexp: %.*s", SPACE_FORMAT,
  3278. s.len, s.s);
  3279. s.s = ((struct naptr_rdata*)(rr->rdata))->repl;
  3280. s.len = ((struct naptr_rdata*)(rr->rdata))->repl_len;
  3281. rpc->printf(ctx, "%srr replacement: %.*s",
  3282. SPACE_FORMAT, s.len, s.s);
  3283. break;
  3284. case T_CNAME:
  3285. rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
  3286. ((struct cname_rdata*)(rr->rdata))->name);
  3287. break;
  3288. default:
  3289. rpc->printf(ctx, "%sresource record: unknown",
  3290. SPACE_FORMAT);
  3291. }
  3292. rpc->printf(ctx, "%srr expires in (s): %d", SPACE_FORMAT,
  3293. (s_ticks_t)(rr->expire-now)<0?-1 :
  3294. TICKS_TO_S(rr->expire-now));
  3295. rpc->printf(ctx, "%srr error flags: %d", SPACE_FORMAT,
  3296. rr->err_flags);
  3297. }
  3298. rpc->printf(ctx, "}");
  3299. }
  3300. }
  3301. UNLOCK_DNS_HASH();
  3302. }
  3303. /* deletes all the entries from the cache */
  3304. void dns_cache_flush(void)
  3305. {
  3306. int h;
  3307. struct dns_hash_entry* e;
  3308. struct dns_hash_entry* tmp;
  3309. DBG("dns_cache_flush(): removing elements from the cache\n");
  3310. LOCK_DNS_HASH();
  3311. for (h=0; h<DNS_HASH_SIZE; h++){
  3312. clist_foreach_safe(&dns_hash[h], e, tmp, next){
  3313. _dns_hash_remove(e);
  3314. }
  3315. }
  3316. UNLOCK_DNS_HASH();
  3317. }
  3318. /* deletes all the entries from the cache */
  3319. void dns_cache_delete_all(rpc_t* rpc, void* ctx)
  3320. {
  3321. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3322. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3323. return;
  3324. }
  3325. dns_cache_flush();
  3326. }
  3327. /* clones an entry and extends its memory area to hold a new rr.
  3328. * if rdata_size>0 the new dns_rr struct is initialized, but the rdata is
  3329. * only filled with 0.
  3330. */
  3331. static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
  3332. int rdata_size,
  3333. int ttl,
  3334. struct dns_rr **_new_rr)
  3335. {
  3336. struct dns_hash_entry *new;
  3337. struct dns_rr *rr, *last_rr, *new_rr;
  3338. int size, rounded_size, rr_size;
  3339. ticks_t now;
  3340. now=get_ticks_raw();
  3341. size = e->total_size;
  3342. if (rdata_size) {
  3343. /* we have to extend the entry */
  3344. rounded_size = ROUND_POINTER(size); /* size may not have been
  3345. rounded previously */
  3346. switch (e->type) {
  3347. case T_A:
  3348. case T_AAAA:
  3349. case T_CNAME:
  3350. rr_size = sizeof(struct dns_rr);
  3351. break;
  3352. case T_SRV:
  3353. rr_size = ROUND_SHORT(sizeof(struct dns_rr));
  3354. break;
  3355. case T_NAPTR:
  3356. rr_size = ROUND_POINTER(sizeof(struct dns_rr));
  3357. break;
  3358. default:
  3359. LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not "
  3360. "supported\n", e->type);
  3361. return NULL;
  3362. }
  3363. } else {
  3364. rounded_size = size; /* no need to round the size, we just clone
  3365. the entry without extending it */
  3366. rr_size = 0;
  3367. }
  3368. new=shm_malloc(rounded_size+rr_size+rdata_size);
  3369. if (!new) {
  3370. LOG(L_ERR, "ERROR: dns_cache_clone_entry: out of memory\n");
  3371. return NULL;
  3372. }
  3373. memset(new, 0, rounded_size+rr_size+rdata_size);
  3374. /* clone the entry */
  3375. memcpy(new, e, size);
  3376. /* fix the values and pointers */
  3377. new->next = new->prev = NULL;
  3378. #ifdef DNS_LU_LST
  3379. new->last_used_lst.next = new->last_used_lst.next = NULL;
  3380. #endif
  3381. new->rr_lst = (struct dns_rr*)translate_pointer((char*)new, (char*)e,
  3382. (char*)new->rr_lst);
  3383. atomic_set(&new->refcnt, 0);
  3384. new->last_used = now;
  3385. /* expire and total_size are fixed later if needed */
  3386. /* fix the pointers inside the rr structures */
  3387. last_rr = NULL;
  3388. for (rr=new->rr_lst; rr; rr=rr->next) {
  3389. rr->rdata = (void*)translate_pointer((char*)new, (char*)e,
  3390. (char*)rr->rdata);
  3391. if (rr->next)
  3392. rr->next = (struct dns_rr*)translate_pointer((char*)new, (char*)e,
  3393. (char*)rr->next);
  3394. else
  3395. last_rr = rr;
  3396. if (e->type == T_NAPTR) {
  3397. /* there are pointers inside the NAPTR rdata stucture */
  3398. ((struct naptr_rdata*)rr->rdata)->flags =
  3399. translate_pointer((char*)new, (char*)e,
  3400. ((struct naptr_rdata*)rr->rdata)->flags);
  3401. ((struct naptr_rdata*)rr->rdata)->services =
  3402. translate_pointer((char*)new, (char*)e,
  3403. ((struct naptr_rdata*)rr->rdata)->services);
  3404. ((struct naptr_rdata*)rr->rdata)->regexp =
  3405. translate_pointer((char*)new, (char*)e,
  3406. ((struct naptr_rdata*)rr->rdata)->regexp);
  3407. ((struct naptr_rdata*)rr->rdata)->repl =
  3408. translate_pointer((char*)new, (char*)e,
  3409. ((struct naptr_rdata*)rr->rdata)->repl);
  3410. }
  3411. }
  3412. if (rdata_size) {
  3413. /* set the pointer to the new rr structure */
  3414. new_rr = (void*)((char*)new + rounded_size);
  3415. new_rr->rdata = (void*)((char*)new_rr+rr_size);
  3416. new_rr->expire = now + S_TO_TICKS(ttl);
  3417. /* link the rr to the previous one */
  3418. last_rr->next = new_rr;
  3419. /* fix the total_size and expires values */
  3420. new->total_size=rounded_size+rr_size+rdata_size;
  3421. new->expire = MAX(new->expire, new_rr->expire);
  3422. if (_new_rr)
  3423. *_new_rr = new_rr;
  3424. } else {
  3425. if (_new_rr)
  3426. *_new_rr = NULL;
  3427. }
  3428. return new;
  3429. }
  3430. /* Adds a new record to the cache.
  3431. * If there is an existing record with the same name and value
  3432. * (ip address in case of A/AAAA record, name in case of SRV record)
  3433. * only the remaining fields are updated.
  3434. *
  3435. * Currently only A, AAAA, and SRV records are supported.
  3436. */
  3437. static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
  3438. {
  3439. struct dns_hash_entry *old=NULL, *new=NULL;
  3440. struct dns_rr *rr;
  3441. str name;
  3442. int ttl;
  3443. str ip, rr_name;
  3444. int flags;
  3445. struct ip_addr *ip_addr;
  3446. int priority, weight, port;
  3447. ticks_t expire;
  3448. int err, h;
  3449. int size;
  3450. /* eliminate gcc warnings */
  3451. ip_addr = 0;
  3452. size = 0;
  3453. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3454. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3455. return;
  3456. }
  3457. switch(type) {
  3458. case T_A:
  3459. case T_AAAA:
  3460. if (rpc->scan(ctx, "SdSd", &name, &ttl, &ip, &flags) < 4)
  3461. return;
  3462. break;
  3463. case T_SRV:
  3464. if (rpc->scan(ctx, "SddddSd", &name, &ttl, &priority, &weight, &port,
  3465. &rr_name, &flags) < 7)
  3466. return;
  3467. break;
  3468. case T_CNAME:
  3469. case T_NAPTR:
  3470. rpc->fault(ctx, 400, "not implemented");
  3471. return;
  3472. default:
  3473. rpc->fault(ctx, 400, "unknown type");
  3474. return;
  3475. }
  3476. if (!flags) {
  3477. /* fix-up the values */
  3478. switch(type) {
  3479. case T_A:
  3480. ip_addr = str2ip(&ip);
  3481. if (!ip_addr) {
  3482. rpc->fault(ctx, 400, "Malformed ip address");
  3483. goto error;
  3484. }
  3485. break;
  3486. case T_AAAA:
  3487. #ifdef USE_IPV6
  3488. ip_addr = str2ip6(&ip);
  3489. if (!ip_addr) {
  3490. rpc->fault(ctx, 400, "Malformed ip address");
  3491. goto error;
  3492. }
  3493. break;
  3494. #else /* USE_IPV6 */
  3495. rpc->fault(ctx, 400, "IPv6 support disabled ");
  3496. return;
  3497. #endif /* USE_IPV6 */
  3498. /* case T_SRV: nothing to do */
  3499. }
  3500. }
  3501. /* check whether there is a matching entry in the cache */
  3502. old = dns_hash_get(&name, type, &h, &err);
  3503. if (old && old->type!=type) {
  3504. /* probably we found a CNAME instead of the specified type,
  3505. it is not needed */
  3506. dns_hash_put(old);
  3507. old=NULL;
  3508. }
  3509. /* prepare the entry */
  3510. if (flags) {
  3511. /* negative entry */
  3512. new = dns_cache_mk_bad_entry(&name, type, ttl, flags);
  3513. if (!new) {
  3514. rpc->fault(ctx, 400, "Failed to add the entry to the cache");
  3515. goto error;
  3516. }
  3517. } else {
  3518. if (!old || old->err_flags) {
  3519. /* there was no matching entry in the hash table,
  3520. or the entry is a negative record with inefficient space,
  3521. let us create a new one */
  3522. switch(type) {
  3523. case T_A:
  3524. case T_AAAA:
  3525. new = dns_cache_mk_ip_entry(&name, ip_addr);
  3526. if (!new) {
  3527. rpc->fault(ctx, 400, "Failed to add the entry to"
  3528. " the cache");
  3529. goto error;
  3530. }
  3531. /* fix the expiration time, dns_cache_mk_ip_entry() sets it
  3532. * to now-1 */
  3533. expire = get_ticks_raw() + S_TO_TICKS(ttl);
  3534. new->expire = expire;
  3535. new->rr_lst->expire = expire;
  3536. break;
  3537. case T_SRV:
  3538. new = dns_cache_mk_srv_entry(&name, priority, weight, port,
  3539. &rr_name, ttl);
  3540. if (!new) {
  3541. rpc->fault(ctx, 400, "Failed to add the entry to"
  3542. " the cache");
  3543. goto error;
  3544. }
  3545. }
  3546. } else {
  3547. /* we must modify the entry, so better to clone it, modify the new
  3548. * one, and replace the old with the new entry in the hash table,
  3549. * because the entry might be in use (even if the dns hash is
  3550. * locked). The old entry will be removed from the hash and
  3551. * automatically destroyed when its refcnt will be 0*/
  3552. /* check whether there is an rr with the same value */
  3553. for (rr=old->rr_lst; rr; rr=rr->next)
  3554. if ((((type == T_A) || (type == T_AAAA)) &&
  3555. (memcmp(ip_addr->u.addr, ((struct a_rdata*)rr->rdata)->ip,
  3556. ip_addr->len)==0))
  3557. || ((type == T_SRV) &&
  3558. (((struct srv_rdata*)rr->rdata)->name_len == rr_name.len)&&
  3559. (memcmp(rr_name.s, ((struct srv_rdata*)rr->rdata)->name,
  3560. rr_name.len)==0)))
  3561. break;
  3562. if (rr) {
  3563. /* the rr was found in the list */
  3564. new = dns_cache_clone_entry(old, 0, 0, 0);
  3565. if (!new) {
  3566. rpc->fault(ctx, 400, "Failed to add the entry to "
  3567. "the cache");
  3568. goto error;
  3569. }
  3570. /* let the rr point to the new structure */
  3571. rr = (struct dns_rr*)translate_pointer((char*)new, (char*)old,
  3572. (char*)rr);
  3573. if (type == T_SRV) {
  3574. /* fix the priority, weight, and port */
  3575. ((struct srv_rdata*)rr->rdata)->priority = priority;
  3576. ((struct srv_rdata*)rr->rdata)->weight = weight;
  3577. ((struct srv_rdata*)rr->rdata)->port = port;
  3578. }
  3579. /* fix the expire value */
  3580. rr->expire = get_ticks_raw() + S_TO_TICKS(ttl);
  3581. new->expire = 0;
  3582. for (rr=new->rr_lst; rr; rr=rr->next)
  3583. new->expire = MAX(new->expire, rr->expire);
  3584. } else {
  3585. /* there was no matching rr, extend the structure with a new
  3586. * one */
  3587. switch(type) {
  3588. case T_A:
  3589. size = sizeof(struct a_rdata);
  3590. break;
  3591. case T_AAAA:
  3592. size = sizeof(struct aaaa_rdata);
  3593. break;
  3594. case T_SRV:
  3595. size = sizeof(struct srv_rdata)-1 +
  3596. rr_name.len+1;
  3597. break;
  3598. }
  3599. new = dns_cache_clone_entry(old, size, ttl, &rr);
  3600. if (!new) {
  3601. rpc->fault(ctx, 400, "Failed to add the entry to"
  3602. " the cache");
  3603. goto error;
  3604. }
  3605. switch(type) {
  3606. case T_A:
  3607. case T_AAAA:
  3608. memcpy(rr->rdata, ip_addr->u.addr, ip_addr->len);
  3609. break;
  3610. case T_SRV:
  3611. ((struct srv_rdata*)rr->rdata)->priority = priority;
  3612. ((struct srv_rdata*)rr->rdata)->weight = weight;
  3613. ((struct srv_rdata*)rr->rdata)->port = port;
  3614. ((struct srv_rdata*)rr->rdata)->name_len = rr_name.len;
  3615. memcpy(((struct srv_rdata*)rr->rdata)->name, rr_name.s,
  3616. rr_name.len);
  3617. }
  3618. /* maximum expire value has been already fixed by
  3619. * dns_cache_clone_entry() */
  3620. }
  3621. }
  3622. }
  3623. LOCK_DNS_HASH();
  3624. if (dns_cache_add_unsafe(new)) {
  3625. rpc->fault(ctx, 400, "Failed to add the entry to the cache");
  3626. UNLOCK_DNS_HASH();
  3627. goto error;
  3628. } else {
  3629. /* remove the old entry from the list */
  3630. if (old)
  3631. _dns_hash_remove(old);
  3632. }
  3633. UNLOCK_DNS_HASH();
  3634. if (old)
  3635. dns_hash_put(old);
  3636. return;
  3637. error:
  3638. /* leave the old entry in the list, and free the new one */
  3639. if (old)
  3640. dns_hash_put(old);
  3641. if (new)
  3642. dns_destroy_entry(new);
  3643. }
  3644. /* deletes a record from the cache */
  3645. static void dns_cache_delete_record(rpc_t* rpc, void* ctx, unsigned short type)
  3646. {
  3647. struct dns_hash_entry *e;
  3648. str name;
  3649. int err, h, found=0;
  3650. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3651. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3652. return;
  3653. }
  3654. if (rpc->scan(ctx, "S", &name) < 1)
  3655. return;
  3656. LOCK_DNS_HASH();
  3657. e=_dns_hash_find(&name, type, &h, &err);
  3658. if (e && (e->type==type)) {
  3659. _dns_hash_remove(e);
  3660. found = 1;
  3661. }
  3662. UNLOCK_DNS_HASH();
  3663. if (!found)
  3664. rpc->fault(ctx, 400, "Not found");
  3665. }
  3666. /* wrapper functions for adding and deleting records */
  3667. void dns_cache_add_a(rpc_t* rpc, void* ctx)
  3668. {
  3669. dns_cache_add_record(rpc, ctx, T_A);
  3670. }
  3671. void dns_cache_add_aaaa(rpc_t* rpc, void* ctx)
  3672. {
  3673. dns_cache_add_record(rpc, ctx, T_AAAA);
  3674. }
  3675. void dns_cache_add_srv(rpc_t* rpc, void* ctx)
  3676. {
  3677. dns_cache_add_record(rpc, ctx, T_SRV);
  3678. }
  3679. void dns_cache_delete_a(rpc_t* rpc, void* ctx)
  3680. {
  3681. dns_cache_delete_record(rpc, ctx, T_A);
  3682. }
  3683. void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx)
  3684. {
  3685. dns_cache_delete_record(rpc, ctx, T_AAAA);
  3686. }
  3687. void dns_cache_delete_srv(rpc_t* rpc, void* ctx)
  3688. {
  3689. dns_cache_delete_record(rpc, ctx, T_SRV);
  3690. }
  3691. #ifdef DNS_WATCHDOG_SUPPORT
  3692. /* sets the DNS server states */
  3693. void dns_set_server_state_rpc(rpc_t* rpc, void* ctx)
  3694. {
  3695. int state;
  3696. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3697. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3698. return;
  3699. }
  3700. if (rpc->scan(ctx, "d", &state) < 1)
  3701. return;
  3702. dns_set_server_state(state);
  3703. }
  3704. /* prints the DNS server state */
  3705. void dns_get_server_state_rpc(rpc_t* rpc, void* ctx)
  3706. {
  3707. if (!cfg_get(core, core_cfg, use_dns_cache)){
  3708. rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
  3709. return;
  3710. }
  3711. rpc->add(ctx, "d", dns_get_server_state());
  3712. }
  3713. #endif /* DNS_WATCHDOG_SUPPORT */
  3714. #endif