gnunet-dns2gns.c 20 KB

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