You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. /*
  2. * Copyright (c) 2009-2013, Vsevolod Stakhov
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "dns.h"
  27. #include "dns_private.h"
  28. #include "main.h"
  29. #include "utlist.h"
  30. #include "uthash.h"
  31. #include "ottery.h"
  32. #ifdef HAVE_OPENSSL
  33. #include <openssl/rand.h>
  34. #endif
  35. static void dns_retransmit_handler (gint fd, short what, void *arg);
  36. static guint16
  37. dns_permutor_generate_id (void)
  38. {
  39. guint16 id;
  40. id = ottery_rand_unsigned ();
  41. return id;
  42. }
  43. /* Punycode utility */
  44. static guint
  45. digit (unsigned n)
  46. {
  47. return "abcdefghijklmnopqrstuvwxyz0123456789"[n];
  48. }
  49. static guint
  50. adapt (guint delta, guint numpoints, gint first)
  51. {
  52. guint k;
  53. if (first) {
  54. delta = delta / damp;
  55. }
  56. else {
  57. delta /= 2;
  58. }
  59. delta += delta / numpoints;
  60. k = 0;
  61. while (delta > ((base - t_min) * t_max) / 2) {
  62. delta /= base - t_min;
  63. k += base;
  64. }
  65. return k + (((base - t_min + 1) * delta) / (delta + skew));
  66. }
  67. /**
  68. * Convert an UCS4 string to a puny-coded DNS label string suitable
  69. * when combined with delimiters and other labels for DNS lookup.
  70. *
  71. * @param in an UCS4 string to convert
  72. * @param in_len the length of in.
  73. * @param out the resulting puny-coded string. The string is not NUL
  74. * terminatied.
  75. * @param out_len before processing out_len should be the length of
  76. * the out variable, after processing it will be the length of the out
  77. * string.
  78. *
  79. * @return returns 0 on success, an wind error code otherwise
  80. * @ingroup wind
  81. */
  82. gboolean
  83. punycode_label_toascii(const gunichar *in, gsize in_len, gchar *out,
  84. gsize *out_len)
  85. {
  86. guint n = initial_n;
  87. guint delta = 0;
  88. guint bias = initial_bias;
  89. guint h = 0;
  90. guint b;
  91. guint i;
  92. guint o = 0;
  93. guint m;
  94. for (i = 0; i < in_len; ++i) {
  95. if (in[i] < 0x80) {
  96. ++h;
  97. if (o >= *out_len) {
  98. return FALSE;
  99. }
  100. out[o++] = in[i];
  101. }
  102. }
  103. b = h;
  104. if (b > 0) {
  105. if (o >= *out_len) {
  106. return FALSE;
  107. }
  108. out[o++] = 0x2D;
  109. }
  110. /* is this string punycoded */
  111. if (h < in_len) {
  112. if (o + 4 >= *out_len) {
  113. return FALSE;
  114. }
  115. memmove (out + 4, out, o);
  116. memcpy (out, "xn--", 4);
  117. o += 4;
  118. }
  119. while (h < in_len) {
  120. m = (guint) -1;
  121. for (i = 0; i < in_len; ++i) {
  122. if (in[i] < m && in[i] >= n) {
  123. m = in[i];
  124. }
  125. }
  126. delta += (m - n) * (h + 1);
  127. n = m;
  128. for (i = 0; i < in_len; ++i) {
  129. if (in[i] < n) {
  130. ++delta;
  131. }
  132. else if (in[i] == n) {
  133. guint q = delta;
  134. guint k;
  135. for (k = base;; k += base) {
  136. guint t;
  137. if (k <= bias) {
  138. t = t_min;
  139. }
  140. else if (k >= bias + t_max) {
  141. t = t_max;
  142. }
  143. else {
  144. t = k - bias;
  145. }
  146. if (q < t) {
  147. break;
  148. }
  149. if (o >= *out_len) {
  150. return -1;
  151. }
  152. out[o++] = digit (t + ((q - t) % (base - t)));
  153. q = (q - t) / (base - t);
  154. }
  155. if (o >= *out_len) {
  156. return -1;
  157. }
  158. out[o++] = digit (q);
  159. /* output */
  160. bias = adapt (delta, h + 1, h == b);
  161. delta = 0;
  162. ++h;
  163. }
  164. }
  165. ++delta;
  166. ++n;
  167. }
  168. *out_len = o;
  169. return TRUE;
  170. }
  171. struct dns_request_key {
  172. guint16 id;
  173. guint16 port;
  174. };
  175. /** Message compression */
  176. struct dns_name_table {
  177. guint8 off;
  178. guint8 *label;
  179. guint8 len;
  180. UT_hash_handle hh;
  181. };
  182. static gboolean
  183. try_compress_label (memory_pool_t *pool, guint8 *target, guint8 *start, guint8 len,
  184. guint8 *label, struct dns_name_table **table)
  185. {
  186. struct dns_name_table *found = NULL;
  187. guint16 pointer;
  188. HASH_FIND (hh, *table, label, len, found);
  189. if (found != NULL) {
  190. pointer = htons ((guint16)found->off | 0xC0);
  191. memcpy (target, &pointer, sizeof (pointer));
  192. return TRUE;
  193. }
  194. else {
  195. /* Insert label to list */
  196. found = memory_pool_alloc (pool, sizeof (struct dns_name_table));
  197. found->off = target - start;
  198. found->label = label;
  199. found->len = len;
  200. HASH_ADD_KEYPTR (hh, *table, found->label, len, found);
  201. }
  202. return FALSE;
  203. }
  204. /** Packet creating functions */
  205. static void
  206. allocate_packet (struct rspamd_dns_request *req, guint namelen)
  207. {
  208. namelen += 96 /* header */
  209. + 2 /* Trailing label */
  210. + 4 /* Resource type */
  211. + 11; /* EDNS0 RR */
  212. req->packet = memory_pool_alloc (req->pool, namelen);
  213. req->pos = 0;
  214. req->packet_len = namelen;
  215. }
  216. static void
  217. make_dns_header (struct rspamd_dns_request *req)
  218. {
  219. struct dns_header *header;
  220. /* Set DNS header values */
  221. header = (struct dns_header *)req->packet;
  222. memset (header, 0 , sizeof (struct dns_header));
  223. header->qid = dns_permutor_generate_id ();
  224. header->rd = 1;
  225. header->qdcount = htons (1);
  226. header->arcount = htons (1);
  227. req->pos += sizeof (struct dns_header);
  228. req->id = header->qid;
  229. }
  230. static gboolean
  231. maybe_punycode_label (guint8 *begin, guint8 **res, guint8 **dot, guint *label_len)
  232. {
  233. gboolean ret = FALSE;
  234. guint8 *p = begin;
  235. *dot = NULL;
  236. while (*p) {
  237. if (*p == '.') {
  238. *dot = p;
  239. break;
  240. }
  241. else if ((*p) & 0x80) {
  242. ret = TRUE;
  243. }
  244. p ++;
  245. }
  246. if (*p) {
  247. *res = p - 1;
  248. *label_len = p - begin;
  249. }
  250. else {
  251. *res = p;
  252. *label_len = p - begin;
  253. }
  254. return ret;
  255. }
  256. static void
  257. format_dns_name (struct rspamd_dns_request *req, const gchar *name, guint namelen)
  258. {
  259. guint8 *pos = req->packet + req->pos, *end, *dot, *name_pos, *begin;
  260. guint remain = req->packet_len - req->pos - 5, label_len;
  261. struct dns_name_table *table = NULL;
  262. gunichar *uclabel;
  263. glong uclabel_len;
  264. gsize punylabel_len;
  265. guint8 tmp_label[DNS_D_MAXLABEL];
  266. if (namelen == 0) {
  267. namelen = strlen (name);
  268. }
  269. begin = (guint8 *)name;
  270. end = (guint8 *)name + namelen;
  271. for (;;) {
  272. /* Check label for unicode characters */
  273. if (maybe_punycode_label (begin, &name_pos, &dot, &label_len)) {
  274. /* Convert to ucs4 */
  275. uclabel = g_utf8_to_ucs4_fast ((gchar *)begin, label_len, &uclabel_len);
  276. memory_pool_add_destructor (req->pool, g_free, uclabel);
  277. punylabel_len = DNS_D_MAXLABEL;
  278. punycode_label_toascii (uclabel, uclabel_len, (gchar *)tmp_label, &punylabel_len);
  279. /* Try to compress name */
  280. if (! try_compress_label (req->pool, pos, req->packet, punylabel_len, tmp_label, &table)) {
  281. /* Copy punylabel */
  282. *pos++ = (guint8)punylabel_len;
  283. memcpy (pos, tmp_label, punylabel_len);
  284. pos += punylabel_len;
  285. }
  286. else {
  287. pos += 2;
  288. }
  289. if (dot) {
  290. remain -= label_len + 1;
  291. begin = dot + 1;
  292. }
  293. else {
  294. break;
  295. }
  296. }
  297. else {
  298. if (dot) {
  299. if (label_len > DNS_D_MAXLABEL) {
  300. msg_err ("dns name component is longer than 63 bytes, should be stripped");
  301. label_len = DNS_D_MAXLABEL;
  302. }
  303. if (remain < label_len + 1) {
  304. label_len = remain - 1;
  305. msg_err ("no buffer remain for constructing query, strip to %ud", label_len);
  306. }
  307. if (label_len == 0) {
  308. /* Two dots in order, skip this */
  309. msg_info ("name contains two or more dots in a row, replace it with one dot");
  310. begin = dot + 1;
  311. continue;
  312. }
  313. /* First try to compress name */
  314. if (! try_compress_label (req->pool, pos, req->packet, end - begin, begin, &table)) {
  315. *pos++ = (guint8)label_len;
  316. memcpy (pos, begin, label_len);
  317. pos += label_len;
  318. }
  319. else {
  320. pos += 2;
  321. }
  322. remain -= label_len + 1;
  323. begin = dot + 1;
  324. }
  325. else {
  326. if (label_len == 0) {
  327. /* If name is ended with dot */
  328. break;
  329. }
  330. if (label_len > DNS_D_MAXLABEL) {
  331. msg_err ("dns name component is longer than 63 bytes, should be stripped");
  332. label_len = DNS_D_MAXLABEL;
  333. }
  334. if (remain < label_len + 1) {
  335. label_len = remain - 1;
  336. msg_err ("no buffer remain for constructing query, strip to %ud", label_len);
  337. }
  338. *pos++ = (guint8)label_len;
  339. memcpy (pos, begin, label_len);
  340. pos += label_len;
  341. break;
  342. }
  343. }
  344. if (remain == 0) {
  345. msg_err ("no buffer space available, aborting");
  346. break;
  347. }
  348. }
  349. /* Termination label */
  350. *pos = '\0';
  351. req->pos += pos - (req->packet + req->pos) + 1;
  352. if (table != NULL) {
  353. HASH_CLEAR (hh, table);
  354. }
  355. }
  356. static void
  357. make_ptr_req (struct rspamd_dns_request *req, struct in_addr *addr)
  358. {
  359. gchar ipbuf[sizeof("255.255.255.255.in-addr.arpa")];
  360. guint32 r;
  361. guint16 *p;
  362. guint8 *addr_p = (guint8 *)&addr->s_addr;
  363. r = rspamd_snprintf (ipbuf, sizeof(ipbuf), "%d.%d.%d.%d.in-addr.arpa",
  364. addr_p[3], addr_p[2], addr_p[1], addr_p[0]);
  365. allocate_packet (req, r);
  366. make_dns_header (req);
  367. format_dns_name (req, ipbuf, r);
  368. p = (guint16 *)(req->packet + req->pos);
  369. *p++ = htons (DNS_T_PTR);
  370. *p = htons (DNS_C_IN);
  371. req->requested_name = memory_pool_strdup (req->pool, ipbuf);
  372. req->pos += sizeof (guint16) * 2;
  373. req->type = DNS_REQUEST_PTR;
  374. }
  375. static void
  376. make_a_req (struct rspamd_dns_request *req, const gchar *name)
  377. {
  378. guint16 *p;
  379. allocate_packet (req, strlen (name));
  380. make_dns_header (req);
  381. format_dns_name (req, name, 0);
  382. p = (guint16 *)(req->packet + req->pos);
  383. *p++ = htons (DNS_T_A);
  384. *p = htons (DNS_C_IN);
  385. req->pos += sizeof (guint16) * 2;
  386. req->type = DNS_REQUEST_A;
  387. req->requested_name = name;
  388. }
  389. #ifdef HAVE_INET_PTON
  390. static void
  391. make_aaa_req (struct rspamd_dns_request *req, const gchar *name)
  392. {
  393. guint16 *p;
  394. allocate_packet (req, strlen (name));
  395. make_dns_header (req);
  396. format_dns_name (req, name, 0);
  397. p = (guint16 *)(req->packet + req->pos);
  398. *p++ = htons (DNS_T_AAAA);
  399. *p = htons (DNS_C_IN);
  400. req->pos += sizeof (guint16) * 2;
  401. req->type = DNS_REQUEST_AAA;
  402. req->requested_name = name;
  403. }
  404. #endif
  405. static void
  406. make_txt_req (struct rspamd_dns_request *req, const gchar *name)
  407. {
  408. guint16 *p;
  409. allocate_packet (req, strlen (name));
  410. make_dns_header (req);
  411. format_dns_name (req, name, 0);
  412. p = (guint16 *)(req->packet + req->pos);
  413. *p++ = htons (DNS_T_TXT);
  414. *p = htons (DNS_C_IN);
  415. req->pos += sizeof (guint16) * 2;
  416. req->type = DNS_REQUEST_TXT;
  417. req->requested_name = name;
  418. }
  419. static void
  420. make_mx_req (struct rspamd_dns_request *req, const gchar *name)
  421. {
  422. guint16 *p;
  423. allocate_packet (req, strlen (name));
  424. make_dns_header (req);
  425. format_dns_name (req, name, 0);
  426. p = (guint16 *)(req->packet + req->pos);
  427. *p++ = htons (DNS_T_MX);
  428. *p = htons (DNS_C_IN);
  429. req->pos += sizeof (guint16) * 2;
  430. req->type = DNS_REQUEST_MX;
  431. req->requested_name = name;
  432. }
  433. static void
  434. make_srv_req (struct rspamd_dns_request *req, const gchar *service, const gchar *proto, const gchar *name)
  435. {
  436. guint16 *p;
  437. guint len;
  438. gchar *target;
  439. len = strlen (service) + strlen (proto) + strlen (name) + 5;
  440. allocate_packet (req, len);
  441. make_dns_header (req);
  442. target = memory_pool_alloc (req->pool, len);
  443. len = rspamd_snprintf (target, len, "_%s._%s.%s", service, proto, name);
  444. format_dns_name (req, target, len);
  445. p = (guint16 *)(req->packet + req->pos);
  446. *p++ = htons (DNS_T_SRV);
  447. *p = htons (DNS_C_IN);
  448. req->pos += sizeof (guint16) * 2;
  449. req->type = DNS_REQUEST_SRV;
  450. req->requested_name = name;
  451. }
  452. static void
  453. make_spf_req (struct rspamd_dns_request *req, const gchar *name)
  454. {
  455. guint16 *p;
  456. allocate_packet (req, strlen (name));
  457. make_dns_header (req);
  458. format_dns_name (req, name, 0);
  459. p = (guint16 *)(req->packet + req->pos);
  460. *p++ = htons (DNS_T_SPF);
  461. *p = htons (DNS_C_IN);
  462. req->pos += sizeof (guint16) * 2;
  463. req->type = DNS_REQUEST_SPF;
  464. req->requested_name = name;
  465. }
  466. static void
  467. rspamd_dns_add_edns0 (struct rspamd_dns_request *req)
  468. {
  469. guint8 *p8;
  470. guint16 *p16;
  471. p8 = (guint8 *)(req->packet + req->pos);
  472. *p8 = '\0'; /* Name is root */
  473. p16 = (guint16 *)(req->packet + req->pos + 1);
  474. *p16++ = htons (DNS_T_OPT);
  475. /* UDP packet length */
  476. *p16++ = htons (UDP_PACKET_SIZE);
  477. /* Extended rcode 00 00 */
  478. *p16++ = 0;
  479. /* Z 10000000 00000000 to allow dnssec */
  480. p8 = (guint8 *)p16++;
  481. /* Not a good time for DNSSEC */
  482. *p8 = 0x00;
  483. /* Length */
  484. *p16 = 0;
  485. req->pos += sizeof (guint8) + sizeof (guint16) * 5;
  486. }
  487. static gint
  488. send_dns_request (struct rspamd_dns_request *req)
  489. {
  490. gint r;
  491. struct rspamd_dns_server *serv = req->io->srv;
  492. r = send (req->sock, req->packet, req->pos, 0);
  493. if (r == -1) {
  494. if (errno == EAGAIN) {
  495. event_set (&req->io_event, req->sock, EV_WRITE, dns_retransmit_handler, req);
  496. event_base_set (req->resolver->ev_base, &req->io_event);
  497. event_add (&req->io_event, &req->tv);
  498. register_async_event (req->session, (event_finalizer_t)event_del, &req->io_event,
  499. g_quark_from_static_string ("dns resolver"));
  500. return 0;
  501. }
  502. else {
  503. msg_err ("send failed: %s for server %s", strerror (errno), serv->name);
  504. upstream_fail (&serv->up, req->time);
  505. return -1;
  506. }
  507. }
  508. else if (r < req->pos) {
  509. msg_err ("incomplete send over UDP socket, seems to be internal bug");
  510. event_set (&req->io_event, req->sock, EV_WRITE, dns_retransmit_handler, req);
  511. event_base_set (req->resolver->ev_base, &req->io_event);
  512. event_add (&req->io_event, &req->tv);
  513. register_async_event (req->session, (event_finalizer_t)event_del, &req->io_event,
  514. g_quark_from_static_string ("dns resolver"));
  515. return 0;
  516. }
  517. return 1;
  518. }
  519. static void
  520. dns_fin_cb (gpointer arg)
  521. {
  522. struct rspamd_dns_request *req = arg;
  523. event_del (&req->timer_event);
  524. g_hash_table_remove (req->io->requests, &req->id);
  525. }
  526. static guint8 *
  527. decompress_label (guint8 *begin, guint16 *len, guint16 max)
  528. {
  529. guint16 offset = (*len);
  530. if (offset > max) {
  531. msg_info ("invalid DNS compression pointer: %d max is %d", (gint)offset, (gint)max);
  532. return NULL;
  533. }
  534. *len = *(begin + offset);
  535. return begin + offset;
  536. }
  537. #define UNCOMPRESS_DNS_OFFSET(p) (((*(p)) ^ DNS_COMPRESSION_BITS) << 8) + *((p) + 1)
  538. static guint8 *
  539. dns_request_reply_cmp (struct rspamd_dns_request *req, guint8 *in, gint len)
  540. {
  541. guint8 *p, *c, *l1, *l2;
  542. guint16 len1, len2;
  543. gint decompressed = 0;
  544. /* QR format:
  545. * labels - len:octets
  546. * null label - 0
  547. * class - 2 octets
  548. * type - 2 octets
  549. */
  550. /* In p we would store current position in reply and in c - position in request */
  551. p = in;
  552. c = req->packet + sizeof (struct dns_header);
  553. for (;;) {
  554. /* Get current label */
  555. len1 = *p;
  556. len2 = *c;
  557. if (p - in > len) {
  558. msg_info ("invalid dns reply");
  559. return NULL;
  560. }
  561. /* This may be compressed, so we need to decompress it */
  562. if (len1 & DNS_COMPRESSION_BITS) {
  563. len1 = UNCOMPRESS_DNS_OFFSET(p);
  564. l1 = decompress_label (in, &len1, len);
  565. if (l1 == NULL) {
  566. return NULL;
  567. }
  568. decompressed ++;
  569. l1 ++;
  570. p += 2;
  571. }
  572. else {
  573. l1 = ++p;
  574. p += len1;
  575. }
  576. if (len2 & DNS_COMPRESSION_BITS) {
  577. len2 = UNCOMPRESS_DNS_OFFSET(p);
  578. l2 = decompress_label (req->packet, &len2, len);
  579. if (l2 == NULL) {
  580. msg_info ("invalid DNS pointer");
  581. return NULL;
  582. }
  583. decompressed ++;
  584. l2 ++;
  585. c += 2;
  586. }
  587. else {
  588. l2 = ++c;
  589. c += len2;
  590. }
  591. if (len1 != len2) {
  592. return NULL;
  593. }
  594. if (len1 == 0) {
  595. break;
  596. }
  597. if (memcmp (l1, l2, len1) != 0) {
  598. return NULL;
  599. }
  600. if (decompressed == 2) {
  601. break;
  602. }
  603. }
  604. /* p now points to the end of QR section */
  605. /* Compare class and type */
  606. if (memcmp (p, c, sizeof (guint16) * 2) == 0) {
  607. return p + sizeof (guint16) * 2;
  608. }
  609. return NULL;
  610. }
  611. #define MAX_RECURSION_LEVEL 10
  612. static gboolean
  613. dns_parse_labels (guint8 *in, gchar **target, guint8 **pos, struct rspamd_dns_reply *rep,
  614. gint *remain, gboolean make_name)
  615. {
  616. guint16 namelen = 0;
  617. guint8 *p = *pos, *begin = *pos, *l, *t, *end = *pos + *remain, *new_pos = *pos;
  618. guint16 llen;
  619. gint length = *remain, new_remain = *remain;
  620. gint ptrs = 0, labels = 0;
  621. gboolean got_compression = FALSE;
  622. /* First go through labels and calculate name length */
  623. while (p - begin < length) {
  624. if (ptrs > MAX_RECURSION_LEVEL) {
  625. msg_warn ("dns pointers are nested too much");
  626. return FALSE;
  627. }
  628. llen = *p;
  629. if (llen == 0) {
  630. if (!got_compression) {
  631. /* In case of compression we have already decremented the processing position */
  632. new_remain -= sizeof (guint8);
  633. new_pos += sizeof (guint8);
  634. }
  635. break;
  636. }
  637. else if ((llen & DNS_COMPRESSION_BITS)) {
  638. if (end - p > 1) {
  639. ptrs ++;
  640. llen = UNCOMPRESS_DNS_OFFSET(p);
  641. l = decompress_label (in, &llen, end - in);
  642. if (l == NULL) {
  643. msg_info ("invalid DNS pointer");
  644. return FALSE;
  645. }
  646. if (!got_compression) {
  647. /* Our label processing is finished actually */
  648. new_remain -= sizeof (guint16);
  649. new_pos += sizeof (guint16);
  650. got_compression = TRUE;
  651. }
  652. if (l < in || l > begin + length) {
  653. msg_warn ("invalid pointer in DNS packet");
  654. return FALSE;
  655. }
  656. begin = l;
  657. length = end - begin;
  658. p = l + *l + 1;
  659. namelen += *l;
  660. labels ++;
  661. }
  662. else {
  663. msg_warn ("DNS packet has incomplete compressed label, input length: %d bytes, remain: %d",
  664. *remain, new_remain);
  665. return FALSE;
  666. }
  667. }
  668. else {
  669. namelen += llen;
  670. p += llen + 1;
  671. labels ++;
  672. if (!got_compression) {
  673. new_remain -= llen + 1;
  674. new_pos += llen + 1;
  675. }
  676. }
  677. }
  678. if (!make_name) {
  679. goto end;
  680. }
  681. *target = memory_pool_alloc (rep->request->pool, namelen + labels + 3);
  682. t = (guint8 *)*target;
  683. p = *pos;
  684. begin = *pos;
  685. length = *remain;
  686. /* Now copy labels to name */
  687. while (p - begin < length) {
  688. llen = *p;
  689. if (llen == 0) {
  690. break;
  691. }
  692. else if (llen & DNS_COMPRESSION_BITS) {
  693. llen = UNCOMPRESS_DNS_OFFSET(p);
  694. l = decompress_label (in, &llen, end - in);
  695. begin = l;
  696. length = end - begin;
  697. p = l + *l + 1;
  698. memcpy (t, l + 1, *l);
  699. t += *l;
  700. *t ++ = '.';
  701. }
  702. else {
  703. memcpy (t, p + 1, *p);
  704. t += *p;
  705. *t ++ = '.';
  706. p += *p + 1;
  707. }
  708. }
  709. *(t - 1) = '\0';
  710. end:
  711. *remain = new_remain;
  712. *pos = new_pos;
  713. return TRUE;
  714. }
  715. #define GET16(x) do {(x) = ((*p) << 8) + *(p + 1); p += sizeof (guint16); *remain -= sizeof (guint16); } while(0)
  716. #define GET32(x) do {(x) = ((*p) << 24) + ((*(p + 1)) << 16) + ((*(p + 2)) << 8) + *(p + 3); p += sizeof (guint32); *remain -= sizeof (guint32); } while(0)
  717. #define SKIP(type) do { p += sizeof(type); *remain -= sizeof(type); } while (0)
  718. static gint
  719. dns_parse_rr (guint8 *in, struct rspamd_reply_entry *elt, guint8 **pos, struct rspamd_dns_reply *rep, gint *remain)
  720. {
  721. guint8 *p = *pos, parts;
  722. guint16 type, datalen, txtlen, copied, ttl;
  723. gboolean parsed = FALSE;
  724. /* Skip the whole name */
  725. if (! dns_parse_labels (in, NULL, &p, rep, remain, FALSE)) {
  726. msg_info ("bad RR name");
  727. return -1;
  728. }
  729. if (*remain < (gint)sizeof (guint16) * 6) {
  730. msg_info ("stripped dns reply: %d bytes remain", *remain);
  731. return -1;
  732. }
  733. GET16 (type);
  734. GET16 (ttl);
  735. /* Skip class */
  736. SKIP (guint32);
  737. GET16 (datalen);
  738. /* Now p points to RR data */
  739. switch (type) {
  740. case DNS_T_A:
  741. if (!(datalen & 0x3) && datalen <= *remain) {
  742. memcpy (&elt->content.a.addr, p, sizeof (struct in_addr));
  743. p += datalen;
  744. *remain -= datalen;
  745. parsed = TRUE;
  746. elt->type = DNS_REQUEST_A;
  747. }
  748. else {
  749. msg_info ("corrupted A record");
  750. return -1;
  751. }
  752. break;
  753. #ifdef HAVE_INET_PTON
  754. case DNS_T_AAAA:
  755. if (datalen == sizeof (struct in6_addr) && datalen <= *remain) {
  756. memcpy (&elt->content.aaa.addr, p, sizeof (struct in6_addr));
  757. p += datalen;
  758. *remain -= datalen;
  759. parsed = TRUE;
  760. elt->type = DNS_REQUEST_AAA;
  761. }
  762. else {
  763. msg_info ("corrupted AAAA record");
  764. return -1;
  765. }
  766. break;
  767. #endif
  768. case DNS_T_PTR:
  769. if (! dns_parse_labels (in, &elt->content.ptr.name, &p, rep, remain, TRUE)) {
  770. msg_info ("invalid labels in PTR record");
  771. return -1;
  772. }
  773. parsed = TRUE;
  774. elt->type = DNS_REQUEST_PTR;
  775. break;
  776. case DNS_T_MX:
  777. GET16 (elt->content.mx.priority);
  778. if (! dns_parse_labels (in, &elt->content.mx.name, &p, rep, remain, TRUE)) {
  779. msg_info ("invalid labels in MX record");
  780. return -1;
  781. }
  782. parsed = TRUE;
  783. elt->type = DNS_REQUEST_MX;
  784. break;
  785. case DNS_T_TXT:
  786. case DNS_T_SPF:
  787. elt->content.txt.data = memory_pool_alloc (rep->request->pool, datalen + 1);
  788. /* Now we should compose data from parts */
  789. copied = 0;
  790. parts = 0;
  791. while (copied + parts < datalen) {
  792. txtlen = *p;
  793. if (txtlen + copied + parts <= datalen) {
  794. parts ++;
  795. memcpy (elt->content.txt.data + copied, p + 1, txtlen);
  796. copied += txtlen;
  797. p += txtlen + 1;
  798. *remain -= txtlen + 1;
  799. }
  800. else {
  801. break;
  802. }
  803. }
  804. *(elt->content.txt.data + copied) = '\0';
  805. parsed = TRUE;
  806. elt->type = DNS_REQUEST_TXT;
  807. break;
  808. case DNS_T_SRV:
  809. if (p - *pos > (gint)(*remain - sizeof (guint16) * 3)) {
  810. msg_info ("stripped dns reply while reading SRV record");
  811. return -1;
  812. }
  813. GET16 (elt->content.srv.priority);
  814. GET16 (elt->content.srv.weight);
  815. GET16 (elt->content.srv.port);
  816. if (! dns_parse_labels (in, &elt->content.srv.target, &p, rep, remain, TRUE)) {
  817. msg_info ("invalid labels in SRV record");
  818. return -1;
  819. }
  820. parsed = TRUE;
  821. elt->type = DNS_REQUEST_SRV;
  822. break;
  823. case DNS_T_CNAME:
  824. /* Skip cname records */
  825. p += datalen;
  826. *remain -= datalen;
  827. break;
  828. default:
  829. msg_debug ("unexpected RR type: %d", type);
  830. p += datalen;
  831. *remain -= datalen;
  832. break;
  833. }
  834. *pos = p;
  835. if (parsed) {
  836. elt->ttl = ttl;
  837. return 1;
  838. }
  839. return 0;
  840. }
  841. static gboolean
  842. dns_parse_reply (gint sock, guint8 *in, gint r, struct rspamd_dns_resolver *resolver,
  843. struct rspamd_dns_request **req_out, struct rspamd_dns_reply **_rep)
  844. {
  845. struct dns_header *header = (struct dns_header *)in;
  846. struct rspamd_dns_request *req;
  847. struct rspamd_dns_reply *rep;
  848. struct rspamd_dns_io_channel *ioc;
  849. struct rspamd_reply_entry *elt;
  850. guint8 *pos;
  851. guint16 id;
  852. gint i, t;
  853. /* First check header fields */
  854. if (header->qr == 0) {
  855. msg_info ("got request while waiting for reply");
  856. return FALSE;
  857. }
  858. /* Find io channel */
  859. if ((ioc = g_hash_table_lookup (resolver->io_channels, GINT_TO_POINTER (sock))) == NULL) {
  860. msg_err ("io channel is not found for this resolver: %d", sock);
  861. return FALSE;
  862. }
  863. /* Now try to find corresponding request */
  864. id = header->qid;
  865. if ((req = g_hash_table_lookup (ioc->requests, &id)) == NULL) {
  866. /* No such requests found */
  867. msg_debug ("DNS request with id %d has not been found for IO channel", (gint)id);
  868. return FALSE;
  869. }
  870. *req_out = req;
  871. /*
  872. * Now we have request and query data is now at the end of header, so compare
  873. * request QR section and reply QR section
  874. */
  875. if ((pos = dns_request_reply_cmp (req, in + sizeof (struct dns_header),
  876. r - sizeof (struct dns_header))) == NULL) {
  877. msg_debug ("DNS request with id %d is for different query, ignoring", (gint)id);
  878. return FALSE;
  879. }
  880. /*
  881. * Now pos is in answer section, so we should extract data and form reply
  882. */
  883. rep = memory_pool_alloc (req->pool, sizeof (struct rspamd_dns_reply));
  884. rep->request = req;
  885. rep->entries = NULL;
  886. rep->code = header->rcode;
  887. if (rep->code == DNS_RC_NOERROR) {
  888. r -= pos - in;
  889. /* Extract RR records */
  890. for (i = 0; i < ntohs (header->ancount); i ++) {
  891. elt = memory_pool_alloc (req->pool, sizeof (struct rspamd_reply_entry));
  892. t = dns_parse_rr (in, elt, &pos, rep, &r);
  893. if (t == -1) {
  894. msg_info ("incomplete reply");
  895. break;
  896. }
  897. else if (t == 1) {
  898. DL_APPEND (rep->entries, elt);
  899. }
  900. }
  901. }
  902. *_rep = rep;
  903. return TRUE;
  904. }
  905. static void
  906. dns_throttling_cb (gint fd, short what, void *arg)
  907. {
  908. struct rspamd_dns_resolver *resolver = arg;
  909. resolver->throttling = FALSE;
  910. resolver->errors = 0;
  911. msg_info ("stop DNS throttling after %d seconds", (int)resolver->throttling_time.tv_sec);
  912. event_del (&resolver->throttling_event);
  913. }
  914. static void
  915. dns_check_throttling (struct rspamd_dns_resolver *resolver)
  916. {
  917. if (resolver->errors > resolver->max_errors && !resolver->throttling) {
  918. msg_info ("starting DNS throttling after %ud errors", resolver->errors);
  919. /* Init throttling timeout */
  920. resolver->throttling = TRUE;
  921. evtimer_set (&resolver->throttling_event, dns_throttling_cb, resolver);
  922. event_base_set (resolver->ev_base, &resolver->throttling_event);
  923. event_add (&resolver->throttling_event, &resolver->throttling_time);
  924. }
  925. }
  926. static void
  927. dns_read_cb (gint fd, short what, void *arg)
  928. {
  929. struct rspamd_dns_resolver *resolver = arg;
  930. struct rspamd_dns_request *req = NULL;
  931. gint r;
  932. struct rspamd_dns_reply *rep;
  933. guint8 in[UDP_PACKET_SIZE];
  934. /* This function is called each time when we have data on one of server's sockets */
  935. /* First read packet from socket */
  936. r = read (fd, in, sizeof (in));
  937. if (r > (gint)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
  938. if (dns_parse_reply (fd, in, r, resolver, &req, &rep)) {
  939. /* Decrease errors count */
  940. if (rep->request->resolver->errors > 0) {
  941. rep->request->resolver->errors --;
  942. }
  943. upstream_ok (&rep->request->io->srv->up, rep->request->time);
  944. rep->request->func (rep, rep->request->arg);
  945. remove_normal_event (req->session, dns_fin_cb, req);
  946. }
  947. }
  948. }
  949. static void
  950. dns_timer_cb (gint fd, short what, void *arg)
  951. {
  952. struct rspamd_dns_request *req = arg;
  953. struct rspamd_dns_reply *rep;
  954. struct rspamd_dns_server *serv;
  955. gint r;
  956. /* Retransmit dns request */
  957. req->retransmits ++;
  958. serv = req->io->srv;
  959. if (req->retransmits >= req->resolver->max_retransmits) {
  960. msg_err ("maximum number of retransmits expired for resolving %s of type %s",
  961. req->requested_name, dns_strtype (req->type));
  962. dns_check_throttling (req->resolver);
  963. req->resolver->errors ++;
  964. goto err;
  965. }
  966. if (req->sock == -1) {
  967. goto err;
  968. }
  969. /* Add other retransmit event */
  970. r = send_dns_request (req);
  971. if (r == -1) {
  972. goto err;
  973. }
  974. msg_debug ("retransmit DNS request with ID %d", (int)req->id);
  975. evtimer_add (&req->timer_event, &req->tv);
  976. return;
  977. err:
  978. msg_debug ("error on retransmitting DNS request with ID %d", (int)req->id);
  979. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  980. rep->request = req;
  981. rep->code = DNS_RC_SERVFAIL;
  982. if (serv) {
  983. upstream_fail (&serv->up, rep->request->time);
  984. }
  985. req->func (rep, req->arg);
  986. remove_normal_event (req->session, dns_fin_cb, req);
  987. return;
  988. }
  989. static void
  990. dns_retransmit_handler (gint fd, short what, void *arg)
  991. {
  992. struct rspamd_dns_request *req = arg;
  993. struct rspamd_dns_reply *rep;
  994. struct rspamd_dns_server *serv;
  995. gint r;
  996. remove_normal_event (req->session, (event_finalizer_t)event_del, &req->io_event);
  997. serv = req->io->srv;
  998. if (what == EV_WRITE) {
  999. /* Retransmit dns request */
  1000. req->retransmits ++;
  1001. event_del (&req->io_event);
  1002. if (req->retransmits >= req->resolver->max_retransmits) {
  1003. msg_err ("maximum number of retransmits expired for %s", req->requested_name);
  1004. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  1005. rep->request = req;
  1006. rep->code = DNS_RC_SERVFAIL;
  1007. upstream_fail (&serv->up, rep->request->time);
  1008. req->resolver->errors ++;
  1009. dns_check_throttling (req->resolver);
  1010. req->func (rep, req->arg);
  1011. return;
  1012. }
  1013. r = send_dns_request (req);
  1014. if (r == -1) {
  1015. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  1016. rep->request = req;
  1017. rep->code = DNS_RC_SERVFAIL;
  1018. upstream_fail (&serv->up, rep->request->time);
  1019. req->func (rep, req->arg);
  1020. }
  1021. else if (r == 1) {
  1022. /* Add timer event */
  1023. event_del (&req->timer_event);
  1024. evtimer_set (&req->timer_event, dns_timer_cb, req);
  1025. event_base_set (req->resolver->ev_base, &req->timer_event);
  1026. evtimer_add (&req->timer_event, &req->tv);
  1027. /* Add request to hash table */
  1028. g_hash_table_insert (req->io->requests, &req->id, req);
  1029. register_async_event (req->session, (event_finalizer_t)dns_fin_cb,
  1030. req, g_quark_from_static_string ("dns resolver"));
  1031. }
  1032. }
  1033. }
  1034. gboolean
  1035. make_dns_request (struct rspamd_dns_resolver *resolver,
  1036. struct rspamd_async_session *session, memory_pool_t *pool, dns_callback_type cb,
  1037. gpointer ud, enum rspamd_request_type type, ...)
  1038. {
  1039. va_list args;
  1040. struct rspamd_dns_request *req;
  1041. struct rspamd_dns_server *serv;
  1042. struct in_addr *addr;
  1043. const gchar *name, *service, *proto;
  1044. gint r;
  1045. const gint max_id_cycles = 32;
  1046. struct dns_header *header;
  1047. /* If no DNS servers defined silently return FALSE */
  1048. if (resolver->servers_num == 0) {
  1049. return FALSE;
  1050. }
  1051. /* Check throttling */
  1052. if (resolver->throttling) {
  1053. return FALSE;
  1054. }
  1055. req = memory_pool_alloc (pool, sizeof (struct rspamd_dns_request));
  1056. req->pool = pool;
  1057. req->session = session;
  1058. req->resolver = resolver;
  1059. req->func = cb;
  1060. req->arg = ud;
  1061. req->type = type;
  1062. va_start (args, type);
  1063. switch (type) {
  1064. case DNS_REQUEST_PTR:
  1065. addr = va_arg (args, struct in_addr *);
  1066. make_ptr_req (req, addr);
  1067. break;
  1068. case DNS_REQUEST_MX:
  1069. name = va_arg (args, const gchar *);
  1070. make_mx_req (req, name);
  1071. break;
  1072. case DNS_REQUEST_A:
  1073. name = va_arg (args, const gchar *);
  1074. make_a_req (req, name);
  1075. break;
  1076. case DNS_REQUEST_AAA:
  1077. #ifdef HAVE_INET_PTON
  1078. name = va_arg (args, const gchar *);
  1079. make_aaa_req (req, name);
  1080. break;
  1081. #else
  1082. msg_err ("your system has no ipv6 support, cannot make aaa request");
  1083. break;
  1084. #endif
  1085. case DNS_REQUEST_TXT:
  1086. name = va_arg (args, const gchar *);
  1087. make_txt_req (req, name);
  1088. break;
  1089. case DNS_REQUEST_SPF:
  1090. name = va_arg (args, const gchar *);
  1091. make_spf_req (req, name);
  1092. break;
  1093. case DNS_REQUEST_SRV:
  1094. service = va_arg (args, const gchar *);
  1095. proto = va_arg (args, const gchar *);
  1096. name = va_arg (args, const gchar *);
  1097. make_srv_req (req, service, proto, name);
  1098. break;
  1099. }
  1100. va_end (args);
  1101. /* Add EDNS RR */
  1102. rspamd_dns_add_edns0 (req);
  1103. req->retransmits = 0;
  1104. req->time = time (NULL);
  1105. if (resolver->is_master_slave) {
  1106. serv = (struct rspamd_dns_server *)get_upstream_master_slave (resolver->servers,
  1107. resolver->servers_num, sizeof (struct rspamd_dns_server),
  1108. req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
  1109. }
  1110. else {
  1111. serv = (struct rspamd_dns_server *)get_upstream_round_robin (resolver->servers,
  1112. resolver->servers_num, sizeof (struct rspamd_dns_server),
  1113. req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
  1114. }
  1115. if (serv == NULL) {
  1116. msg_err ("cannot find suitable server for request");
  1117. return FALSE;
  1118. }
  1119. /* Now select IO channel */
  1120. req->io = serv->cur_io_channel;
  1121. if (req->io == NULL) {
  1122. msg_err ("cannot find suitable io channel for the server %s", serv->name);
  1123. return FALSE;
  1124. }
  1125. serv->cur_io_channel = serv->cur_io_channel->next;
  1126. req->sock = req->io->sock;
  1127. if (req->sock == -1) {
  1128. return FALSE;
  1129. }
  1130. /* Fill timeout */
  1131. msec_to_tv (resolver->request_timeout, &req->tv);
  1132. evtimer_set (&req->timer_event, dns_timer_cb, req);
  1133. event_base_set (req->resolver->ev_base, &req->timer_event);
  1134. /* Now send request to server */
  1135. r = send_dns_request (req);
  1136. if (r == 1) {
  1137. /* Add request to hash table */
  1138. r = 0;
  1139. while (g_hash_table_lookup (req->io->requests, &req->id)) {
  1140. /* Check for unique id */
  1141. header = (struct dns_header *)req->packet;
  1142. header->qid = dns_permutor_generate_id ();
  1143. req->id = header->qid;
  1144. if (++r > max_id_cycles) {
  1145. msg_err ("cannot generate new id for server %s", serv->name);
  1146. return FALSE;
  1147. }
  1148. }
  1149. /* Add timer event */
  1150. evtimer_add (&req->timer_event, &req->tv);
  1151. g_hash_table_insert (req->io->requests, &req->id, req);
  1152. register_async_event (session, (event_finalizer_t)dns_fin_cb, req,
  1153. g_quark_from_static_string ("dns resolver"));
  1154. }
  1155. else if (r == -1) {
  1156. return FALSE;
  1157. }
  1158. return TRUE;
  1159. }
  1160. static gboolean
  1161. parse_resolv_conf (struct rspamd_dns_resolver *resolver)
  1162. {
  1163. FILE *r;
  1164. gchar buf[BUFSIZ], *p, addr_holder[16];
  1165. struct rspamd_dns_server *new;
  1166. r = fopen (RESOLV_CONF, "r");
  1167. if (r == NULL) {
  1168. msg_err ("cannot open %s: %s", RESOLV_CONF, strerror (errno));
  1169. return FALSE;
  1170. }
  1171. while (! feof (r)) {
  1172. if (fgets (buf, sizeof (buf), r)) {
  1173. g_strstrip (buf);
  1174. if (g_ascii_strncasecmp (buf, "nameserver", sizeof ("nameserver") - 1) == 0) {
  1175. p = buf + sizeof ("nameserver");
  1176. while (*p && g_ascii_isspace (*p)) {
  1177. p ++;
  1178. }
  1179. if (! *p) {
  1180. msg_warn ("cannot parse empty nameserver line in resolv.conf");
  1181. continue;
  1182. }
  1183. else {
  1184. if (inet_pton (AF_INET6, p, addr_holder) == 1 ||
  1185. inet_pton (AF_INET, p, addr_holder) == 1) {
  1186. new = &resolver->servers[resolver->servers_num];
  1187. new->name = strdup (p);
  1188. resolver->servers_num ++;
  1189. }
  1190. else {
  1191. msg_warn ("cannot parse ip address of nameserver: %s", p);
  1192. continue;
  1193. }
  1194. }
  1195. }
  1196. }
  1197. }
  1198. fclose (r);
  1199. return TRUE;
  1200. }
  1201. /* Hashing utilities */
  1202. static gboolean
  1203. dns_id_equal (gconstpointer v1, gconstpointer v2)
  1204. {
  1205. return *((const guint16*) v1) == *((const guint16*) v2);
  1206. }
  1207. static guint
  1208. dns_id_hash (gconstpointer v)
  1209. {
  1210. return *(const guint16 *) v;
  1211. }
  1212. struct rspamd_dns_resolver *
  1213. dns_resolver_init (struct event_base *ev_base, struct config_file *cfg)
  1214. {
  1215. GList *cur;
  1216. struct rspamd_dns_resolver *new;
  1217. gchar *begin, *p, *err, addr_holder[16];
  1218. gint priority, i, j;
  1219. struct rspamd_dns_server *serv;
  1220. struct rspamd_dns_io_channel *ioc;
  1221. new = g_slice_alloc0 (sizeof (struct rspamd_dns_resolver));
  1222. new->ev_base = ev_base;
  1223. new->io_channels = g_hash_table_new (g_direct_hash, g_direct_equal);
  1224. new->request_timeout = cfg->dns_timeout;
  1225. new->max_retransmits = cfg->dns_retransmits;
  1226. new->max_errors = cfg->dns_throttling_errors;
  1227. msec_to_tv (cfg->dns_throttling_time, &new->throttling_time);
  1228. if (cfg->nameservers == NULL) {
  1229. /* Parse resolv.conf */
  1230. if (! parse_resolv_conf (new) || new->servers_num == 0) {
  1231. msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
  1232. return new;
  1233. }
  1234. }
  1235. else {
  1236. cur = cfg->nameservers;
  1237. while (cur) {
  1238. begin = cur->data;
  1239. p = strchr (begin, ':');
  1240. if (p != NULL) {
  1241. *p = '\0';
  1242. p ++;
  1243. if (!new->is_master_slave) {
  1244. priority = strtoul (p, &err, 10);
  1245. if (err != NULL && (*err == 'm' || *err == 'M' || *err == 's' || *err == 'S')) {
  1246. new->is_master_slave = TRUE;
  1247. }
  1248. else {
  1249. msg_info ("bad character '%c', must be 'm' or 's' or a numeric priority", *err);
  1250. }
  1251. }
  1252. if (new->is_master_slave) {
  1253. if (*p == 'm' || *p == 'M') {
  1254. priority = 100;
  1255. }
  1256. else if (*p == 's' || *p == 'S') {
  1257. priority = 1;
  1258. }
  1259. else {
  1260. msg_info ("master/slave mode is turned on, and %c character is invalid", *p);
  1261. priority = 0;
  1262. }
  1263. }
  1264. }
  1265. else {
  1266. priority = 0;
  1267. }
  1268. serv = &new->servers[new->servers_num];
  1269. if (inet_pton (AF_INET6, p, addr_holder) == 1 ||
  1270. inet_pton (AF_INET, p, addr_holder) == 1) {
  1271. serv->name = strdup (begin);
  1272. serv->up.priority = priority;
  1273. new->servers_num ++;
  1274. }
  1275. else {
  1276. msg_warn ("cannot parse ip address of nameserver: %s", p);
  1277. cur = g_list_next (cur);
  1278. continue;
  1279. }
  1280. cur = g_list_next (cur);
  1281. }
  1282. if (new->servers_num == 0) {
  1283. msg_err ("no valid nameservers defined, try to parse resolv.conf");
  1284. if (! parse_resolv_conf (new) || new->servers_num == 0) {
  1285. msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
  1286. return new;
  1287. }
  1288. }
  1289. }
  1290. /* Now init io channels to all servers */
  1291. for (i = 0; i < new->servers_num; i ++) {
  1292. serv = &new->servers[i];
  1293. for (j = 0; j < (gint)cfg->dns_io_per_server; j ++) {
  1294. ioc = g_slice_alloc0 (sizeof (struct rspamd_dns_io_channel));
  1295. ioc->sock = make_universal_socket (serv->name, dns_port, SOCK_DGRAM, TRUE, FALSE, FALSE);
  1296. if (ioc->sock == -1) {
  1297. msg_warn ("cannot create socket to server %s", serv->name);
  1298. }
  1299. else {
  1300. ioc->requests = g_hash_table_new (dns_id_hash, dns_id_equal);
  1301. ioc->srv = serv;
  1302. ioc->resolver = new;
  1303. event_set (&ioc->ev, ioc->sock, EV_READ | EV_PERSIST, dns_read_cb, new);
  1304. event_base_set (new->ev_base, &ioc->ev);
  1305. event_add (&ioc->ev, NULL);
  1306. CDL_PREPEND (serv->io_channels, ioc);
  1307. serv->cur_io_channel = ioc;
  1308. g_hash_table_insert (new->io_channels, GINT_TO_POINTER (ioc->sock), ioc);
  1309. }
  1310. }
  1311. }
  1312. return new;
  1313. }
  1314. const gchar *
  1315. dns_strerror (enum dns_rcode rcode)
  1316. {
  1317. rcode &= 0xf;
  1318. static gchar numbuf[16];
  1319. if ('\0' == dns_rcodes[rcode][0]) {
  1320. rspamd_snprintf (numbuf, sizeof (numbuf), "UNKNOWN: %d", (gint)rcode);
  1321. return numbuf;
  1322. }
  1323. return dns_rcodes[rcode];
  1324. }
  1325. const gchar *
  1326. dns_strtype (enum rspamd_request_type type)
  1327. {
  1328. return dns_types[type];
  1329. }