gnunet-dns2gns.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file gnunet-dns2gns.c
  18. * @brief DNS server that translates DNS requests to GNS
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include <gnunet_util_lib.h>
  23. #include <gnunet_dnsparser_lib.h>
  24. #include <gnunet_gns_service.h>
  25. #include <gnunet_dnsstub_lib.h>
  26. #include "gns.h"
  27. /**
  28. * Timeout for DNS requests.
  29. */
  30. #define TIMEOUT GNUNET_TIME_UNIT_MINUTES
  31. /**
  32. * Data kept per request.
  33. */
  34. struct Request
  35. {
  36. /**
  37. * Socket to use for sending the reply.
  38. */
  39. struct GNUNET_NETWORK_Handle *lsock;
  40. /**
  41. * Destination address to use.
  42. */
  43. const void *addr;
  44. /**
  45. * Initially, this is the DNS request, it will then be
  46. * converted to the DNS response.
  47. */
  48. struct GNUNET_DNSPARSER_Packet *packet;
  49. /**
  50. * Our GNS request handle.
  51. */
  52. struct GNUNET_GNS_LookupWithTldRequest *lookup;
  53. /**
  54. * Our DNS request handle
  55. */
  56. struct GNUNET_DNSSTUB_RequestSocket *dns_lookup;
  57. /**
  58. * Task run on timeout or shutdown to clean up without
  59. * response.
  60. */
  61. struct GNUNET_SCHEDULER_Task *timeout_task;
  62. /**
  63. * Original UDP request message.
  64. */
  65. char *udp_msg;
  66. /**
  67. * Number of bytes in @e addr.
  68. */
  69. size_t addr_len;
  70. /**
  71. * Number of bytes in @e udp_msg.
  72. */
  73. size_t udp_msg_size;
  74. /**
  75. * ID of the original request.
  76. */
  77. uint16_t original_request_id;
  78. };
  79. /**
  80. * The address to bind to
  81. */
  82. static in_addr_t address;
  83. /**
  84. * The IPv6 address to bind to
  85. */
  86. static struct in6_addr address6;
  87. /**
  88. * Handle to GNS resolver.
  89. */
  90. struct GNUNET_GNS_Handle *gns;
  91. /**
  92. * Stub resolver
  93. */
  94. struct GNUNET_DNSSTUB_Context *dns_stub;
  95. /**
  96. * Listen socket for IPv4.
  97. */
  98. static struct GNUNET_NETWORK_Handle *listen_socket4;
  99. /**
  100. * Listen socket for IPv6.
  101. */
  102. static struct GNUNET_NETWORK_Handle *listen_socket6;
  103. /**
  104. * Task for IPv4 socket.
  105. */
  106. static struct GNUNET_SCHEDULER_Task *t4;
  107. /**
  108. * Task for IPv6 socket.
  109. */
  110. static struct GNUNET_SCHEDULER_Task *t6;
  111. /**
  112. * IP of DNS server
  113. */
  114. static char *dns_ip;
  115. /**
  116. * UDP Port we listen on for inbound DNS requests.
  117. */
  118. static unsigned int listen_port = 53;
  119. /**
  120. * Configuration to use.
  121. */
  122. static const struct GNUNET_CONFIGURATION_Handle *cfg;
  123. /**
  124. * Task run on shutdown. Cleans up everything.
  125. *
  126. * @param cls unused
  127. */
  128. static void
  129. do_shutdown (void *cls)
  130. {
  131. (void) cls;
  132. if (NULL != t4)
  133. {
  134. GNUNET_SCHEDULER_cancel (t4);
  135. t4 = NULL;
  136. }
  137. if (NULL != t6)
  138. {
  139. GNUNET_SCHEDULER_cancel (t6);
  140. t6 = NULL;
  141. }
  142. if (NULL != listen_socket4)
  143. {
  144. GNUNET_NETWORK_socket_close (listen_socket4);
  145. listen_socket4 = NULL;
  146. }
  147. if (NULL != listen_socket6)
  148. {
  149. GNUNET_NETWORK_socket_close (listen_socket6);
  150. listen_socket6 = NULL;
  151. }
  152. if (NULL != gns)
  153. {
  154. GNUNET_GNS_disconnect (gns);
  155. gns = NULL;
  156. }
  157. if (NULL != dns_stub)
  158. {
  159. GNUNET_DNSSTUB_stop (dns_stub);
  160. dns_stub = NULL;
  161. }
  162. }
  163. /**
  164. * Shuffle answers
  165. * Fisher-Yates (aka Knuth) Shuffle
  166. *
  167. * @param request context for the request (with answers)
  168. */
  169. static void
  170. shuffle_answers (struct Request *request)
  171. {
  172. unsigned int idx = request->packet->num_answers;
  173. unsigned int r_idx;
  174. struct GNUNET_DNSPARSER_Record tmp_answer;
  175. while (0 != idx)
  176. {
  177. r_idx = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  178. request->packet->num_answers);
  179. idx--;
  180. tmp_answer = request->packet->answers[idx];
  181. memcpy (&request->packet->answers[idx], &request->packet->answers[r_idx],
  182. sizeof (struct GNUNET_DNSPARSER_Record));
  183. memcpy (&request->packet->answers[r_idx], &tmp_answer,
  184. sizeof (struct GNUNET_DNSPARSER_Record));
  185. }
  186. }
  187. /**
  188. * Send the response for the given request and clean up.
  189. *
  190. * @param request context for the request.
  191. */
  192. static void
  193. send_response (struct Request *request)
  194. {
  195. char *buf;
  196. size_t size;
  197. ssize_t sret;
  198. shuffle_answers (request);
  199. if (GNUNET_SYSERR ==
  200. GNUNET_DNSPARSER_pack (request->packet,
  201. UINT16_MAX /* is this not too much? */,
  202. &buf,
  203. &size))
  204. {
  205. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  206. _ ("Failed to pack DNS response into UDP packet!\n"));
  207. }
  208. else
  209. {
  210. sret = GNUNET_NETWORK_socket_sendto (request->lsock,
  211. buf,
  212. size,
  213. request->addr,
  214. request->addr_len);
  215. if ((sret < 0) ||
  216. (size != (size_t) sret))
  217. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  218. "sendto");
  219. GNUNET_free (buf);
  220. }
  221. GNUNET_SCHEDULER_cancel (request->timeout_task);
  222. GNUNET_DNSPARSER_free_packet (request->packet);
  223. GNUNET_free (request->udp_msg);
  224. GNUNET_free (request);
  225. }
  226. /**
  227. * Task run on timeout. Cleans up request.
  228. *
  229. * @param cls `struct Request *` of the request to clean up
  230. */
  231. static void
  232. do_timeout (void *cls)
  233. {
  234. struct Request *request = cls;
  235. if (NULL != request->packet)
  236. GNUNET_DNSPARSER_free_packet (request->packet);
  237. if (NULL != request->lookup)
  238. GNUNET_GNS_lookup_with_tld_cancel (request->lookup);
  239. if (NULL != request->dns_lookup)
  240. GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
  241. GNUNET_free (request->udp_msg);
  242. GNUNET_free (request);
  243. }
  244. /**
  245. * Iterator called on obtained result for a DNS lookup
  246. *
  247. * @param cls closure
  248. * @param dns the DNS udp payload
  249. * @param r size of the DNS payload
  250. */
  251. static void
  252. dns_result_processor (void *cls,
  253. const struct GNUNET_TUN_DnsHeader *dns,
  254. size_t r)
  255. {
  256. struct Request *request = cls;
  257. if (NULL == dns)
  258. {
  259. /* DNSSTUB gave up, so we trigger timeout early */
  260. GNUNET_SCHEDULER_cancel (request->timeout_task);
  261. do_timeout (request);
  262. return;
  263. }
  264. if (request->original_request_id != dns->id)
  265. {
  266. /* for a another query, ignore */
  267. return;
  268. }
  269. request->packet = GNUNET_DNSPARSER_parse ((char *) dns,
  270. r);
  271. if (NULL == request->packet)
  272. {
  273. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  274. _ ("Failed to parse DNS response!\n"));
  275. GNUNET_SCHEDULER_cancel (request->timeout_task);
  276. do_timeout (request);
  277. return;
  278. }
  279. GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
  280. send_response (request);
  281. }
  282. /**
  283. * Iterator called on obtained result for a GNS lookup.
  284. *
  285. * @param cls closure
  286. * @param was_gns #GNUNET_NO if the TLD is not configured for GNS
  287. * @param rd_count number of records in @a rd
  288. * @param rd the records in reply
  289. */
  290. static void
  291. result_processor (void *cls,
  292. int was_gns,
  293. uint32_t rd_count,
  294. const struct GNUNET_GNSRECORD_Data *rd)
  295. {
  296. struct Request *request = cls;
  297. struct GNUNET_DNSPARSER_Packet *packet;
  298. struct GNUNET_DNSPARSER_Record rec;
  299. request->lookup = NULL;
  300. if (GNUNET_NO == was_gns)
  301. {
  302. /* TLD not configured for GNS, fall back to DNS */
  303. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  304. "Using DNS resolver IP `%s' to resolve `%s'\n",
  305. dns_ip,
  306. request->packet->queries[0].name);
  307. request->original_request_id = request->packet->id;
  308. GNUNET_DNSPARSER_free_packet (request->packet);
  309. request->packet = NULL;
  310. request->dns_lookup = GNUNET_DNSSTUB_resolve (dns_stub,
  311. request->udp_msg,
  312. request->udp_msg_size,
  313. &dns_result_processor,
  314. request);
  315. return;
  316. }
  317. packet = request->packet;
  318. packet->flags.query_or_response = 1;
  319. packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR;
  320. packet->flags.checking_disabled = 0;
  321. packet->flags.authenticated_data = 1;
  322. packet->flags.zero = 0;
  323. packet->flags.recursion_available = 1;
  324. packet->flags.message_truncated = 0;
  325. packet->flags.authoritative_answer = 0;
  326. // packet->flags.opcode = GNUNET_TUN_DNS_OPCODE_STATUS; // ???
  327. for (uint32_t i = 0; i < rd_count; i++)
  328. {
  329. rec.expiration_time.abs_value_us = rd[i].expiration_time;
  330. switch (rd[i].record_type)
  331. {
  332. case GNUNET_DNSPARSER_TYPE_A:
  333. GNUNET_assert (sizeof(struct in_addr) == rd[i].data_size);
  334. rec.name = GNUNET_strdup (packet->queries[0].name);
  335. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  336. rec.type = GNUNET_DNSPARSER_TYPE_A;
  337. rec.data.raw.data = GNUNET_new (struct in_addr);
  338. GNUNET_memcpy (rec.data.raw.data,
  339. rd[i].data,
  340. rd[i].data_size);
  341. rec.data.raw.data_len = sizeof(struct in_addr);
  342. GNUNET_array_append (packet->answers,
  343. packet->num_answers,
  344. rec);
  345. break;
  346. case GNUNET_DNSPARSER_TYPE_AAAA:
  347. GNUNET_assert (sizeof(struct in6_addr) == rd[i].data_size);
  348. rec.name = GNUNET_strdup (packet->queries[0].name);
  349. rec.data.raw.data = GNUNET_new (struct in6_addr);
  350. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  351. rec.type = GNUNET_DNSPARSER_TYPE_AAAA;
  352. GNUNET_memcpy (rec.data.raw.data,
  353. rd[i].data,
  354. rd[i].data_size);
  355. rec.data.raw.data_len = sizeof(struct in6_addr);
  356. GNUNET_array_append (packet->answers,
  357. packet->num_answers,
  358. rec);
  359. break;
  360. case GNUNET_DNSPARSER_TYPE_CNAME:
  361. rec.name = GNUNET_strdup (packet->queries[0].name);
  362. rec.data.hostname = GNUNET_strdup (rd[i].data);
  363. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  364. rec.type = GNUNET_DNSPARSER_TYPE_CNAME;
  365. GNUNET_memcpy (rec.data.hostname,
  366. rd[i].data,
  367. rd[i].data_size);
  368. GNUNET_array_append (packet->answers,
  369. packet->num_answers,
  370. rec);
  371. break;
  372. default:
  373. /* skip */
  374. break;
  375. }
  376. }
  377. send_response (request);
  378. }
  379. /**
  380. * Handle DNS request.
  381. *
  382. * @param lsock socket to use for sending the reply
  383. * @param addr address to use for sending the reply
  384. * @param addr_len number of bytes in @a addr
  385. * @param udp_msg DNS request payload
  386. * @param udp_msg_size number of bytes in @a udp_msg
  387. */
  388. static void
  389. handle_request (struct GNUNET_NETWORK_Handle *lsock,
  390. const void *addr,
  391. size_t addr_len,
  392. const char *udp_msg,
  393. size_t udp_msg_size)
  394. {
  395. struct Request *request;
  396. struct GNUNET_DNSPARSER_Packet *packet;
  397. packet = GNUNET_DNSPARSER_parse (udp_msg,
  398. udp_msg_size);
  399. if (NULL == packet)
  400. {
  401. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  402. _ ("Cannot parse DNS request from %s\n"),
  403. GNUNET_a2s (addr, addr_len));
  404. return;
  405. }
  406. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  407. "Received request for `%s' with flags %u, #answers %d, #auth %d, #additional %d\n",
  408. packet->queries[0].name,
  409. (unsigned int) packet->flags.query_or_response,
  410. (int) packet->num_answers,
  411. (int) packet->num_authority_records,
  412. (int) packet->num_additional_records);
  413. if ((0 != packet->flags.query_or_response) ||
  414. (0 != packet->num_answers) ||
  415. (0 != packet->num_authority_records))
  416. {
  417. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  418. _ ("Received malformed DNS request from %s\n"),
  419. GNUNET_a2s (addr, addr_len));
  420. GNUNET_DNSPARSER_free_packet (packet);
  421. return;
  422. }
  423. if ((1 != packet->num_queries))
  424. {
  425. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  426. _ ("Received unsupported DNS request from %s\n"),
  427. GNUNET_a2s (addr,
  428. addr_len));
  429. GNUNET_DNSPARSER_free_packet (packet);
  430. return;
  431. }
  432. request = GNUNET_malloc (sizeof(struct Request) + addr_len);
  433. request->lsock = lsock;
  434. request->packet = packet;
  435. request->addr = &request[1];
  436. request->addr_len = addr_len;
  437. GNUNET_memcpy (&request[1],
  438. addr,
  439. addr_len);
  440. request->udp_msg_size = udp_msg_size;
  441. request->udp_msg = GNUNET_memdup (udp_msg,
  442. udp_msg_size);
  443. request->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
  444. &do_timeout,
  445. request);
  446. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  447. "Calling GNS on `%s'\n",
  448. packet->queries[0].name);
  449. request->lookup = GNUNET_GNS_lookup_with_tld (gns,
  450. packet->queries[0].name,
  451. packet->queries[0].type,
  452. GNUNET_GNS_LO_DEFAULT,
  453. &result_processor,
  454. request);
  455. }
  456. /**
  457. * Task to read IPv4 DNS packets.
  458. *
  459. * @param cls the 'listen_socket4'
  460. */
  461. static void
  462. read_dns4 (void *cls)
  463. {
  464. struct sockaddr_in v4;
  465. socklen_t addrlen;
  466. ssize_t size;
  467. const struct GNUNET_SCHEDULER_TaskContext *tc;
  468. GNUNET_assert (listen_socket4 == cls);
  469. t4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  470. listen_socket4,
  471. &read_dns4,
  472. listen_socket4);
  473. tc = GNUNET_SCHEDULER_get_task_context ();
  474. if (0 == (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason))
  475. return; /* shutdown? */
  476. size = GNUNET_NETWORK_socket_recvfrom_amount (listen_socket4);
  477. if (0 > size)
  478. {
  479. GNUNET_break (0);
  480. return; /* read error!? */
  481. }
  482. {
  483. char buf[size + 1];
  484. ssize_t sret;
  485. addrlen = sizeof(v4);
  486. sret = GNUNET_NETWORK_socket_recvfrom (listen_socket4,
  487. buf,
  488. size + 1,
  489. (struct sockaddr *) &v4,
  490. &addrlen);
  491. if (0 > sret)
  492. {
  493. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  494. "recvfrom");
  495. return;
  496. }
  497. GNUNET_break (size == sret);
  498. handle_request (listen_socket4,
  499. &v4,
  500. addrlen,
  501. buf,
  502. size);
  503. }
  504. }
  505. /**
  506. * Task to read IPv6 DNS packets.
  507. *
  508. * @param cls the 'listen_socket6'
  509. */
  510. static void
  511. read_dns6 (void *cls)
  512. {
  513. struct sockaddr_in6 v6;
  514. socklen_t addrlen;
  515. ssize_t size;
  516. const struct GNUNET_SCHEDULER_TaskContext *tc;
  517. GNUNET_assert (listen_socket6 == cls);
  518. t6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  519. listen_socket6,
  520. &read_dns6,
  521. listen_socket6);
  522. tc = GNUNET_SCHEDULER_get_task_context ();
  523. if (0 == (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason))
  524. return; /* shutdown? */
  525. size = GNUNET_NETWORK_socket_recvfrom_amount (listen_socket6);
  526. if (0 > size)
  527. {
  528. GNUNET_break (0);
  529. return; /* read error!? */
  530. }
  531. {
  532. char buf[size];
  533. ssize_t sret;
  534. addrlen = sizeof(v6);
  535. sret = GNUNET_NETWORK_socket_recvfrom (listen_socket6,
  536. buf,
  537. size,
  538. (struct sockaddr *) &v6,
  539. &addrlen);
  540. if (0 > sret)
  541. {
  542. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  543. "recvfrom");
  544. return;
  545. }
  546. GNUNET_break (size == sret);
  547. handle_request (listen_socket6,
  548. &v6,
  549. addrlen,
  550. buf,
  551. size);
  552. }
  553. }
  554. /**
  555. * Main function that will be run.
  556. *
  557. * @param cls closure
  558. * @param args remaining command-line arguments
  559. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  560. * @param c configuration
  561. */
  562. static void
  563. run (void *cls,
  564. char *const *args,
  565. const char *cfgfile,
  566. const struct GNUNET_CONFIGURATION_Handle *c)
  567. {
  568. char *addr_str;
  569. (void) cls;
  570. (void) args;
  571. (void) cfgfile;
  572. cfg = c;
  573. if (NULL == dns_ip)
  574. {
  575. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  576. _ ("No DNS server specified!\n"));
  577. return;
  578. }
  579. GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
  580. NULL);
  581. if (NULL == (gns = GNUNET_GNS_connect (cfg)))
  582. return;
  583. GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128)));
  584. if (GNUNET_OK !=
  585. GNUNET_DNSSTUB_add_dns_ip (dns_stub,
  586. dns_ip))
  587. {
  588. GNUNET_DNSSTUB_stop (dns_stub);
  589. GNUNET_GNS_disconnect (gns);
  590. gns = NULL;
  591. return;
  592. }
  593. /* Get address to bind to */
  594. if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "dns2gns",
  595. "BIND_TO",
  596. &addr_str))
  597. {
  598. // No address specified
  599. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  600. "Don't know what to bind to...\n");
  601. GNUNET_free (addr_str);
  602. GNUNET_SCHEDULER_shutdown ();
  603. return;
  604. }
  605. if (1 != inet_pton (AF_INET, addr_str, &address))
  606. {
  607. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  608. "Unable to parse address %s\n",
  609. addr_str);
  610. GNUNET_free (addr_str);
  611. GNUNET_SCHEDULER_shutdown ();
  612. return;
  613. }
  614. GNUNET_free (addr_str);
  615. /* Get address to bind to */
  616. if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "dns2gns",
  617. "BIND_TO6",
  618. &addr_str))
  619. {
  620. // No address specified
  621. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  622. "Don't know what to bind6 to...\n");
  623. GNUNET_free (addr_str);
  624. GNUNET_SCHEDULER_shutdown ();
  625. return;
  626. }
  627. if (1 != inet_pton (AF_INET6, addr_str, &address6))
  628. {
  629. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  630. "Unable to parse IPv6 address %s\n",
  631. addr_str);
  632. GNUNET_free (addr_str);
  633. GNUNET_SCHEDULER_shutdown ();
  634. return;
  635. }
  636. GNUNET_free (addr_str);
  637. listen_socket4 = GNUNET_NETWORK_socket_create (PF_INET,
  638. SOCK_DGRAM,
  639. IPPROTO_UDP);
  640. if (NULL != listen_socket4)
  641. {
  642. struct sockaddr_in v4;
  643. memset (&v4, 0, sizeof(v4));
  644. v4.sin_family = AF_INET;
  645. v4.sin_addr.s_addr = address;
  646. #if HAVE_SOCKADDR_IN_SIN_LEN
  647. v4.sin_len = sizeof(v4);
  648. #endif
  649. v4.sin_port = htons (listen_port);
  650. if (GNUNET_OK !=
  651. GNUNET_NETWORK_socket_bind (listen_socket4,
  652. (struct sockaddr *) &v4,
  653. sizeof(v4)))
  654. {
  655. GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
  656. GNUNET_NETWORK_socket_close (listen_socket4);
  657. listen_socket4 = NULL;
  658. }
  659. }
  660. listen_socket6 = GNUNET_NETWORK_socket_create (PF_INET6,
  661. SOCK_DGRAM,
  662. IPPROTO_UDP);
  663. if (NULL != listen_socket6)
  664. {
  665. struct sockaddr_in6 v6;
  666. memset (&v6, 0, sizeof(v6));
  667. v6.sin6_family = AF_INET6;
  668. v6.sin6_addr = address6;
  669. #if HAVE_SOCKADDR_IN_SIN_LEN
  670. v6.sin6_len = sizeof(v6);
  671. #endif
  672. v6.sin6_port = htons (listen_port);
  673. if (GNUNET_OK !=
  674. GNUNET_NETWORK_socket_bind (listen_socket6,
  675. (struct sockaddr *) &v6,
  676. sizeof(v6)))
  677. {
  678. GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
  679. GNUNET_NETWORK_socket_close (listen_socket6);
  680. listen_socket6 = NULL;
  681. }
  682. }
  683. if ((NULL == listen_socket4) &&
  684. (NULL == listen_socket6))
  685. {
  686. GNUNET_GNS_disconnect (gns);
  687. gns = NULL;
  688. GNUNET_DNSSTUB_stop (dns_stub);
  689. dns_stub = NULL;
  690. return;
  691. }
  692. if (NULL != listen_socket4)
  693. t4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  694. listen_socket4,
  695. &read_dns4,
  696. listen_socket4);
  697. if (NULL != listen_socket6)
  698. t6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  699. listen_socket6,
  700. &read_dns6,
  701. listen_socket6);
  702. }
  703. /**
  704. * The main function for the dns2gns daemon.
  705. *
  706. * @param argc number of arguments from the command line
  707. * @param argv command line arguments
  708. * @return 0 ok, 1 on error
  709. */
  710. int
  711. main (int argc,
  712. char *const *argv)
  713. {
  714. struct GNUNET_GETOPT_CommandLineOption options[] = {
  715. GNUNET_GETOPT_option_string ('d',
  716. "dns",
  717. "IP",
  718. gettext_noop (
  719. "IP of recursive DNS resolver to use (required)"),
  720. &dns_ip),
  721. GNUNET_GETOPT_option_uint ('p',
  722. "port",
  723. "UDPPORT",
  724. gettext_noop (
  725. "UDP port to listen on for inbound DNS requests; default: 2853"),
  726. &listen_port),
  727. GNUNET_GETOPT_OPTION_END
  728. };
  729. int ret;
  730. if (GNUNET_OK !=
  731. GNUNET_STRINGS_get_utf8_args (argc, argv,
  732. &argc, &argv))
  733. return 2;
  734. GNUNET_log_setup ("gnunet-dns2gns",
  735. "WARNING",
  736. NULL);
  737. ret =
  738. (GNUNET_OK ==
  739. GNUNET_PROGRAM_run (argc, argv,
  740. "gnunet-dns2gns",
  741. _ ("GNUnet DNS-to-GNS proxy (a DNS server)"),
  742. options,
  743. &run, NULL)) ? 0 : 1;
  744. GNUNET_free_nz ((void *) argv);
  745. return ret;
  746. }
  747. /* end of gnunet-dns2gns.c */