DNSServer.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "interface/DNSServer.h"
  16. #include "benc/String.h"
  17. #include "exception/Jmp.h"
  18. #include "crypto/AddressCalc.h"
  19. #include "util/Base32.h"
  20. #include "util/Identity.h"
  21. #include "wire/Message.h"
  22. #include "wire/Error.h"
  23. enum ResponseCode {
  24. ResponseCode_NO_ERROR = 0,
  25. ResponseCode_FORMAT_ERROR = 1,
  26. ResponseCode_SERVER_ERROR = 2,
  27. ResponseCode_NXDOMAIN = 3,
  28. ResponseCode_NOT_IMPLEMENTED = 4,
  29. ResponseCode_REFUSED = 5,
  30. ResponseCode_XYDOMAIN = 6,
  31. ResponseCode_YXRRSET = 7,
  32. ResponseCode_NXRRSET = 8,
  33. ResponseCode_NOT_AUTH_FOR_ZONE = 9,
  34. };
  35. enum Type {
  36. Type_TXT = 16,
  37. Type_AAAA = 28
  38. };
  39. enum Class {
  40. Class_IN = 1
  41. };
  42. struct DNSServer_RR
  43. {
  44. String** name;
  45. uint16_t type;
  46. uint16_t class;
  47. uint32_t ttl;
  48. String* data;
  49. };
  50. struct DNSServer_Question
  51. {
  52. String** name;
  53. uint16_t class;
  54. uint16_t type;
  55. };
  56. struct DNSServer_Flags
  57. {
  58. int responseCode;
  59. bool cd;
  60. bool authenticated;
  61. bool z;
  62. bool recursionAvailable;
  63. bool recursionDesired;
  64. bool truncated;
  65. bool authoritative;
  66. int opCode;
  67. bool isResponse;
  68. };
  69. struct DNSServer_Message
  70. {
  71. uint16_t id;
  72. struct DNSServer_Flags flags;
  73. struct DNSServer_Question** questions;
  74. struct DNSServer_RR** answers;
  75. struct DNSServer_RR** authorities;
  76. struct DNSServer_RR** additionals;
  77. };
  78. struct DNSServer_pvt
  79. {
  80. struct DNSServer pub;
  81. struct Interface* iface;
  82. struct Log* logger;
  83. struct RainflyClient* rainfly;
  84. struct Sockaddr* addr;
  85. /* Plain old DNS servers for resolving non-cjdns addresses. */
  86. int serverCount;
  87. struct Sockaddr** servers;
  88. struct Allocator* alloc;
  89. Identity
  90. };
  91. static void parseFlags(uint16_t flags, struct DNSServer_Flags* out)
  92. {
  93. #define POP(count) flags & ((1<<(count))-1); flags >>= (count)
  94. out->responseCode = POP(4);
  95. out->cd = POP(1);
  96. out->authenticated = POP(1);
  97. out->z = POP(1);
  98. out->recursionAvailable = POP(1);
  99. out->recursionDesired = POP(1);
  100. out->truncated = POP(1);
  101. out->authoritative = POP(1);
  102. out->opCode = POP(4);
  103. out->isResponse = POP(1);
  104. Assert_true(flags == 0);
  105. #undef POP
  106. }
  107. static uint16_t flagsAsInt(struct DNSServer_Flags* flags)
  108. {
  109. uint16_t out = 0;
  110. #define PUSH(count, data) out <<= (count); out |= ((data) & ((1<<(count))-1))
  111. PUSH(1, flags->isResponse);
  112. PUSH(4, flags->opCode);
  113. PUSH(1, flags->authoritative);
  114. PUSH(1, flags->truncated);
  115. PUSH(1, flags->recursionDesired);
  116. PUSH(1, flags->recursionAvailable);
  117. PUSH(1, flags->z);
  118. PUSH(1, flags->authenticated);
  119. PUSH(1, flags->cd);
  120. PUSH(4, flags->responseCode);
  121. return out;
  122. #undef PUSH
  123. }
  124. static String** parseName(struct Message* msg, struct Allocator* alloc, struct Except* eh)
  125. {
  126. String** array = Allocator_calloc(alloc, sizeof(uintptr_t), 1);
  127. uint8_t len = Message_pop8(msg, eh);
  128. int count = 0;
  129. while (len) {
  130. count++;
  131. array = Allocator_realloc(alloc, array, sizeof(uintptr_t) * count + 1);
  132. array[count] = NULL;
  133. String* str = array[count-1] = String_newBinary(NULL, len, alloc);
  134. Message_pop(msg, str->bytes, len, eh);
  135. len = Message_pop8(msg, eh);
  136. }
  137. return array;
  138. }
  139. static void serializeName(struct Message* msg, String** name, struct Except* eh)
  140. {
  141. Message_push8(msg, 0, eh);
  142. int i;
  143. for (i = 0; name[i]; i++) ;
  144. i--;
  145. for (;i >= 0; i--) {
  146. Message_push(msg, name[i]->bytes, name[i]->len, eh);
  147. Message_push8(msg, name[i]->len, eh);
  148. }
  149. }
  150. static struct DNSServer_Question* parseQuestion(struct Message* msg,
  151. struct Allocator* alloc,
  152. struct Except* eh)
  153. {
  154. struct DNSServer_Question* q = Allocator_malloc(alloc, sizeof(struct DNSServer_Question));
  155. q->name = parseName(msg, alloc, eh);
  156. q->type = Message_pop16(msg, eh);
  157. q->class = Message_pop16(msg, eh);
  158. return q;
  159. }
  160. static void serializeQuestion(struct Message* msg, struct DNSServer_Question* q, struct Except* eh)
  161. {
  162. Message_push16(msg, q->class, eh);
  163. Message_push16(msg, q->type, eh);
  164. serializeName(msg, q->name, eh);
  165. }
  166. static struct DNSServer_RR* parseRR(struct Message* msg, struct Allocator* alloc, struct Except* eh)
  167. {
  168. struct DNSServer_RR* rr = Allocator_malloc(alloc, sizeof(struct DNSServer_RR));
  169. rr->name = parseName(msg, alloc, eh);
  170. rr->type = Message_pop16(msg, eh);
  171. rr->class = Message_pop16(msg, eh);
  172. rr->ttl = Message_pop32(msg, eh);
  173. uint16_t dataLen = Message_pop16(msg, eh);
  174. rr->data = String_newBinary(NULL, dataLen, alloc);
  175. Message_pop(msg, rr->data->bytes, dataLen, eh);
  176. return rr;
  177. }
  178. static void serializeRR(struct Message* msg, struct DNSServer_RR* rr, struct Except* eh)
  179. {
  180. Message_push(msg, rr->data->bytes, rr->data->len, eh);
  181. Message_push16(msg, rr->data->len, eh);
  182. Message_push32(msg, rr->ttl, eh);
  183. Message_push16(msg, rr->class, eh);
  184. Message_push16(msg, rr->type, eh);
  185. serializeName(msg, rr->name, eh);
  186. }
  187. static struct DNSServer_Message* parseMessage(struct Message* msg,
  188. struct Allocator* alloc,
  189. struct Except* eh)
  190. {
  191. struct DNSServer_Message* dmesg = Allocator_calloc(alloc, sizeof(struct DNSServer_Message), 1);
  192. dmesg->id = Message_pop16(msg, eh);
  193. uint16_t flags = Message_pop16(msg, eh);
  194. parseFlags(flags, &dmesg->flags);
  195. int totalQuestions = Message_pop16(msg, eh);
  196. int totalAnswerRRs = Message_pop16(msg, eh);
  197. int totalAuthorityRRs = Message_pop16(msg, eh);
  198. int totalAdditionalRRs = Message_pop16(msg, eh);
  199. dmesg->questions = Allocator_calloc(alloc, sizeof(uintptr_t), totalQuestions+1);
  200. dmesg->answers = Allocator_calloc(alloc, sizeof(uintptr_t), totalAnswerRRs+1);
  201. dmesg->authorities = Allocator_calloc(alloc, sizeof(uintptr_t), totalAuthorityRRs+1);
  202. dmesg->additionals = Allocator_calloc(alloc, sizeof(uintptr_t), totalAdditionalRRs+1);
  203. for (int i = 0; i < totalQuestions; i++) {
  204. dmesg->questions[i] = parseQuestion(msg, alloc, eh);
  205. }
  206. for (int i = 0; i < totalAnswerRRs; i++) {
  207. dmesg->answers[i] = parseRR(msg, alloc, eh);
  208. }
  209. for (int i = 0; i < totalAuthorityRRs; i++) {
  210. dmesg->authorities[i] = parseRR(msg, alloc, eh);
  211. }
  212. for (int i = 0; i < totalAdditionalRRs; i++) {
  213. dmesg->additionals[i] = parseRR(msg, alloc, eh);
  214. }
  215. return dmesg;
  216. }
  217. static void serializeMessage(struct Message* msg,
  218. struct DNSServer_Message* dmesg,
  219. struct Except* eh)
  220. {
  221. int totalAdditionalRRs = 0;
  222. int totalAuthorityRRs = 0;
  223. int totalAnswerRRs = 0;
  224. int totalQuestions = 0;
  225. for (int i = 0; dmesg->additionals && dmesg->additionals[i]; i++) {
  226. serializeRR(msg, dmesg->additionals[i], eh);
  227. totalAdditionalRRs++;
  228. }
  229. for (int i = 0; dmesg->authorities && dmesg->authorities[i]; i++) {
  230. serializeRR(msg, dmesg->authorities[i], eh);
  231. totalAuthorityRRs++;
  232. }
  233. for (int i = 0; dmesg->answers && dmesg->answers[i]; i++) {
  234. serializeRR(msg, dmesg->answers[i], eh);
  235. totalAnswerRRs++;
  236. }
  237. for (int i = 0; dmesg->questions && dmesg->questions[i]; i++) {
  238. serializeQuestion(msg, dmesg->questions[i], eh);
  239. totalQuestions++;
  240. }
  241. Message_push16(msg, totalAdditionalRRs, eh);
  242. Message_push16(msg, totalAuthorityRRs, eh);
  243. Message_push16(msg, totalAnswerRRs, eh);
  244. Message_push16(msg, totalQuestions, eh);
  245. Message_push16(msg, flagsAsInt(&dmesg->flags), eh);
  246. Message_push16(msg, dmesg->id, eh);
  247. }
  248. static int cannonicalizeDomain(String* str)
  249. {
  250. #define XX(x,y) [((uint8_t)x)]=y,
  251. static const char numForAscii[256] =
  252. {
  253. XX('a','a') XX('b','b') XX('c','c') XX('d','d')
  254. XX('e','e') XX('f','f') XX('g','g') XX('h','h')
  255. XX('i','i') XX('j','j') XX('k','k') XX('l','l')
  256. XX('m','m') XX('n','n') XX('o','o') XX('p','p')
  257. XX('q','q') XX('r','r') XX('s','s') XX('t','t')
  258. XX('u','u') XX('v','v') XX('w','w') XX('x','x')
  259. XX('y','y') XX('z','z')
  260. XX('A','a') XX('B','b') XX('C','c') XX('D','d')
  261. XX('E','e') XX('F','f') XX('G','g') XX('H','h')
  262. XX('I','i') XX('J','j') XX('K','k') XX('L','l')
  263. XX('M','m') XX('N','n') XX('O','o') XX('P','p')
  264. XX('Q','q') XX('R','r') XX('S','s') XX('T','t')
  265. XX('U','u') XX('V','v') XX('W','w') XX('X','x')
  266. XX('Y','y') XX('Z','z')
  267. XX('0','0') XX('1','1') XX('2','2') XX('3','3')
  268. XX('4','4') XX('5','5') XX('6','6') XX('7','7')
  269. XX('8','8') XX('9','9')
  270. XX('-','-')
  271. };
  272. #undef XX
  273. for (int i = 0; i < (int)str->len; i++) {
  274. if (!(str->bytes[i] = numForAscii[(uint8_t)str->bytes[i]])) {
  275. return -1;
  276. }
  277. }
  278. return 0;
  279. }
  280. static uint8_t sendResponse(struct Message* msg,
  281. struct DNSServer_Message* dmesg,
  282. struct Sockaddr* sourceAddr,
  283. struct DNSServer_pvt* ctx,
  284. struct Except* eh)
  285. {
  286. dmesg->flags.isResponse = 1;
  287. serializeMessage(msg, dmesg, eh);
  288. Message_push(msg, sourceAddr, ctx->addr->addrLen, eh);
  289. // lazy man's alignment
  290. if ((uintptr_t)(msg->bytes) % 8) {
  291. int len = (((uintptr_t)(msg->bytes)) % 8);
  292. Message_shift(msg, len, eh);
  293. Bits_memmove(msg->bytes, &msg->bytes[len], msg->length - len);
  294. msg->length -= len;
  295. }
  296. return Interface_sendMessage(ctx->iface, msg);
  297. }
  298. /** @return non-zero on failure. */
  299. static int trySendResponse(struct Message* msg,
  300. struct DNSServer_Message* dmesg,
  301. struct Sockaddr* sourceAddr,
  302. struct DNSServer_pvt* ctx)
  303. {
  304. struct Jmp j = { .message = NULL };
  305. Jmp_try(j) {
  306. sendResponse(msg, dmesg, sourceAddr, ctx, &j.handler);
  307. return 0;
  308. } Jmp_catch {
  309. return -1;
  310. }
  311. }
  312. static uint8_t handleDotK(struct Message* msg,
  313. struct DNSServer_Message* dmesg,
  314. struct DNSServer_Question* q,
  315. struct Sockaddr* sourceAddr,
  316. struct DNSServer_pvt* ctx)
  317. {
  318. // .k address lookup
  319. String* domain = q->name[0];
  320. uint8_t publicKey[32];
  321. uint8_t ipv6[16];
  322. if (Base32_decode(publicKey, 32, domain->bytes, domain->len) != 32) {
  323. Log_debug(ctx->logger, "Unparsable .k address [%s]", domain->bytes);
  324. } else if (!AddressCalc_addressForPublicKey(ipv6, publicKey)) {
  325. Log_debug(ctx->logger, "Invalid (not fc prefix) .k address [%s]", q->name[0]->bytes);
  326. } else if (q->type != Type_AAAA || q->class != Class_IN) {
  327. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  328. dmesg->flags.responseCode = ResponseCode_NO_ERROR;
  329. dmesg->answers = NULL;
  330. dmesg->authorities = NULL;
  331. dmesg->additionals = NULL;
  332. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  333. return Error_NONE;
  334. } else {
  335. struct DNSServer_RR rr = {
  336. .name = q->name,
  337. .type = Type_AAAA,
  338. .class = Class_IN,
  339. .ttl = ~0,
  340. .data = &(String) { .bytes = ipv6, .len = 16 }
  341. };
  342. struct DNSServer_RR* answers[2] = { &rr, NULL };
  343. dmesg->answers = answers;
  344. dmesg->authorities = NULL;
  345. dmesg->additionals = NULL;
  346. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  347. dmesg->flags.responseCode = ResponseCode_NO_ERROR;
  348. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  349. return Error_NONE;
  350. }
  351. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  352. dmesg->flags.responseCode = ResponseCode_NXDOMAIN;
  353. dmesg->answers = NULL;
  354. dmesg->authorities = NULL;
  355. dmesg->additionals = NULL;
  356. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  357. return Error_NONE;
  358. }
  359. struct DNSServer_RainflyRequest
  360. {
  361. struct RainflyClient_Lookup* lookup;
  362. struct Sockaddr* addr;
  363. struct Message* msg;
  364. struct DNSServer_Message* dmesg;
  365. struct DNSServer_pvt* ctx;
  366. Identity
  367. };
  368. static void onRainflyReply(struct RainflyClient_Lookup* promise,
  369. Dict* value,
  370. enum RainflyClient_ResponseCode code)
  371. {
  372. struct DNSServer_RainflyRequest* lookup =
  373. Identity_cast((struct DNSServer_RainflyRequest*)promise->userData);
  374. struct DNSServer_pvt* ctx =
  375. Identity_cast((struct DNSServer_pvt*)lookup->ctx);
  376. struct DNSServer_Message* dmesg = lookup->dmesg;
  377. struct DNSServer_Question* q = dmesg->questions[0];
  378. String* cjdns = Dict_getString(value, String_CONST("cjdns"));
  379. uint8_t publicKey[32];
  380. uint8_t ipv6[16];
  381. if (code) {
  382. // got error code
  383. } else if (!cjdns || cjdns->len < 3) {
  384. // no error, no answer
  385. } else if (Base32_decode(publicKey, 32, cjdns->bytes, cjdns->len-2) != 32) {
  386. Log_debug(ctx->logger, "Unparsable .k address [%s]", cjdns->bytes);
  387. } else if (!AddressCalc_addressForPublicKey(ipv6, publicKey)) {
  388. Log_debug(ctx->logger, "Invalid (not fc prefix) .k address [%s]", cjdns->bytes);
  389. } else {
  390. struct DNSServer_RR rr = {
  391. .name = q->name,
  392. .type = Type_AAAA,
  393. .class = Class_IN,
  394. .ttl = 153600,
  395. .data = &(String) { .bytes = ipv6, .len = 16 }
  396. };
  397. struct DNSServer_RR* answers[2] = { &rr, NULL };
  398. dmesg->answers = answers;
  399. dmesg->authorities = NULL;
  400. dmesg->additionals = NULL;
  401. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  402. dmesg->flags.responseCode = ResponseCode_NO_ERROR;
  403. if (!trySendResponse(lookup->msg, dmesg, lookup->addr, ctx)) {
  404. return;
  405. } else {
  406. code = RainflyClient_ResponseCode_SERVER_ERROR;
  407. }
  408. }
  409. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  410. dmesg->flags.responseCode = code;
  411. dmesg->answers = NULL;
  412. dmesg->authorities = NULL;
  413. dmesg->additionals = NULL;
  414. sendResponse(lookup->msg, dmesg, lookup->addr, ctx, NULL);
  415. return;
  416. }
  417. static uint8_t handleDotH(struct Message* msg,
  418. struct DNSServer_Message* dmesg,
  419. struct DNSServer_Question* q,
  420. String* domain,
  421. struct Sockaddr* sourceAddr,
  422. struct DNSServer_pvt* ctx)
  423. {
  424. // .h address lookup
  425. if (q->type != Type_AAAA || q->class != Class_IN) {
  426. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  427. dmesg->flags.responseCode = ResponseCode_NO_ERROR;
  428. dmesg->answers = NULL;
  429. dmesg->authorities = NULL;
  430. dmesg->additionals = NULL;
  431. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  432. return Error_NONE;
  433. }
  434. if (cannonicalizeDomain(domain)) {
  435. // invalid domain
  436. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  437. dmesg->flags.responseCode = ResponseCode_NXDOMAIN;
  438. dmesg->answers = NULL;
  439. dmesg->authorities = NULL;
  440. dmesg->additionals = NULL;
  441. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  442. return Error_NONE;
  443. }
  444. struct RainflyClient_Lookup* lookup = RainflyClient_lookup(ctx->rainfly, domain);
  445. Allocator_adopt(lookup->alloc, msg->alloc);
  446. struct DNSServer_RainflyRequest* req =
  447. Allocator_calloc(lookup->alloc, sizeof(struct DNSServer_RainflyRequest), 1);
  448. req->lookup = lookup;
  449. req->addr = sourceAddr;
  450. req->msg = msg;
  451. req->dmesg = dmesg;
  452. req->ctx = ctx;
  453. Identity_set(req);
  454. lookup->onReply = onRainflyReply;
  455. lookup->userData = req;
  456. return Error_NONE;
  457. }
  458. static void receiveB(struct Message* msg, struct DNSServer_pvt* ctx, struct Except* eh)
  459. {
  460. struct Sockaddr* sourceAddr = Allocator_malloc(msg->alloc, ctx->addr->addrLen);
  461. Message_pop(msg, sourceAddr, ctx->addr->addrLen, eh);
  462. struct DNSServer_Message* dmesg = parseMessage(msg, msg->alloc, eh);
  463. if (msg->length > 0) {
  464. Log_debug(ctx->logger, "[%d] bytes of crap following DNS request", msg->length);
  465. Message_shift(msg, -(msg->length), NULL);
  466. }
  467. if (!dmesg->questions || !dmesg->questions[0]) {
  468. Log_debug(ctx->logger, "Got DNS query with no questions");
  469. return;
  470. }
  471. struct DNSServer_Question* q = dmesg->questions[0];
  472. if (!q->name[0] || !q->name[1]) {
  473. Log_debug(ctx->logger, "Missing domain");
  474. return;
  475. }
  476. String* tld = NULL;
  477. String* domain = NULL;
  478. for (int i = 0; q->name[i]; i++) {
  479. if (cannonicalizeDomain(q->name[i])) {
  480. Log_debug(ctx->logger, "Invalid chars in domain");
  481. return;
  482. }
  483. tld = q->name[i];
  484. if (i > 0) {
  485. domain = q->name[i-1];
  486. }
  487. }
  488. if (String_equals(tld, String_CONST("h"))) {
  489. handleDotH(msg, dmesg, q, domain, sourceAddr, ctx);
  490. return;
  491. } else if (String_equals(tld, String_CONST("k"))) {
  492. if (q->name[2]) {
  493. Log_debug(ctx->logger, ".k domain with subdomain");
  494. return;
  495. }
  496. handleDotK(msg, dmesg, q, sourceAddr, ctx);
  497. return;
  498. } else {
  499. // not authoritative for zone
  500. Bits_memset(&dmesg->flags, 0, sizeof(struct DNSServer_Flags));
  501. dmesg->flags.responseCode = ResponseCode_NOT_AUTH_FOR_ZONE;
  502. dmesg->answers = NULL;
  503. dmesg->authorities = NULL;
  504. dmesg->additionals = NULL;
  505. sendResponse(msg, dmesg, sourceAddr, ctx, NULL);
  506. }
  507. return;
  508. }
  509. static uint8_t receiveMessage(struct Message* msg, struct Interface* iface)
  510. {
  511. struct DNSServer_pvt* const ctx = Identity_cast((struct DNSServer_pvt*)iface->receiverContext);
  512. struct Jmp jmp = { .message = NULL };
  513. Jmp_try(jmp) {
  514. receiveB(msg, ctx, &jmp.handler);
  515. } Jmp_catch {
  516. Log_debug(ctx->logger, "Failed to parse dns message [%s]", jmp.message);
  517. }
  518. return Error_NONE;
  519. }
  520. ///////////
  521. int DNSServer_addServer(struct DNSServer* dns, struct Sockaddr* addr)
  522. {
  523. struct DNSServer_pvt* ctx = Identity_cast((struct DNSServer_pvt*)dns);
  524. if (addr->addrLen != ctx->addr->addrLen
  525. || Sockaddr_getFamily(addr) != Sockaddr_getFamily(ctx->addr))
  526. {
  527. return DNSServer_addServer_WRONG_ADDRESS_TYPE;
  528. }
  529. ctx->serverCount++;
  530. ctx->servers =
  531. Allocator_realloc(ctx->alloc, ctx->servers, ctx->serverCount * sizeof(uintptr_t));
  532. ctx->servers[ctx->serverCount-1] = Sockaddr_clone(addr, ctx->alloc);
  533. return 0;
  534. }
  535. struct DNSServer* DNSServer_new(struct AddrInterface* iface,
  536. struct Log* logger,
  537. struct RainflyClient* rainfly)
  538. {
  539. struct DNSServer_pvt* context =
  540. Allocator_clone(iface->generic.allocator, (&(struct DNSServer_pvt) {
  541. .iface = &iface->generic,
  542. .logger = logger,
  543. .rainfly = rainfly,
  544. .addr = iface->addr,
  545. .alloc = iface->generic.allocator
  546. }));
  547. Identity_set(context);
  548. iface->generic.receiveMessage = receiveMessage;
  549. iface->generic.receiverContext = context;
  550. return &context->pub;
  551. }