gnunet-dns2gns.c 20 KB

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