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.

dns.c 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275
  1. /*
  2. * Copyright (c) 2009, Rambler media
  3. * Copyright (c) 2008, 2009, 2010 William Ahern
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY Rambler media ''AS IS'' AND ANY
  16. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL Rambler BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /*
  27. * Rspamd resolver library is based on code written by William Ahern.
  28. *
  29. * The original library can be found at: http://25thandclement.com/~william/projects/dns.c.html
  30. */
  31. #include "config.h"
  32. #include "dns.h"
  33. #include "main.h"
  34. /* Upstream timeouts */
  35. #define DEFAULT_UPSTREAM_ERROR_TIME 10
  36. #define DEFAULT_UPSTREAM_DEAD_TIME 300
  37. #define DEFAULT_UPSTREAM_MAXERRORS 10
  38. #ifdef HAVE_ARC4RANDOM
  39. #define DNS_RANDOM arc4random
  40. #elif defined HAVE_RANDOM
  41. #define DNS_RANDOM random
  42. #else
  43. #define DNS_RANDOM rand
  44. #endif
  45. #define UDP_PACKET_SIZE 512
  46. #define DNS_COMPRESSION_BITS 0xC0
  47. /*
  48. * P E R M U T A T I O N G E N E R A T O R
  49. */
  50. #define DNS_K_TEA_BLOCK_SIZE 8
  51. #define DNS_K_TEA_CYCLES 32
  52. #define DNS_K_TEA_MAGIC 0x9E3779B9U
  53. static void dns_retransmit_handler (int fd, short what, void *arg);
  54. static void
  55. dns_k_tea_init(struct dns_k_tea *tea, uint32_t key[], unsigned cycles)
  56. {
  57. memcpy(tea->key, key, sizeof tea->key);
  58. tea->cycles = (cycles)? cycles : DNS_K_TEA_CYCLES;
  59. } /* dns_k_tea_init() */
  60. static void
  61. dns_k_tea_encrypt (struct dns_k_tea *tea, uint32_t v[], uint32_t *w)
  62. {
  63. guint32 y, z, sum, n;
  64. y = v[0];
  65. z = v[1];
  66. sum = 0;
  67. for (n = 0; n < tea->cycles; n++) {
  68. sum += DNS_K_TEA_MAGIC;
  69. y += ((z << 4) + tea->key[0]) ^ (z + sum) ^ ((z >> 5) + tea->key[1]);
  70. z += ((y << 4) + tea->key[2]) ^ (y + sum) ^ ((y >> 5) + tea->key[3]);
  71. }
  72. w[0] = y;
  73. w[1] = z;
  74. } /* dns_k_tea_encrypt() */
  75. /*
  76. * Permutation generator, based on a Luby-Rackoff Feistel construction.
  77. *
  78. * Specifically, this is a generic balanced Feistel block cipher using TEA
  79. * (another block cipher) as the pseudo-random function, F. At best it's as
  80. * strong as F (TEA), notwithstanding the seeding. F could be AES, SHA-1, or
  81. * perhaps Bernstein's Salsa20 core; I am naively trying to keep things
  82. * simple.
  83. *
  84. * The generator can create a permutation of any set of numbers, as long as
  85. * the size of the set is an even power of 2. This limitation arises either
  86. * out of an inherent property of balanced Feistel constructions, or by my
  87. * own ignorance. I'll tackle an unbalanced construction after I wrap my
  88. * head around Schneier and Kelsey's paper.
  89. *
  90. * CAVEAT EMPTOR. IANAC.
  91. */
  92. #define DNS_K_PERMUTOR_ROUNDS 8
  93. static inline unsigned int
  94. dns_k_permutor_powof (unsigned int n)
  95. {
  96. unsigned int m, i = 0;
  97. for (m = 1; m < n; m <<= 1, i++);
  98. return i;
  99. } /* dns_k_permutor_powof() */
  100. static void
  101. dns_k_permutor_init (struct dns_k_permutor *p, unsigned low, unsigned high)
  102. {
  103. uint32_t key[DNS_K_TEA_KEY_SIZE / sizeof (uint32_t)];
  104. unsigned width, i;
  105. p->stepi = 0;
  106. p->length = (high - low) + 1;
  107. p->limit = high;
  108. width = dns_k_permutor_powof (p->length);
  109. width += width % 2;
  110. p->shift = width / 2;
  111. p->mask = (1U << p->shift) - 1;
  112. p->rounds = DNS_K_PERMUTOR_ROUNDS;
  113. for (i = 0; i < G_N_ELEMENTS (key); i++) {
  114. key[i] = DNS_RANDOM ();
  115. }
  116. dns_k_tea_init (&p->tea, key, 0);
  117. } /* dns_k_permutor_init() */
  118. static unsigned
  119. dns_k_permutor_F (struct dns_k_permutor *p, unsigned k, unsigned x)
  120. {
  121. uint32_t in[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)], out[DNS_K_TEA_BLOCK_SIZE / sizeof (uint32_t)];
  122. memset(in, '\0', sizeof in);
  123. in[0] = k;
  124. in[1] = x;
  125. dns_k_tea_encrypt (&p->tea, in, out);
  126. return p->mask & out[0];
  127. } /* dns_k_permutor_F() */
  128. static unsigned
  129. dns_k_permutor_E (struct dns_k_permutor *p, unsigned n)
  130. {
  131. unsigned l[2], r[2];
  132. unsigned i;
  133. i = 0;
  134. l[i] = p->mask & (n >> p->shift);
  135. r[i] = p->mask & (n >> 0);
  136. do {
  137. l[(i + 1) % 2] = r[i % 2];
  138. r[(i + 1) % 2] = l[i % 2] ^ dns_k_permutor_F(p, i, r[i % 2]);
  139. i++;
  140. } while (i < p->rounds - 1);
  141. return ((l[i % 2] & p->mask) << p->shift) | ((r[i % 2] & p->mask) << 0);
  142. } /* dns_k_permutor_E() */
  143. static unsigned
  144. dns_k_permutor_D (struct dns_k_permutor *p, unsigned n)
  145. {
  146. unsigned l[2], r[2];
  147. unsigned i;
  148. i = p->rounds - 1;
  149. l[i % 2] = p->mask & (n >> p->shift);
  150. r[i % 2] = p->mask & (n >> 0);
  151. do {
  152. i--;
  153. r[i % 2] = l[(i + 1) % 2];
  154. l[i % 2] = r[(i + 1) % 2] ^ dns_k_permutor_F(p, i, l[(i + 1) % 2]);
  155. } while (i > 0);
  156. return ((l[i % 2] & p->mask) << p->shift) | ((r[i % 2] & p->mask) << 0);
  157. } /* dns_k_permutor_D() */
  158. static unsigned
  159. dns_k_permutor_step(struct dns_k_permutor *p)
  160. {
  161. unsigned n;
  162. do {
  163. n = dns_k_permutor_E(p, p->stepi++);
  164. } while (n >= p->length);
  165. return n + (p->limit + 1 - p->length);
  166. } /* dns_k_permutor_step() */
  167. /*
  168. * Simple permutation box. Useful for shuffling rrsets from an iterator.
  169. * Uses AES s-box to provide good diffusion.
  170. */
  171. static unsigned short
  172. dns_k_shuffle16 (unsigned short n, unsigned s)
  173. {
  174. static const unsigned char sbox[256] =
  175. { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
  176. 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
  177. 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
  178. 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
  179. 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
  180. 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
  181. 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
  182. 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
  183. 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
  184. 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
  185. 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
  186. 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
  187. 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
  188. 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
  189. 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
  190. 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
  191. 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
  192. 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
  193. 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
  194. 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
  195. 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
  196. 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
  197. 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
  198. 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
  199. 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
  200. 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
  201. 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
  202. 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
  203. 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
  204. 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
  205. 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
  206. 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
  207. unsigned char a, b;
  208. unsigned i;
  209. a = 0xff & (n >> 0);
  210. b = 0xff & (n >> 8);
  211. for (i = 0; i < 4; i++) {
  212. a ^= 0xff & s;
  213. a = sbox[a] ^ b;
  214. b = sbox[b] ^ a;
  215. s >>= 8;
  216. }
  217. return ((0xff00 & (a << 8)) | (0x00ff & (b << 0)));
  218. } /* dns_k_shuffle16() */
  219. struct dns_request_key {
  220. guint16 id;
  221. guint16 port;
  222. };
  223. /** Message compression */
  224. struct dns_name_table {
  225. guint8 off;
  226. guint8 *label;
  227. guint8 len;
  228. };
  229. static gboolean
  230. try_compress_label (memory_pool_t *pool, guint8 *target, guint8 *start, guint8 len, guint8 *label, GList *table)
  231. {
  232. GList *cur;
  233. struct dns_name_table *tbl;
  234. guint16 pointer;
  235. cur = table;
  236. while (cur) {
  237. tbl = cur->data;
  238. if (tbl->len == len) {
  239. if (memcmp (label, tbl->label, len) == 0) {
  240. pointer = htons ((guint16)tbl->off | 0xC0);
  241. memcpy (target, &pointer, sizeof (pointer));
  242. return TRUE;
  243. }
  244. }
  245. cur = g_list_next (cur);
  246. }
  247. /* Insert label to list */
  248. tbl = memory_pool_alloc (pool, sizeof (struct dns_name_table));
  249. tbl->off = target - start;
  250. tbl->label = label;
  251. tbl->len = len;
  252. table = g_list_prepend (table, tbl);
  253. return FALSE;
  254. }
  255. /** Packet creating functions */
  256. static void
  257. allocate_packet (struct rspamd_dns_request *req, guint namelen)
  258. {
  259. namelen += 96 /* header */
  260. + 2 /* Trailing label */
  261. + 4; /* Resource type */
  262. req->packet = memory_pool_alloc (req->pool, namelen);
  263. req->pos = 0;
  264. req->packet_len = namelen;
  265. }
  266. static void
  267. make_dns_header (struct rspamd_dns_request *req)
  268. {
  269. struct dns_header *header;
  270. /* Set DNS header values */
  271. header = (struct dns_header *)req->packet;
  272. memset (header, 0 , sizeof (struct dns_header));
  273. header->qid = dns_k_permutor_step (req->resolver->permutor);
  274. header->rd = 1;
  275. header->qdcount = htons (1);
  276. req->pos += sizeof (struct dns_header);
  277. req->id = header->qid;
  278. }
  279. static void
  280. format_dns_name (struct rspamd_dns_request *req, const char *name, guint namelen)
  281. {
  282. guint8 *pos = req->packet + req->pos, *end, *dot, *begin;
  283. guint remain = req->packet_len - req->pos - 5, label_len;
  284. GList *table = NULL;
  285. if (namelen == 0) {
  286. namelen = strlen (name);
  287. }
  288. begin = (guint8 *)name;
  289. end = (guint8 *)name + namelen;
  290. for (;;) {
  291. dot = strchr (begin, '.');
  292. if (dot) {
  293. label_len = dot - begin;
  294. if (label_len > DNS_D_MAXLABEL) {
  295. msg_err ("dns name component is longer than 63 bytes, should be stripped");
  296. label_len = DNS_D_MAXLABEL;
  297. }
  298. if (remain < label_len + 1) {
  299. label_len = remain - 1;
  300. msg_err ("no buffer remain for constructing query, strip to %ud", label_len);
  301. }
  302. /* First try to compress name */
  303. if (! try_compress_label (req->pool, pos, req->packet, end - begin, begin, table)) {
  304. *pos++ = (guint8)label_len;
  305. memcpy (pos, begin, label_len);
  306. pos += label_len;
  307. }
  308. else {
  309. pos += 2;
  310. }
  311. remain -= label_len + 1;
  312. begin = dot + 1;
  313. }
  314. else {
  315. label_len = end - begin;
  316. if (label_len == 0) {
  317. /* If name is ended with dot */
  318. break;
  319. }
  320. if (label_len > DNS_D_MAXLABEL) {
  321. msg_err ("dns name component is longer than 63 bytes, should be stripped");
  322. label_len = DNS_D_MAXLABEL;
  323. }
  324. if (remain < label_len + 1) {
  325. label_len = remain - 1;
  326. msg_err ("no buffer remain for constructing query, strip to %ud", label_len);
  327. }
  328. *pos++ = (guint8)label_len;
  329. memcpy (pos, begin, label_len);
  330. pos += label_len;
  331. remain -= label_len + 1;
  332. break;
  333. }
  334. if (remain == 0) {
  335. msg_err ("no buffer space available, aborting");
  336. break;
  337. }
  338. }
  339. /* Termination label */
  340. *pos = '\0';
  341. req->pos += pos - (req->packet + req->pos) + 1;
  342. if (table != NULL) {
  343. g_list_free (table);
  344. }
  345. }
  346. static void
  347. make_ptr_req (struct rspamd_dns_request *req, struct in_addr addr)
  348. {
  349. char ipbuf[sizeof("255.255.255.255.in-addr.arpa")];
  350. guint32 a = ntohl (addr.s_addr), r;
  351. guint16 *p;
  352. r = rspamd_snprintf (ipbuf, sizeof(ipbuf), "%d.%d.%d.%d.in-addr.arpa",
  353. (int)(guint8)((a ) & 0xff),
  354. (int)(guint8)((a>>8 ) & 0xff),
  355. (int)(guint8)((a>>16) & 0xff),
  356. (int)(guint8)((a>>24) & 0xff));
  357. allocate_packet (req, r);
  358. make_dns_header (req);
  359. format_dns_name (req, ipbuf, r);
  360. p = (guint16 *)(req->packet + req->pos);
  361. *p++ = htons (DNS_T_PTR);
  362. *p = htons (DNS_C_IN);
  363. req->requested_name = memory_pool_strdup (req->pool, ipbuf);
  364. req->pos += sizeof (guint16) * 2;
  365. req->type = DNS_REQUEST_PTR;
  366. }
  367. static void
  368. make_a_req (struct rspamd_dns_request *req, const char *name)
  369. {
  370. guint16 *p;
  371. allocate_packet (req, strlen (name));
  372. make_dns_header (req);
  373. format_dns_name (req, name, 0);
  374. p = (guint16 *)(req->packet + req->pos);
  375. *p++ = htons (DNS_T_A);
  376. *p = htons (DNS_C_IN);
  377. req->pos += sizeof (guint16) * 2;
  378. req->type = DNS_REQUEST_A;
  379. req->requested_name = name;
  380. }
  381. static void
  382. make_txt_req (struct rspamd_dns_request *req, const char *name)
  383. {
  384. guint16 *p;
  385. allocate_packet (req, strlen (name));
  386. make_dns_header (req);
  387. format_dns_name (req, name, 0);
  388. p = (guint16 *)(req->packet + req->pos);
  389. *p++ = htons (DNS_T_TXT);
  390. *p = htons (DNS_C_IN);
  391. req->pos += sizeof (guint16) * 2;
  392. req->type = DNS_REQUEST_TXT;
  393. req->requested_name = name;
  394. }
  395. static void
  396. make_mx_req (struct rspamd_dns_request *req, const char *name)
  397. {
  398. guint16 *p;
  399. allocate_packet (req, strlen (name));
  400. make_dns_header (req);
  401. format_dns_name (req, name, 0);
  402. p = (guint16 *)(req->packet + req->pos);
  403. *p++ = htons (DNS_T_MX);
  404. *p = htons (DNS_C_IN);
  405. req->pos += sizeof (guint16) * 2;
  406. req->type = DNS_REQUEST_MX;
  407. req->requested_name = name;
  408. }
  409. static void
  410. make_srv_req (struct rspamd_dns_request *req, const char *service, const char *proto, const char *name)
  411. {
  412. guint16 *p;
  413. guint len;
  414. gchar *target;
  415. len = strlen (service) + strlen (proto) + strlen (name) + 5;
  416. allocate_packet (req, len);
  417. make_dns_header (req);
  418. target = memory_pool_alloc (req->pool, len);
  419. len = rspamd_snprintf (target, len, "_%s._%s.%s", service, proto, name);
  420. format_dns_name (req, target, len);
  421. p = (guint16 *)(req->packet + req->pos);
  422. *p++ = htons (DNS_T_SRV);
  423. *p = htons (DNS_C_IN);
  424. req->pos += sizeof (guint16) * 2;
  425. req->type = DNS_REQUEST_SRV;
  426. req->requested_name = name;
  427. }
  428. static void
  429. make_spf_req (struct rspamd_dns_request *req, const char *name)
  430. {
  431. guint16 *p;
  432. allocate_packet (req, strlen (name));
  433. make_dns_header (req);
  434. format_dns_name (req, name, 0);
  435. p = (guint16 *)(req->packet + req->pos);
  436. *p++ = htons (DNS_T_SPF);
  437. *p = htons (DNS_C_IN);
  438. req->pos += sizeof (guint16) * 2;
  439. req->type = DNS_REQUEST_SPF;
  440. req->requested_name = name;
  441. }
  442. static int
  443. send_dns_request (struct rspamd_dns_request *req)
  444. {
  445. gint r;
  446. r = send (req->sock, req->packet, req->pos, 0);
  447. if (r == -1) {
  448. if (errno == EAGAIN) {
  449. event_set (&req->io_event, req->sock, EV_WRITE, dns_retransmit_handler, req);
  450. event_add (&req->io_event, &req->tv);
  451. register_async_event (req->session, (event_finalizer_t)event_del, &req->io_event, FALSE);
  452. return 0;
  453. }
  454. else {
  455. msg_err ("send failed: %s for server %s", strerror (errno), req->server->name);
  456. upstream_fail (&req->server->up, time (NULL));
  457. return -1;
  458. }
  459. }
  460. else if (r < req->pos) {
  461. event_set (&req->io_event, req->sock, EV_WRITE, dns_retransmit_handler, req);
  462. event_add (&req->io_event, &req->tv);
  463. register_async_event (req->session, (event_finalizer_t)event_del, &req->io_event, FALSE);
  464. return 0;
  465. }
  466. return 1;
  467. }
  468. static void
  469. dns_fin_cb (gpointer arg)
  470. {
  471. struct rspamd_dns_request *req = arg;
  472. event_del (&req->timer_event);
  473. g_hash_table_remove (req->resolver->requests, GUINT_TO_POINTER (req->id));
  474. }
  475. static guint8 *
  476. decompress_label (guint8 *begin, guint16 *len)
  477. {
  478. guint16 offset;
  479. offset = ntohs ((*len) ^ DNS_COMPRESSION_BITS);
  480. *len = *(begin + offset);
  481. return begin + offset;
  482. }
  483. static guint8 *
  484. dns_request_reply_cmp (struct rspamd_dns_request *req, guint8 *in, int len)
  485. {
  486. guint8 *p, *c, *l1, *l2;
  487. guint16 len1, len2;
  488. gint decompressed = 0;
  489. /* QR format:
  490. * labels - len:octets
  491. * null label - 0
  492. * class - 2 octets
  493. * type - 2 octets
  494. */
  495. /* In p we would store current position in reply and in c - position in request */
  496. p = in;
  497. c = req->packet + sizeof (struct dns_header);
  498. for (;;) {
  499. /* Get current label */
  500. len1 = *p;
  501. len2 = *c;
  502. if (p - in > len) {
  503. msg_info ("invalid dns reply");
  504. return NULL;
  505. }
  506. /* This may be compressed, so we need to decompress it */
  507. if (len1 & DNS_COMPRESSION_BITS) {
  508. memcpy (&len1, p, sizeof (guint16));
  509. l1 = decompress_label (in, &len1);
  510. decompressed ++;
  511. l1 ++;
  512. p += 2;
  513. }
  514. else {
  515. l1 = ++p;
  516. p += len1;
  517. }
  518. if (len2 & DNS_COMPRESSION_BITS) {
  519. memcpy (&len2, p, sizeof (guint16));
  520. l2 = decompress_label (req->packet, &len2);
  521. decompressed ++;
  522. l2 ++;
  523. c += 2;
  524. }
  525. else {
  526. l2 = ++c;
  527. c += len2;
  528. }
  529. if (len1 != len2) {
  530. return NULL;
  531. }
  532. if (len1 == 0) {
  533. break;
  534. }
  535. if (memcmp (l1, l2, len1) != 0) {
  536. return NULL;
  537. }
  538. if (decompressed == 2) {
  539. break;
  540. }
  541. }
  542. /* p now points to the end of QR section */
  543. /* Compare class and type */
  544. if (memcmp (p, c, sizeof (guint16) * 2) == 0) {
  545. return p + sizeof (guint16) * 2;
  546. }
  547. return NULL;
  548. }
  549. #define MAX_RECURSION_LEVEL 10
  550. static gboolean
  551. dns_parse_labels (guint8 *in, char **target, guint8 **pos, struct rspamd_dns_reply *rep, int *remain, gboolean make_name)
  552. {
  553. guint16 namelen = 0;
  554. guint8 *p = *pos, *begin = *pos, *l, *t;
  555. guint16 llen;
  556. gint offset = -1;
  557. gint length = *remain;
  558. gint ptrs = 0, labels = 0;
  559. /* First go through labels and calculate name length */
  560. while (p - begin < length) {
  561. if (ptrs > MAX_RECURSION_LEVEL) {
  562. msg_warn ("dns pointers are nested too much");
  563. return FALSE;
  564. }
  565. llen = *p;
  566. if (llen == 0) {
  567. break;
  568. }
  569. else if (llen & DNS_COMPRESSION_BITS) {
  570. ptrs ++;
  571. memcpy (&llen, p, sizeof (guint16));
  572. l = decompress_label (in, &llen);
  573. if (offset < 0) {
  574. offset = p - begin + 2;
  575. }
  576. if (l < in || l > begin + length) {
  577. msg_warn ("invalid pointer in DNS packet");
  578. return FALSE;
  579. }
  580. begin = l;
  581. p = l + *l + 1;
  582. namelen += *p;
  583. labels ++;
  584. }
  585. else {
  586. namelen += *p;
  587. p += *p + 1;
  588. labels ++;
  589. }
  590. }
  591. if (!make_name) {
  592. goto end;
  593. }
  594. *target = memory_pool_alloc (rep->request->pool, namelen + labels + 1);
  595. t = (guint8 *)*target;
  596. p = *pos;
  597. /* Now copy labels to name */
  598. while (p - begin < length) {
  599. llen = *p;
  600. if (llen == 0) {
  601. break;
  602. }
  603. else if (llen & DNS_COMPRESSION_BITS) {
  604. memcpy (&llen, p, sizeof (guint16));
  605. l = decompress_label (in, &llen);
  606. begin = p;
  607. p = l + *l + 1;
  608. namelen += *p;
  609. }
  610. else {
  611. memcpy (t, p + 1, *p);
  612. t += *p;
  613. *t ++ = '.';
  614. p += *p + 1;
  615. }
  616. }
  617. *t = '\0';
  618. end:
  619. if (offset < 0) {
  620. offset = p - begin;
  621. }
  622. *remain -= offset;
  623. *pos += offset;
  624. return TRUE;
  625. }
  626. #define GET16(x) do {if (*remain < sizeof (guint16)) {goto err;} memcpy (&(x), p, sizeof (guint16)); (x) = ntohs ((x)); p += sizeof (guint16); *remain -= sizeof (guint16); } while(0)
  627. #define GET32(x) do {if (*remain < sizeof (guint32)) {goto err;} memcpy (&(x), p, sizeof (guint32)); (x) = ntohl ((x)); p += sizeof (guint32); *remain -= sizeof (guint32); } while(0)
  628. static gboolean
  629. dns_parse_rr (guint8 *in, union rspamd_reply_element *elt, guint8 **pos, struct rspamd_dns_reply *rep, int *remain)
  630. {
  631. guint8 *p = *pos;
  632. guint16 type, datalen;
  633. /* Skip the whole name */
  634. if (! dns_parse_labels (in, NULL, &p, rep, remain, FALSE)) {
  635. msg_info ("bad RR name");
  636. return FALSE;
  637. }
  638. if (p - *pos >= *remain - sizeof (guint16) * 5) {
  639. msg_info ("stripped dns reply");
  640. return FALSE;
  641. }
  642. GET16 (type);
  643. /* Skip ttl and class */
  644. p += sizeof (guint16) + sizeof (guint32);
  645. *remain -= sizeof (guint16) + sizeof (guint32);
  646. GET16 (datalen);
  647. /* Now p points to RR data */
  648. switch (type) {
  649. case DNS_T_A:
  650. if (rep->request->type != DNS_REQUEST_A) {
  651. p += datalen;
  652. }
  653. else {
  654. if (!(datalen & 0x3) && datalen <= *remain) {
  655. memcpy (&elt->a.addr[0], p, sizeof (struct in_addr));
  656. p += datalen;
  657. }
  658. else {
  659. msg_info ("corrupted A record");
  660. return FALSE;
  661. }
  662. }
  663. break;
  664. case DNS_T_PTR:
  665. if (rep->request->type != DNS_REQUEST_PTR) {
  666. p += datalen;
  667. }
  668. else {
  669. if (! dns_parse_labels (in, &elt->ptr.name, &p, rep, remain, TRUE)) {
  670. msg_info ("invalid labels in PTR record");
  671. return FALSE;
  672. }
  673. }
  674. break;
  675. case DNS_T_MX:
  676. if (rep->request->type != DNS_REQUEST_MX) {
  677. p += datalen;
  678. }
  679. else {
  680. GET16 (elt->mx.priority);
  681. if (! dns_parse_labels (in, &elt->mx.name, &p, rep, remain, TRUE)) {
  682. msg_info ("invalid labels in MX record");
  683. return FALSE;
  684. }
  685. }
  686. break;
  687. case DNS_T_TXT:
  688. if (rep->request->type != DNS_REQUEST_TXT) {
  689. p += datalen;
  690. }
  691. else {
  692. elt->txt.data = memory_pool_alloc (rep->request->pool, datalen);
  693. memcpy (elt->txt.data, p + 1, datalen - 1);
  694. *(elt->txt.data + datalen) = '\0';
  695. }
  696. break;
  697. case DNS_T_SPF:
  698. if (rep->request->type != DNS_REQUEST_SPF) {
  699. p += datalen;
  700. }
  701. else {
  702. elt->spf.data = memory_pool_alloc (rep->request->pool, datalen);
  703. memcpy (elt->spf.data, p + 1, datalen - 1);
  704. *(elt->spf.data + datalen) = '\0';
  705. }
  706. break;
  707. case DNS_T_SRV:
  708. if (rep->request->type != DNS_REQUEST_SRV) {
  709. p += datalen;
  710. }
  711. else {
  712. GET16 (elt->srv.priority);
  713. GET16 (elt->srv.weight);
  714. GET16 (elt->srv.port);
  715. if (! dns_parse_labels (in, &elt->srv.target, &p, rep, remain, TRUE)) {
  716. msg_info ("invalid labels in SRV record");
  717. return FALSE;
  718. }
  719. }
  720. break;
  721. default:
  722. msg_info ("unexpected RR type: %d", type);
  723. }
  724. *remain -= datalen;
  725. *pos = p;
  726. return TRUE;
  727. err:
  728. msg_info ("incomplete RR, only %d bytes remain, packet length %d", (int)*remain, (int)(*pos - in));
  729. return FALSE;
  730. }
  731. static struct rspamd_dns_reply *
  732. dns_parse_reply (guint8 *in, int r, struct rspamd_dns_resolver *resolver)
  733. {
  734. struct dns_header *header = (struct dns_header *)in;
  735. struct rspamd_dns_request *req;
  736. struct rspamd_dns_reply *rep;
  737. union rspamd_reply_element *elt;
  738. guint8 *pos;
  739. int i;
  740. /* First check header fields */
  741. if (header->qr == 0) {
  742. msg_info ("got request while waiting for reply");
  743. return NULL;
  744. }
  745. /* Now try to find corresponding request */
  746. if ((req = g_hash_table_lookup (resolver->requests, GUINT_TO_POINTER (header->qid))) == NULL) {
  747. /* No such requests found */
  748. return NULL;
  749. }
  750. /*
  751. * Now we have request and query data is now at the end of header, so compare
  752. * request QR section and reply QR section
  753. */
  754. if ((pos = dns_request_reply_cmp (req, in + sizeof (struct dns_header), r - sizeof (struct dns_header))) == NULL) {
  755. return NULL;
  756. }
  757. /*
  758. * Remove delayed retransmits for this packet
  759. */
  760. event_del (&req->timer_event);
  761. /*
  762. * Now pos is in answer section, so we should extract data and form reply
  763. */
  764. rep = memory_pool_alloc (req->pool, sizeof (struct rspamd_dns_reply));
  765. rep->request = req;
  766. rep->type = req->type;
  767. rep->elements = NULL;
  768. rep->code = header->rcode;
  769. r -= pos - in;
  770. /* Extract RR records */
  771. for (i = 0; i < ntohs (header->ancount); i ++) {
  772. elt = memory_pool_alloc (req->pool, sizeof (union rspamd_reply_element));
  773. if (! dns_parse_rr (in, elt, &pos, rep, &r)) {
  774. msg_info ("incomplete reply");
  775. break;
  776. }
  777. rep->elements = g_list_prepend (rep->elements, elt);
  778. }
  779. return rep;
  780. }
  781. static void
  782. dns_read_cb (int fd, short what, void *arg)
  783. {
  784. struct rspamd_dns_resolver *resolver = arg;
  785. int r;
  786. struct rspamd_dns_reply *rep;
  787. guint8 in[UDP_PACKET_SIZE];
  788. /* This function is called each time when we have data on one of server's sockets */
  789. /* First read packet from socket */
  790. r = read (fd, in, sizeof (in));
  791. if (r > sizeof (struct dns_header) + sizeof (struct dns_query)) {
  792. if ((rep = dns_parse_reply (in, r, resolver)) != NULL) {
  793. rep->request->func (rep, rep->request->arg);
  794. upstream_ok (&rep->request->server->up, rep->request->time);
  795. return;
  796. }
  797. }
  798. }
  799. static void
  800. dns_timer_cb (int fd, short what, void *arg)
  801. {
  802. struct rspamd_dns_request *req = arg;
  803. struct rspamd_dns_reply *rep;
  804. int r;
  805. /* Retransmit dns request */
  806. req->retransmits ++;
  807. if (req->retransmits >= req->resolver->max_retransmits) {
  808. msg_err ("maximum number of retransmits expired for resolving %s of type %s", req->requested_name, dns_strtype (req->type));
  809. event_del (&req->timer_event);
  810. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  811. rep->request = req;
  812. rep->code = DNS_RC_SERVFAIL;
  813. req->func (rep, req->arg);
  814. upstream_fail (&rep->request->server->up, rep->request->time);
  815. return;
  816. }
  817. /* Select other server */
  818. req->server = (struct rspamd_dns_server *)get_upstream_round_robin (req->resolver->servers,
  819. req->resolver->servers_num, sizeof (struct rspamd_dns_server),
  820. time (NULL), DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
  821. if (req->server == NULL) {
  822. event_del (&req->timer_event);
  823. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  824. rep->request = req;
  825. rep->code = DNS_RC_SERVFAIL;
  826. req->func (rep, req->arg);
  827. return;
  828. }
  829. if (req->server->sock == -1) {
  830. req->server->sock = make_udp_socket (&req->server->addr, htons (53), FALSE, TRUE);
  831. }
  832. req->sock = req->server->sock;
  833. if (req->sock == -1) {
  834. event_del (&req->timer_event);
  835. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  836. rep->request = req;
  837. rep->code = DNS_RC_SERVFAIL;
  838. req->func (rep, req->arg);
  839. upstream_fail (&rep->request->server->up, rep->request->time);
  840. return;
  841. }
  842. /* Add other retransmit event */
  843. evtimer_add (&req->timer_event, &req->tv);
  844. r = send_dns_request (req);
  845. if (r == -1) {
  846. event_del (&req->io_event);
  847. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  848. rep->request = req;
  849. rep->code = DNS_RC_SERVFAIL;
  850. req->func (rep, req->arg);
  851. upstream_fail (&rep->request->server->up, rep->request->time);
  852. }
  853. }
  854. static void
  855. dns_retransmit_handler (int fd, short what, void *arg)
  856. {
  857. struct rspamd_dns_request *req = arg;
  858. struct rspamd_dns_reply *rep;
  859. gint r;
  860. if (what == EV_WRITE) {
  861. /* Retransmit dns request */
  862. req->retransmits ++;
  863. if (req->retransmits >= req->resolver->max_retransmits) {
  864. msg_err ("maximum number of retransmits expired for %s", req->requested_name);
  865. event_del (&req->io_event);
  866. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  867. rep->request = req;
  868. rep->code = DNS_RC_SERVFAIL;
  869. req->func (rep, req->arg);
  870. upstream_fail (&rep->request->server->up, rep->request->time);
  871. return;
  872. }
  873. r = send_dns_request (req);
  874. if (r == -1) {
  875. event_del (&req->io_event);
  876. rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply));
  877. rep->request = req;
  878. rep->code = DNS_RC_SERVFAIL;
  879. req->func (rep, req->arg);
  880. upstream_fail (&rep->request->server->up, rep->request->time);
  881. }
  882. else if (r == 1) {
  883. /* Add timer event */
  884. evtimer_set (&req->timer_event, dns_timer_cb, req);
  885. evtimer_add (&req->timer_event, &req->tv);
  886. /* Add request to hash table */
  887. g_hash_table_insert (req->resolver->requests, GUINT_TO_POINTER (req->id), req);
  888. register_async_event (req->session, (event_finalizer_t)dns_fin_cb, req, FALSE);
  889. }
  890. }
  891. }
  892. gboolean
  893. make_dns_request (struct rspamd_dns_resolver *resolver,
  894. struct rspamd_async_session *session, memory_pool_t *pool, dns_callback_type cb,
  895. gpointer ud, enum rspamd_request_type type, ...)
  896. {
  897. va_list args;
  898. struct rspamd_dns_request *req;
  899. struct in_addr addr;
  900. const char *name, *service, *proto;
  901. gint r;
  902. req = memory_pool_alloc (pool, sizeof (struct rspamd_dns_request));
  903. req->pool = pool;
  904. req->session = session;
  905. req->resolver = resolver;
  906. req->func = cb;
  907. req->arg = ud;
  908. req->type = type;
  909. va_start (args, type);
  910. switch (type) {
  911. case DNS_REQUEST_PTR:
  912. addr = va_arg (args, struct in_addr);
  913. make_ptr_req (req, addr);
  914. break;
  915. case DNS_REQUEST_MX:
  916. name = va_arg (args, const char *);
  917. make_mx_req (req, name);
  918. break;
  919. case DNS_REQUEST_A:
  920. name = va_arg (args, const char *);
  921. make_a_req (req, name);
  922. break;
  923. case DNS_REQUEST_TXT:
  924. name = va_arg (args, const char *);
  925. make_txt_req (req, name);
  926. break;
  927. case DNS_REQUEST_SPF:
  928. name = va_arg (args, const char *);
  929. make_spf_req (req, name);
  930. break;
  931. case DNS_REQUEST_SRV:
  932. service = va_arg (args, const char *);
  933. proto = va_arg (args, const char *);
  934. name = va_arg (args, const char *);
  935. make_srv_req (req, service, proto, name);
  936. break;
  937. }
  938. va_end (args);
  939. req->retransmits = 0;
  940. req->server = (struct rspamd_dns_server *)get_upstream_round_robin (resolver->servers,
  941. resolver->servers_num, sizeof (struct rspamd_dns_server),
  942. time (NULL), DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
  943. if (req->server == NULL) {
  944. msg_err ("cannot find suitable server for request");
  945. return FALSE;
  946. }
  947. if (req->server->sock == -1) {
  948. req->server->sock = make_udp_socket (&req->server->addr, htons (53), FALSE, TRUE);
  949. }
  950. req->sock = req->server->sock;
  951. if (req->sock == -1) {
  952. return FALSE;
  953. }
  954. /* Fill timeout */
  955. req->tv.tv_sec = resolver->request_timeout / 1000;
  956. req->tv.tv_usec = (resolver->request_timeout - req->tv.tv_sec * 1000) * 1000;
  957. req->time = time (NULL);
  958. /* Now send request to server */
  959. r = send_dns_request (req);
  960. if (r == 1) {
  961. /* Add timer event */
  962. evtimer_set (&req->timer_event, dns_timer_cb, req);
  963. evtimer_add (&req->timer_event, &req->tv);
  964. /* Add request to hash table */
  965. g_hash_table_insert (resolver->requests, GUINT_TO_POINTER (req->id), req);
  966. register_async_event (session, (event_finalizer_t)dns_fin_cb, req, FALSE);
  967. }
  968. else if (r == -1) {
  969. return FALSE;
  970. }
  971. return TRUE;
  972. }
  973. #define RESOLV_CONF "/etc/resolv.conf"
  974. static gboolean
  975. parse_resolv_conf (struct rspamd_dns_resolver *resolver)
  976. {
  977. FILE *r;
  978. char buf[BUFSIZ], *p;
  979. struct rspamd_dns_server *new;
  980. struct in_addr addr;
  981. r = fopen (RESOLV_CONF, "r");
  982. if (r == NULL) {
  983. msg_err ("cannot open %s: %s", RESOLV_CONF, strerror (errno));
  984. return FALSE;
  985. }
  986. while (! feof (r)) {
  987. if (fgets (buf, sizeof (buf), r)) {
  988. g_strstrip (buf);
  989. if (g_ascii_strncasecmp (buf, "nameserver", sizeof ("nameserver") - 1) == 0) {
  990. p = buf + sizeof ("nameserver");
  991. while (*p && g_ascii_isspace (*p)) {
  992. p ++;
  993. }
  994. if (! *p) {
  995. msg_warn ("cannot parse empty nameserver line in resolv.conf");
  996. continue;
  997. }
  998. else {
  999. if (inet_aton (p, &addr) != 0) {
  1000. new = &resolver->servers[resolver->servers_num];
  1001. new->name = memory_pool_strdup (resolver->static_pool, p);
  1002. memcpy (&new->addr, &addr, sizeof (struct in_addr));
  1003. resolver->servers_num ++;
  1004. }
  1005. else {
  1006. msg_warn ("cannot parse ip address of nameserver: %s", p);
  1007. continue;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. }
  1013. fclose (r);
  1014. return TRUE;
  1015. }
  1016. struct rspamd_dns_resolver *
  1017. dns_resolver_init (struct config_file *cfg)
  1018. {
  1019. GList *cur;
  1020. struct rspamd_dns_resolver *new;
  1021. char *begin, *p;
  1022. int priority, i;
  1023. struct rspamd_dns_server *serv;
  1024. new = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_dns_resolver));
  1025. new->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
  1026. new->permutor = memory_pool_alloc (cfg->cfg_pool, sizeof (struct dns_k_permutor));
  1027. dns_k_permutor_init (new->permutor, 0, G_MAXUINT16);
  1028. new->static_pool = cfg->cfg_pool;
  1029. new->request_timeout = cfg->dns_timeout;
  1030. new->max_retransmits = cfg->dns_retransmits;
  1031. if (cfg->nameservers == NULL) {
  1032. /* Parse resolv.conf */
  1033. if (! parse_resolv_conf (new) || new->servers_num == 0) {
  1034. msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
  1035. return NULL;
  1036. }
  1037. }
  1038. else {
  1039. cur = cfg->nameservers;
  1040. while (cur) {
  1041. begin = cur->data;
  1042. p = strchr (begin, ':');
  1043. if (p != NULL) {
  1044. *p = '\0';
  1045. p ++;
  1046. priority = strtoul (p, NULL, 10);
  1047. }
  1048. else {
  1049. priority = 0;
  1050. }
  1051. serv = &new->servers[new->servers_num];
  1052. if (inet_aton (begin, &serv->addr) != 0) {
  1053. serv->name = memory_pool_strdup (new->static_pool, begin);
  1054. serv->up.priority = priority;
  1055. new->servers_num ++;
  1056. }
  1057. else {
  1058. msg_warn ("cannot parse ip address of nameserver: %s", p);
  1059. cur = g_list_next (cur);
  1060. continue;
  1061. }
  1062. cur = g_list_next (cur);
  1063. }
  1064. if (new->servers_num == 0) {
  1065. msg_err ("no valid nameservers defined, try to parse resolv.conf");
  1066. if (! parse_resolv_conf (new) || new->servers_num == 0) {
  1067. msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
  1068. return NULL;
  1069. }
  1070. }
  1071. }
  1072. /* Now init all servers */
  1073. for (i = 0; i < new->servers_num; i ++) {
  1074. serv = &new->servers[i];
  1075. serv->sock = make_udp_socket (&serv->addr, 53, FALSE, TRUE);
  1076. if (serv->sock == -1) {
  1077. msg_warn ("cannot create socket to server %s", serv->name);
  1078. }
  1079. else {
  1080. event_set (&serv->ev, serv->sock, EV_READ | EV_PERSIST, dns_read_cb, new);
  1081. event_add (&serv->ev, NULL);
  1082. }
  1083. }
  1084. return new;
  1085. }
  1086. static char dns_rcodes[16][16] = {
  1087. [DNS_RC_NOERROR] = "NOERROR",
  1088. [DNS_RC_FORMERR] = "FORMERR",
  1089. [DNS_RC_SERVFAIL] = "SERVFAIL",
  1090. [DNS_RC_NXDOMAIN] = "NXDOMAIN",
  1091. [DNS_RC_NOTIMP] = "NOTIMP",
  1092. [DNS_RC_REFUSED] = "REFUSED",
  1093. [DNS_RC_YXDOMAIN] = "YXDOMAIN",
  1094. [DNS_RC_YXRRSET] = "YXRRSET",
  1095. [DNS_RC_NXRRSET] = "NXRRSET",
  1096. [DNS_RC_NOTAUTH] = "NOTAUTH",
  1097. [DNS_RC_NOTZONE] = "NOTZONE",
  1098. };
  1099. const char *
  1100. dns_strerror (enum dns_rcode rcode)
  1101. {
  1102. rcode &= 0xf;
  1103. static char numbuf[16];
  1104. if ('\0' == dns_rcodes[rcode][0]) {
  1105. rspamd_snprintf (numbuf, sizeof (numbuf), "UNKNOWN: %d", (int)rcode);
  1106. return numbuf;
  1107. }
  1108. return dns_rcodes[rcode];
  1109. }
  1110. static char dns_types[6][16] = {
  1111. [DNS_REQUEST_A] = "A request",
  1112. [DNS_REQUEST_PTR] = "PTR request",
  1113. [DNS_REQUEST_MX] = "MX request",
  1114. [DNS_REQUEST_TXT] = "TXT request",
  1115. [DNS_REQUEST_SRV] = "SRV request",
  1116. [DNS_REQUEST_SPF] = "SPF request"
  1117. };
  1118. const char *
  1119. dns_strtype (enum rspamd_request_type type)
  1120. {
  1121. return dns_types[type];
  1122. }