gnunet-dns2gns.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  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. * Send the response for the given request and clean up.
  165. *
  166. * @param request context for the request.
  167. */
  168. static void
  169. send_response (struct Request *request)
  170. {
  171. char *buf;
  172. size_t size;
  173. ssize_t sret;
  174. if (GNUNET_SYSERR ==
  175. GNUNET_DNSPARSER_pack (request->packet,
  176. UINT16_MAX /* is this not too much? */,
  177. &buf,
  178. &size))
  179. {
  180. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  181. _ ("Failed to pack DNS response into UDP packet!\n"));
  182. }
  183. else
  184. {
  185. sret = GNUNET_NETWORK_socket_sendto (request->lsock,
  186. buf,
  187. size,
  188. request->addr,
  189. request->addr_len);
  190. if ((sret < 0) ||
  191. (size != (size_t) sret))
  192. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  193. "sendto");
  194. GNUNET_free (buf);
  195. }
  196. GNUNET_SCHEDULER_cancel (request->timeout_task);
  197. GNUNET_DNSPARSER_free_packet (request->packet);
  198. GNUNET_free (request->udp_msg);
  199. GNUNET_free (request);
  200. }
  201. /**
  202. * Task run on timeout. Cleans up request.
  203. *
  204. * @param cls `struct Request *` of the request to clean up
  205. */
  206. static void
  207. do_timeout (void *cls)
  208. {
  209. struct Request *request = cls;
  210. if (NULL != request->packet)
  211. GNUNET_DNSPARSER_free_packet (request->packet);
  212. if (NULL != request->lookup)
  213. GNUNET_GNS_lookup_with_tld_cancel (request->lookup);
  214. if (NULL != request->dns_lookup)
  215. GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
  216. GNUNET_free (request->udp_msg);
  217. GNUNET_free (request);
  218. }
  219. /**
  220. * Iterator called on obtained result for a DNS lookup
  221. *
  222. * @param cls closure
  223. * @param dns the DNS udp payload
  224. * @param r size of the DNS payload
  225. */
  226. static void
  227. dns_result_processor (void *cls,
  228. const struct GNUNET_TUN_DnsHeader *dns,
  229. size_t r)
  230. {
  231. struct Request *request = cls;
  232. if (NULL == dns)
  233. {
  234. /* DNSSTUB gave up, so we trigger timeout early */
  235. GNUNET_SCHEDULER_cancel (request->timeout_task);
  236. do_timeout (request);
  237. return;
  238. }
  239. if (request->original_request_id != dns->id)
  240. {
  241. /* for a another query, ignore */
  242. return;
  243. }
  244. request->packet = GNUNET_DNSPARSER_parse ((char *) dns,
  245. r);
  246. GNUNET_DNSSTUB_resolve_cancel (request->dns_lookup);
  247. send_response (request);
  248. }
  249. /**
  250. * Iterator called on obtained result for a GNS lookup.
  251. *
  252. * @param cls closure
  253. * @param was_gns #GNUNET_NO if the TLD is not configured for GNS
  254. * @param rd_count number of records in @a rd
  255. * @param rd the records in reply
  256. */
  257. static void
  258. result_processor (void *cls,
  259. int was_gns,
  260. uint32_t rd_count,
  261. const struct GNUNET_GNSRECORD_Data *rd)
  262. {
  263. struct Request *request = cls;
  264. struct GNUNET_DNSPARSER_Packet *packet;
  265. struct GNUNET_DNSPARSER_Record rec;
  266. request->lookup = NULL;
  267. if (GNUNET_NO == was_gns)
  268. {
  269. /* TLD not configured for GNS, fall back to DNS */
  270. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  271. "Using DNS resolver IP `%s' to resolve `%s'\n",
  272. dns_ip,
  273. request->packet->queries[0].name);
  274. request->original_request_id = request->packet->id;
  275. GNUNET_DNSPARSER_free_packet (request->packet);
  276. request->packet = NULL;
  277. request->dns_lookup = GNUNET_DNSSTUB_resolve (dns_stub,
  278. request->udp_msg,
  279. request->udp_msg_size,
  280. &dns_result_processor,
  281. request);
  282. return;
  283. }
  284. packet = request->packet;
  285. packet->flags.query_or_response = 1;
  286. packet->flags.return_code = GNUNET_TUN_DNS_RETURN_CODE_NO_ERROR;
  287. packet->flags.checking_disabled = 0;
  288. packet->flags.authenticated_data = 1;
  289. packet->flags.zero = 0;
  290. packet->flags.recursion_available = 1;
  291. packet->flags.message_truncated = 0;
  292. packet->flags.authoritative_answer = 0;
  293. // packet->flags.opcode = GNUNET_TUN_DNS_OPCODE_STATUS; // ???
  294. for (uint32_t i = 0; i < rd_count; i++)
  295. {
  296. // FIXME: do we need to hanlde #GNUNET_GNSRECORD_RF_SHADOW_RECORD
  297. // here? Or should we do this in libgnunetgns?
  298. rec.expiration_time.abs_value_us = rd[i].expiration_time;
  299. switch (rd[i].record_type)
  300. {
  301. case GNUNET_DNSPARSER_TYPE_A:
  302. GNUNET_assert (sizeof(struct in_addr) == rd[i].data_size);
  303. rec.name = GNUNET_strdup (packet->queries[0].name);
  304. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  305. rec.type = GNUNET_DNSPARSER_TYPE_A;
  306. rec.data.raw.data = GNUNET_new (struct in_addr);
  307. GNUNET_memcpy (rec.data.raw.data,
  308. rd[i].data,
  309. rd[i].data_size);
  310. rec.data.raw.data_len = sizeof(struct in_addr);
  311. GNUNET_array_append (packet->answers,
  312. packet->num_answers,
  313. rec);
  314. break;
  315. case GNUNET_DNSPARSER_TYPE_AAAA:
  316. GNUNET_assert (sizeof(struct in6_addr) == rd[i].data_size);
  317. rec.name = GNUNET_strdup (packet->queries[0].name);
  318. rec.data.raw.data = GNUNET_new (struct in6_addr);
  319. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  320. rec.type = GNUNET_DNSPARSER_TYPE_AAAA;
  321. GNUNET_memcpy (rec.data.raw.data,
  322. rd[i].data,
  323. rd[i].data_size);
  324. rec.data.raw.data_len = sizeof(struct in6_addr);
  325. GNUNET_array_append (packet->answers,
  326. packet->num_answers,
  327. rec);
  328. break;
  329. case GNUNET_DNSPARSER_TYPE_CNAME:
  330. rec.name = GNUNET_strdup (packet->queries[0].name);
  331. rec.data.hostname = GNUNET_strdup (rd[i].data);
  332. rec.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
  333. rec.type = GNUNET_DNSPARSER_TYPE_CNAME;
  334. GNUNET_memcpy (rec.data.hostname,
  335. rd[i].data,
  336. rd[i].data_size);
  337. GNUNET_array_append (packet->answers,
  338. packet->num_answers,
  339. rec);
  340. break;
  341. default:
  342. /* skip */
  343. break;
  344. }
  345. }
  346. send_response (request);
  347. }
  348. /**
  349. * Handle DNS request.
  350. *
  351. * @param lsock socket to use for sending the reply
  352. * @param addr address to use for sending the reply
  353. * @param addr_len number of bytes in @a addr
  354. * @param udp_msg DNS request payload
  355. * @param udp_msg_size number of bytes in @a udp_msg
  356. */
  357. static void
  358. handle_request (struct GNUNET_NETWORK_Handle *lsock,
  359. const void *addr,
  360. size_t addr_len,
  361. const char *udp_msg,
  362. size_t udp_msg_size)
  363. {
  364. struct Request *request;
  365. struct GNUNET_DNSPARSER_Packet *packet;
  366. packet = GNUNET_DNSPARSER_parse (udp_msg,
  367. udp_msg_size);
  368. if (NULL == packet)
  369. {
  370. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  371. _ ("Cannot parse DNS request from %s\n"),
  372. GNUNET_a2s (addr, addr_len));
  373. return;
  374. }
  375. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  376. "Received request for `%s' with flags %u, #answers %d, #auth %d, #additional %d\n",
  377. packet->queries[0].name,
  378. (unsigned int) packet->flags.query_or_response,
  379. (int) packet->num_answers,
  380. (int) packet->num_authority_records,
  381. (int) packet->num_additional_records);
  382. if ((0 != packet->flags.query_or_response) ||
  383. (0 != packet->num_answers) ||
  384. (0 != packet->num_authority_records))
  385. {
  386. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  387. _ ("Received malformed DNS request from %s\n"),
  388. GNUNET_a2s (addr, addr_len));
  389. GNUNET_DNSPARSER_free_packet (packet);
  390. return;
  391. }
  392. if ((1 != packet->num_queries))
  393. {
  394. GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
  395. _ ("Received unsupported DNS request from %s\n"),
  396. GNUNET_a2s (addr,
  397. addr_len));
  398. GNUNET_DNSPARSER_free_packet (packet);
  399. return;
  400. }
  401. request = GNUNET_malloc (sizeof(struct Request) + addr_len);
  402. request->lsock = lsock;
  403. request->packet = packet;
  404. request->addr = &request[1];
  405. request->addr_len = addr_len;
  406. GNUNET_memcpy (&request[1],
  407. addr,
  408. addr_len);
  409. request->udp_msg_size = udp_msg_size;
  410. request->udp_msg = GNUNET_memdup (udp_msg,
  411. udp_msg_size);
  412. request->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
  413. &do_timeout,
  414. request);
  415. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  416. "Calling GNS on `%s'\n",
  417. packet->queries[0].name);
  418. request->lookup = GNUNET_GNS_lookup_with_tld (gns,
  419. packet->queries[0].name,
  420. packet->queries[0].type,
  421. GNUNET_NO,
  422. &result_processor,
  423. request);
  424. }
  425. /**
  426. * Task to read IPv4 DNS packets.
  427. *
  428. * @param cls the 'listen_socket4'
  429. */
  430. static void
  431. read_dns4 (void *cls)
  432. {
  433. struct sockaddr_in v4;
  434. socklen_t addrlen;
  435. ssize_t size;
  436. const struct GNUNET_SCHEDULER_TaskContext *tc;
  437. GNUNET_assert (listen_socket4 == cls);
  438. t4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  439. listen_socket4,
  440. &read_dns4,
  441. listen_socket4);
  442. tc = GNUNET_SCHEDULER_get_task_context ();
  443. if (0 == (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason))
  444. return; /* shutdown? */
  445. size = GNUNET_NETWORK_socket_recvfrom_amount (listen_socket4);
  446. if (0 > size)
  447. {
  448. GNUNET_break (0);
  449. return; /* read error!? */
  450. }
  451. {
  452. char buf[size + 1];
  453. ssize_t sret;
  454. addrlen = sizeof(v4);
  455. sret = GNUNET_NETWORK_socket_recvfrom (listen_socket4,
  456. buf,
  457. size + 1,
  458. (struct sockaddr *) &v4,
  459. &addrlen);
  460. if (0 > sret)
  461. {
  462. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  463. "recvfrom");
  464. return;
  465. }
  466. GNUNET_break (size == sret);
  467. handle_request (listen_socket4,
  468. &v4,
  469. addrlen,
  470. buf,
  471. size);
  472. }
  473. }
  474. /**
  475. * Task to read IPv6 DNS packets.
  476. *
  477. * @param cls the 'listen_socket6'
  478. */
  479. static void
  480. read_dns6 (void *cls)
  481. {
  482. struct sockaddr_in6 v6;
  483. socklen_t addrlen;
  484. ssize_t size;
  485. const struct GNUNET_SCHEDULER_TaskContext *tc;
  486. GNUNET_assert (listen_socket6 == cls);
  487. t6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  488. listen_socket6,
  489. &read_dns6,
  490. listen_socket6);
  491. tc = GNUNET_SCHEDULER_get_task_context ();
  492. if (0 == (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason))
  493. return; /* shutdown? */
  494. size = GNUNET_NETWORK_socket_recvfrom_amount (listen_socket6);
  495. if (0 > size)
  496. {
  497. GNUNET_break (0);
  498. return; /* read error!? */
  499. }
  500. {
  501. char buf[size];
  502. ssize_t sret;
  503. addrlen = sizeof(v6);
  504. sret = GNUNET_NETWORK_socket_recvfrom (listen_socket6,
  505. buf,
  506. size,
  507. (struct sockaddr *) &v6,
  508. &addrlen);
  509. if (0 > sret)
  510. {
  511. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
  512. "recvfrom");
  513. return;
  514. }
  515. GNUNET_break (size == sret);
  516. handle_request (listen_socket6,
  517. &v6,
  518. addrlen,
  519. buf,
  520. size);
  521. }
  522. }
  523. /**
  524. * Main function that will be run.
  525. *
  526. * @param cls closure
  527. * @param args remaining command-line arguments
  528. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  529. * @param c configuration
  530. */
  531. static void
  532. run (void *cls,
  533. char *const *args,
  534. const char *cfgfile,
  535. const struct GNUNET_CONFIGURATION_Handle *c)
  536. {
  537. char *addr_str;
  538. (void) cls;
  539. (void) args;
  540. (void) cfgfile;
  541. cfg = c;
  542. if (NULL == dns_ip)
  543. {
  544. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  545. _ ("No DNS server specified!\n"));
  546. return;
  547. }
  548. GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
  549. NULL);
  550. if (NULL == (gns = GNUNET_GNS_connect (cfg)))
  551. return;
  552. GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128)));
  553. if (GNUNET_OK !=
  554. GNUNET_DNSSTUB_add_dns_ip (dns_stub,
  555. dns_ip))
  556. {
  557. GNUNET_DNSSTUB_stop (dns_stub);
  558. GNUNET_GNS_disconnect (gns);
  559. gns = NULL;
  560. return;
  561. }
  562. /* Get address to bind to */
  563. if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "dns2gns",
  564. "BIND_TO",
  565. &addr_str))
  566. {
  567. // No address specified
  568. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  569. "Don't know what to bind to...\n");
  570. GNUNET_free (addr_str);
  571. GNUNET_SCHEDULER_shutdown ();
  572. return;
  573. }
  574. if (1 != inet_pton (AF_INET, addr_str, &address))
  575. {
  576. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  577. "Unable to parse address %s\n",
  578. addr_str);
  579. GNUNET_free (addr_str);
  580. GNUNET_SCHEDULER_shutdown ();
  581. return;
  582. }
  583. GNUNET_free (addr_str);
  584. /* Get address to bind to */
  585. if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "dns2gns",
  586. "BIND_TO6",
  587. &addr_str))
  588. {
  589. // No address specified
  590. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  591. "Don't know what to bind6 to...\n");
  592. GNUNET_free (addr_str);
  593. GNUNET_SCHEDULER_shutdown ();
  594. return;
  595. }
  596. if (1 != inet_pton (AF_INET6, addr_str, &address6))
  597. {
  598. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  599. "Unable to parse IPv6 address %s\n",
  600. addr_str);
  601. GNUNET_free (addr_str);
  602. GNUNET_SCHEDULER_shutdown ();
  603. return;
  604. }
  605. GNUNET_free (addr_str);
  606. listen_socket4 = GNUNET_NETWORK_socket_create (PF_INET,
  607. SOCK_DGRAM,
  608. IPPROTO_UDP);
  609. if (NULL != listen_socket4)
  610. {
  611. struct sockaddr_in v4;
  612. memset (&v4, 0, sizeof(v4));
  613. v4.sin_family = AF_INET;
  614. v4.sin_addr.s_addr = address;
  615. #if HAVE_SOCKADDR_IN_SIN_LEN
  616. v4.sin_len = sizeof(v4);
  617. #endif
  618. v4.sin_port = htons (listen_port);
  619. if (GNUNET_OK !=
  620. GNUNET_NETWORK_socket_bind (listen_socket4,
  621. (struct sockaddr *) &v4,
  622. sizeof(v4)))
  623. {
  624. GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
  625. GNUNET_NETWORK_socket_close (listen_socket4);
  626. listen_socket4 = NULL;
  627. }
  628. }
  629. listen_socket6 = GNUNET_NETWORK_socket_create (PF_INET6,
  630. SOCK_DGRAM,
  631. IPPROTO_UDP);
  632. if (NULL != listen_socket6)
  633. {
  634. struct sockaddr_in6 v6;
  635. memset (&v6, 0, sizeof(v6));
  636. v6.sin6_family = AF_INET6;
  637. v6.sin6_addr = address6;
  638. #if HAVE_SOCKADDR_IN_SIN_LEN
  639. v6.sin6_len = sizeof(v6);
  640. #endif
  641. v6.sin6_port = htons (listen_port);
  642. if (GNUNET_OK !=
  643. GNUNET_NETWORK_socket_bind (listen_socket6,
  644. (struct sockaddr *) &v6,
  645. sizeof(v6)))
  646. {
  647. GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
  648. GNUNET_NETWORK_socket_close (listen_socket6);
  649. listen_socket6 = NULL;
  650. }
  651. }
  652. if ((NULL == listen_socket4) &&
  653. (NULL == listen_socket6))
  654. {
  655. GNUNET_GNS_disconnect (gns);
  656. gns = NULL;
  657. GNUNET_DNSSTUB_stop (dns_stub);
  658. dns_stub = NULL;
  659. return;
  660. }
  661. if (NULL != listen_socket4)
  662. t4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  663. listen_socket4,
  664. &read_dns4,
  665. listen_socket4);
  666. if (NULL != listen_socket6)
  667. t6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
  668. listen_socket6,
  669. &read_dns6,
  670. listen_socket6);
  671. }
  672. /**
  673. * The main function for the dns2gns daemon.
  674. *
  675. * @param argc number of arguments from the command line
  676. * @param argv command line arguments
  677. * @return 0 ok, 1 on error
  678. */
  679. int
  680. main (int argc,
  681. char *const *argv)
  682. {
  683. struct GNUNET_GETOPT_CommandLineOption options[] = {
  684. GNUNET_GETOPT_option_string ('d',
  685. "dns",
  686. "IP",
  687. gettext_noop (
  688. "IP of recursive DNS resolver to use (required)"),
  689. &dns_ip),
  690. GNUNET_GETOPT_option_uint ('p',
  691. "port",
  692. "UDPPORT",
  693. gettext_noop (
  694. "UDP port to listen on for inbound DNS requests; default: 2853"),
  695. &listen_port),
  696. GNUNET_GETOPT_OPTION_END
  697. };
  698. int ret;
  699. if (GNUNET_OK !=
  700. GNUNET_STRINGS_get_utf8_args (argc, argv,
  701. &argc, &argv))
  702. return 2;
  703. GNUNET_log_setup ("gnunet-dns2gns",
  704. "WARNING",
  705. NULL);
  706. ret =
  707. (GNUNET_OK ==
  708. GNUNET_PROGRAM_run (argc, argv,
  709. "gnunet-dns2gns",
  710. _ ("GNUnet DNS-to-GNS proxy (a DNS server)"),
  711. options,
  712. &run, NULL)) ? 0 : 1;
  713. GNUNET_free ((void *) argv);
  714. return ret;
  715. }
  716. /* end of gnunet-dns2gns.c */