diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-04-19 18:38:41 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-04-19 18:38:41 +0200 |
commit | ff4d7b51f37f61633766664647e9b148af1e4f0a (patch) | |
tree | 500aa14d9452ce90c19dbbb18cfaec0dd51e6ec2 /src/gns | |
parent | 9c699755967529e59815561d03b85e9a90d789f8 (diff) | |
download | gnunet-ff4d7b51f37f61633766664647e9b148af1e4f0a.tar.gz gnunet-ff4d7b51f37f61633766664647e9b148af1e4f0a.zip |
support multiple DNS resolvers for queries (in DNSSTUB and GNS2DNS resolution for now)
Diffstat (limited to 'src/gns')
-rw-r--r-- | src/gns/gnunet-dns2gns.c | 19 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns_resolver.c | 1072 | ||||
-rw-r--r-- | src/gns/test_gns_lookup.conf | 2 |
3 files changed, 600 insertions, 493 deletions
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c index 47cc6dde0..bc66f1325 100644 --- a/src/gns/gnunet-dns2gns.c +++ b/src/gns/gnunet-dns2gns.c | |||
@@ -247,19 +247,16 @@ do_timeout (void *cls) | |||
247 | * Iterator called on obtained result for a DNS lookup | 247 | * Iterator called on obtained result for a DNS lookup |
248 | * | 248 | * |
249 | * @param cls closure | 249 | * @param cls closure |
250 | * @param rs the request socket | ||
251 | * @param dns the DNS udp payload | 250 | * @param dns the DNS udp payload |
252 | * @param r size of the DNS payload | 251 | * @param r size of the DNS payload |
253 | */ | 252 | */ |
254 | static void | 253 | static void |
255 | dns_result_processor (void *cls, | 254 | dns_result_processor (void *cls, |
256 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
257 | const struct GNUNET_TUN_DnsHeader *dns, | 255 | const struct GNUNET_TUN_DnsHeader *dns, |
258 | size_t r) | 256 | size_t r) |
259 | { | 257 | { |
260 | struct Request *request = cls; | 258 | struct Request *request = cls; |
261 | 259 | ||
262 | (void) rs; | ||
263 | if (NULL == dns) | 260 | if (NULL == dns) |
264 | { | 261 | { |
265 | /* DNSSTUB gave up, so we trigger timeout early */ | 262 | /* DNSSTUB gave up, so we trigger timeout early */ |
@@ -307,11 +304,11 @@ result_processor (void *cls, | |||
307 | request->original_request_id = request->packet->id; | 304 | request->original_request_id = request->packet->id; |
308 | GNUNET_DNSPARSER_free_packet (request->packet); | 305 | GNUNET_DNSPARSER_free_packet (request->packet); |
309 | request->packet = NULL; | 306 | request->packet = NULL; |
310 | request->dns_lookup = GNUNET_DNSSTUB_resolve2 (dns_stub, | 307 | request->dns_lookup = GNUNET_DNSSTUB_resolve (dns_stub, |
311 | request->udp_msg, | 308 | request->udp_msg, |
312 | request->udp_msg_size, | 309 | request->udp_msg_size, |
313 | &dns_result_processor, | 310 | &dns_result_processor, |
314 | request); | 311 | request); |
315 | return; | 312 | return; |
316 | } | 313 | } |
317 | packet = request->packet; | 314 | packet = request->packet; |
@@ -594,8 +591,12 @@ run (void *cls, | |||
594 | NULL); | 591 | NULL); |
595 | if (NULL == (gns = GNUNET_GNS_connect (cfg))) | 592 | if (NULL == (gns = GNUNET_GNS_connect (cfg))) |
596 | return; | 593 | return; |
597 | if (NULL == (dns_stub = GNUNET_DNSSTUB_start (dns_ip))) | 594 | GNUNET_assert (NULL != (dns_stub = GNUNET_DNSSTUB_start (128))); |
595 | if (GNUNET_OK != | ||
596 | GNUNET_DNSSTUB_add_dns_ip (dns_stub, | ||
597 | dns_ip)) | ||
598 | { | 598 | { |
599 | GNUNET_DNSSTUB_stop (dns_stub); | ||
599 | GNUNET_GNS_disconnect (gns); | 600 | GNUNET_GNS_disconnect (gns); |
600 | gns = NULL; | 601 | gns = NULL; |
601 | return; | 602 | return; |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 94819b040..74eb47f29 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -72,6 +72,57 @@ | |||
72 | * DLL to hold the authority chain we had to pass in the resolution | 72 | * DLL to hold the authority chain we had to pass in the resolution |
73 | * process. | 73 | * process. |
74 | */ | 74 | */ |
75 | struct AuthorityChain; | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Element of a resolution process for looking up the | ||
80 | * responsible DNS server hostname in a GNS2DNS recursive | ||
81 | * resolution. | ||
82 | */ | ||
83 | struct Gns2DnsPending | ||
84 | { | ||
85 | |||
86 | /** | ||
87 | * Kept in a DLL. | ||
88 | */ | ||
89 | struct Gns2DnsPending *next; | ||
90 | |||
91 | /** | ||
92 | * Kept in a DLL. | ||
93 | */ | ||
94 | struct Gns2DnsPending *prev; | ||
95 | |||
96 | /** | ||
97 | * Context this activity belongs with. | ||
98 | */ | ||
99 | struct AuthorityChain *ac; | ||
100 | |||
101 | /** | ||
102 | * Handle for the resolution of the IP part of the | ||
103 | * GNS2DNS record. Will return to us the addresses | ||
104 | * of the DNS resolver to use. | ||
105 | */ | ||
106 | struct GNS_ResolverHandle *rh; | ||
107 | |||
108 | /** | ||
109 | * Handle for DNS resolution of the DNS nameserver. | ||
110 | */ | ||
111 | struct GNUNET_RESOLVER_RequestHandle *dns_rh; | ||
112 | }; | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Handle to a currenty pending resolution. On result (positive or | ||
117 | * negative) the #GNS_ResultProcessor is called. | ||
118 | */ | ||
119 | struct GNS_ResolverHandle; | ||
120 | |||
121 | |||
122 | /** | ||
123 | * DLL to hold the authority chain we had to pass in the resolution | ||
124 | * process. | ||
125 | */ | ||
75 | struct AuthorityChain | 126 | struct AuthorityChain |
76 | { | 127 | { |
77 | /** | 128 | /** |
@@ -131,11 +182,32 @@ struct AuthorityChain | |||
131 | char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1]; | 182 | char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1]; |
132 | 183 | ||
133 | /** | 184 | /** |
134 | * IP address of the DNS resolver that is authoritative. | 185 | * List of resolutions of the 'ip' of the name server that |
135 | * (this implementation currently only supports one | 186 | * are still pending. |
136 | * IP at a time). | 187 | */ |
188 | struct Gns2DnsPending *gp_head; | ||
189 | |||
190 | /** | ||
191 | * Tail of list of resolutions of the 'ip' of the name server that | ||
192 | * are still pending. | ||
193 | */ | ||
194 | struct Gns2DnsPending *gp_tail; | ||
195 | |||
196 | /** | ||
197 | * Handle to perform DNS lookups with this authority (in GNS2DNS handling). | ||
198 | */ | ||
199 | struct GNUNET_DNSSTUB_Context *dns_handle; | ||
200 | |||
201 | /** | ||
202 | * Did we succeed in getting an IP address for *any* of the DNS servers listed? | ||
203 | * Once we do, we can start with DNS queries. | ||
204 | */ | ||
205 | int found; | ||
206 | |||
207 | /** | ||
208 | * Did we start the recursive resolution via DNS? | ||
137 | */ | 209 | */ |
138 | struct sockaddr_storage dns_ip; | 210 | int launched; |
139 | 211 | ||
140 | } dns_authority; | 212 | } dns_authority; |
141 | 213 | ||
@@ -218,34 +290,6 @@ struct VpnContext | |||
218 | 290 | ||
219 | 291 | ||
220 | /** | 292 | /** |
221 | * Information we keep during the resolution of an | ||
222 | * IP address for a DNS server while handling a | ||
223 | * GNS2DNS record. | ||
224 | */ | ||
225 | struct Gns2DnsContext | ||
226 | { | ||
227 | |||
228 | /** | ||
229 | * DNS domain in which the resolution will continue | ||
230 | * (first part of the GNS2DNS record). | ||
231 | */ | ||
232 | char *ns; | ||
233 | |||
234 | /** | ||
235 | * Handle for the resolution of the IP part of the | ||
236 | * GNS2DNS record. Will return to us the addresses | ||
237 | * of the DNS resolver to use. | ||
238 | */ | ||
239 | struct GNS_ResolverHandle *rh; | ||
240 | |||
241 | /** | ||
242 | * Handle for DNS resolution of the DNS nameserver. | ||
243 | */ | ||
244 | struct GNUNET_RESOLVER_RequestHandle *dns_rh; | ||
245 | }; | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Handle to a currenty pending resolution. On result (positive or | 293 | * Handle to a currenty pending resolution. On result (positive or |
250 | * negative) the #GNS_ResultProcessor is called. | 294 | * negative) the #GNS_ResultProcessor is called. |
251 | */ | 295 | */ |
@@ -278,12 +322,6 @@ struct GNS_ResolverHandle | |||
278 | void* proc_cls; | 322 | void* proc_cls; |
279 | 323 | ||
280 | /** | 324 | /** |
281 | * Handle used during GNS2DNS resolution for looking up the | ||
282 | * IP address of the DNS server. | ||
283 | */ | ||
284 | struct Gns2DnsContext *g2dc; | ||
285 | |||
286 | /** | ||
287 | * Handle for DHT lookups. should be NULL if no lookups are in progress | 325 | * Handle for DHT lookups. should be NULL if no lookups are in progress |
288 | */ | 326 | */ |
289 | struct GNUNET_DHT_GetHandle *get_handle; | 327 | struct GNUNET_DHT_GetHandle *get_handle; |
@@ -431,11 +469,6 @@ static struct GNUNET_VPN_Handle *vpn_handle; | |||
431 | static struct GNUNET_DHT_Handle *dht_handle; | 469 | static struct GNUNET_DHT_Handle *dht_handle; |
432 | 470 | ||
433 | /** | 471 | /** |
434 | * Handle to perform DNS lookups. | ||
435 | */ | ||
436 | static struct GNUNET_DNSSTUB_Context *dns_handle; | ||
437 | |||
438 | /** | ||
439 | * Heap for limiting parallel DHT lookups | 472 | * Heap for limiting parallel DHT lookups |
440 | */ | 473 | */ |
441 | static struct GNUNET_CONTAINER_Heap *dht_lookup_heap; | 474 | static struct GNUNET_CONTAINER_Heap *dht_lookup_heap; |
@@ -543,21 +576,53 @@ translate_dot_plus (struct GNS_ResolverHandle *rh, | |||
543 | 576 | ||
544 | 577 | ||
545 | /** | 578 | /** |
546 | * Task scheduled to asynchronously fail a resolution. | 579 | * Wrapper around #GNS_resolver_lookup_cancel() as a task. |
580 | * Used for delayed cleanup so we can unwind the stack first. | ||
547 | * | 581 | * |
548 | * @param cls the 'struct GNS_ResolverHandle' of the resolution to fail | 582 | * @param cls the `struct GNS_ResolverHandle` |
549 | */ | 583 | */ |
550 | static void | 584 | static void |
551 | fail_resolution (void *cls) | 585 | GNS_resolver_lookup_cancel_ (void *cls) |
552 | { | 586 | { |
553 | struct GNS_ResolverHandle *rh = cls; | 587 | struct GNS_ResolverHandle *rh = cls; |
554 | 588 | ||
555 | rh->task_id = NULL; | 589 | rh->task_id = NULL; |
556 | rh->proc (rh->proc_cls, 0, NULL); | ||
557 | GNS_resolver_lookup_cancel (rh); | 590 | GNS_resolver_lookup_cancel (rh); |
558 | } | 591 | } |
559 | 592 | ||
560 | 593 | ||
594 | /** | ||
595 | * Function called to asynchronously fail a resolution. | ||
596 | * | ||
597 | * @param rh the resolution to fail | ||
598 | */ | ||
599 | static void | ||
600 | fail_resolution (struct GNS_ResolverHandle *rh) | ||
601 | { | ||
602 | rh->proc (rh->proc_cls, | ||
603 | 0, | ||
604 | NULL); | ||
605 | GNUNET_assert (NULL == rh->task_id); | ||
606 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
607 | rh); | ||
608 | } | ||
609 | |||
610 | |||
611 | /** | ||
612 | * Function called when a resolution times out. | ||
613 | * | ||
614 | * @param cls the `struct GNS_ResolverHandle` | ||
615 | */ | ||
616 | static void | ||
617 | timeout_resolution (void *cls) | ||
618 | { | ||
619 | struct GNS_ResolverHandle *rh = cls; | ||
620 | |||
621 | rh->task_id = NULL; | ||
622 | fail_resolution (rh); | ||
623 | } | ||
624 | |||
625 | |||
561 | #if (defined WINDOWS) || (defined DARWIN) | 626 | #if (defined WINDOWS) || (defined DARWIN) |
562 | /* Don't have this on W32, here's a naive implementation | 627 | /* Don't have this on W32, here's a naive implementation |
563 | * Was somehow removed on OS X ... */ | 628 | * Was somehow removed on OS X ... */ |
@@ -831,13 +896,11 @@ start_resolver_lookup (void *cls); | |||
831 | * | 896 | * |
832 | * @param cls the request handle of the resolution that | 897 | * @param cls the request handle of the resolution that |
833 | * we were attempting to make | 898 | * we were attempting to make |
834 | * @param rs socket that received the response | ||
835 | * @param dns dns response, never NULL | 899 | * @param dns dns response, never NULL |
836 | * @param dns_len number of bytes in @a dns | 900 | * @param dns_len number of bytes in @a dns |
837 | */ | 901 | */ |
838 | static void | 902 | static void |
839 | dns_result_parser (void *cls, | 903 | dns_result_parser (void *cls, |
840 | struct GNUNET_DNSSTUB_RequestSocket *rs, | ||
841 | const struct GNUNET_TUN_DnsHeader *dns, | 904 | const struct GNUNET_TUN_DnsHeader *dns, |
842 | size_t dns_len) | 905 | size_t dns_len) |
843 | { | 906 | { |
@@ -845,18 +908,13 @@ dns_result_parser (void *cls, | |||
845 | struct GNUNET_DNSPARSER_Packet *p; | 908 | struct GNUNET_DNSPARSER_Packet *p; |
846 | const struct GNUNET_DNSPARSER_Record *rec; | 909 | const struct GNUNET_DNSPARSER_Record *rec; |
847 | unsigned int rd_count; | 910 | unsigned int rd_count; |
848 | unsigned int i; | ||
849 | 911 | ||
850 | (void) rs; | ||
851 | if (NULL == dns) | 912 | if (NULL == dns) |
852 | { | 913 | { |
853 | rh->dns_request = NULL; | 914 | rh->dns_request = NULL; |
854 | GNUNET_SCHEDULER_cancel (rh->task_id); | 915 | GNUNET_SCHEDULER_cancel (rh->task_id); |
855 | rh->task_id = NULL; | 916 | rh->task_id = NULL; |
856 | rh->proc (rh->proc_cls, | 917 | fail_resolution (rh); |
857 | 0, | ||
858 | NULL); | ||
859 | GNS_resolver_lookup_cancel (rh); | ||
860 | return; | 918 | return; |
861 | } | 919 | } |
862 | if (rh->original_dns_id != dns->id) | 920 | if (rh->original_dns_id != dns->id) |
@@ -872,6 +930,8 @@ dns_result_parser (void *cls, | |||
872 | _("Failed to parse DNS response\n")); | 930 | _("Failed to parse DNS response\n")); |
873 | return; | 931 | return; |
874 | } | 932 | } |
933 | |||
934 | /* We got a result from DNS */ | ||
875 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 935 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
876 | "Received DNS response for `%s' with %u answers\n", | 936 | "Received DNS response for `%s' with %u answers\n", |
877 | rh->ac_tail->label, | 937 | rh->ac_tail->label, |
@@ -920,8 +980,10 @@ dns_result_parser (void *cls, | |||
920 | 980 | ||
921 | buf_off = 0; | 981 | buf_off = 0; |
922 | skip = 0; | 982 | skip = 0; |
923 | memset (rd, 0, sizeof (rd)); | 983 | memset (rd, |
924 | for (i=0;i<rd_count;i++) | 984 | 0, |
985 | sizeof (rd)); | ||
986 | for (unsigned int i=0;i<rd_count;i++) | ||
925 | { | 987 | { |
926 | if (i < p->num_answers) | 988 | if (i < p->num_answers) |
927 | rec = &p->answers[i]; | 989 | rec = &p->answers[i]; |
@@ -1043,9 +1105,12 @@ dns_result_parser (void *cls, | |||
1043 | rh->proc (rh->proc_cls, | 1105 | rh->proc (rh->proc_cls, |
1044 | rd_count - skip, | 1106 | rd_count - skip, |
1045 | rd); | 1107 | rd); |
1046 | GNS_resolver_lookup_cancel (rh); | ||
1047 | } | 1108 | } |
1048 | GNUNET_DNSPARSER_free_packet (p); | 1109 | GNUNET_DNSPARSER_free_packet (p); |
1110 | if (NULL != rh->task_id) | ||
1111 | GNUNET_SCHEDULER_cancel (rh->task_id); /* should be timeout task */ | ||
1112 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
1113 | rh); | ||
1049 | } | 1114 | } |
1050 | 1115 | ||
1051 | 1116 | ||
@@ -1061,7 +1126,6 @@ static void | |||
1061 | recursive_dns_resolution (struct GNS_ResolverHandle *rh) | 1126 | recursive_dns_resolution (struct GNS_ResolverHandle *rh) |
1062 | { | 1127 | { |
1063 | struct AuthorityChain *ac; | 1128 | struct AuthorityChain *ac; |
1064 | socklen_t sa_len; | ||
1065 | struct GNUNET_DNSPARSER_Query *query; | 1129 | struct GNUNET_DNSPARSER_Query *query; |
1066 | struct GNUNET_DNSPARSER_Packet *p; | 1130 | struct GNUNET_DNSPARSER_Packet *p; |
1067 | char *dns_request; | 1131 | char *dns_request; |
@@ -1074,20 +1138,6 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh) | |||
1074 | "Starting DNS lookup for `%s'\n", | 1138 | "Starting DNS lookup for `%s'\n", |
1075 | ac->label); | 1139 | ac->label); |
1076 | GNUNET_assert (GNUNET_NO == ac->gns_authority); | 1140 | GNUNET_assert (GNUNET_NO == ac->gns_authority); |
1077 | switch (((const struct sockaddr *) &ac->authority_info.dns_authority.dns_ip)->sa_family) | ||
1078 | { | ||
1079 | case AF_INET: | ||
1080 | sa_len = sizeof (struct sockaddr_in); | ||
1081 | break; | ||
1082 | case AF_INET6: | ||
1083 | sa_len = sizeof (struct sockaddr_in6); | ||
1084 | break; | ||
1085 | default: | ||
1086 | GNUNET_break (0); | ||
1087 | rh->proc (rh->proc_cls, 0, NULL); | ||
1088 | GNS_resolver_lookup_cancel (rh); | ||
1089 | return; | ||
1090 | } | ||
1091 | query = GNUNET_new (struct GNUNET_DNSPARSER_Query); | 1141 | query = GNUNET_new (struct GNUNET_DNSPARSER_Query); |
1092 | query->name = GNUNET_strdup (ac->label); | 1142 | query->name = GNUNET_strdup (ac->label); |
1093 | query->type = rh->record_type; | 1143 | query->type = rh->record_type; |
@@ -1109,20 +1159,22 @@ recursive_dns_resolution (struct GNS_ResolverHandle *rh) | |||
1109 | rh->proc (rh->proc_cls, | 1159 | rh->proc (rh->proc_cls, |
1110 | 0, | 1160 | 0, |
1111 | NULL); | 1161 | NULL); |
1112 | GNS_resolver_lookup_cancel (rh); | 1162 | GNUNET_assert (NULL == rh->task_id); |
1163 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
1164 | rh); | ||
1113 | } | 1165 | } |
1114 | else | 1166 | else |
1115 | { | 1167 | { |
1116 | rh->original_dns_id = p->id; | 1168 | rh->original_dns_id = p->id; |
1117 | rh->dns_request = GNUNET_DNSSTUB_resolve (dns_handle, | 1169 | GNUNET_assert (NULL != ac->authority_info.dns_authority.dns_handle); |
1118 | (const struct sockaddr *) &ac->authority_info.dns_authority.dns_ip, | 1170 | GNUNET_assert (NULL == rh->dns_request); |
1119 | sa_len, | 1171 | rh->dns_request = GNUNET_DNSSTUB_resolve (ac->authority_info.dns_authority.dns_handle, |
1120 | dns_request, | 1172 | dns_request, |
1121 | dns_request_length, | 1173 | dns_request_length, |
1122 | &dns_result_parser, | 1174 | &dns_result_parser, |
1123 | rh); | 1175 | rh); |
1124 | rh->task_id = GNUNET_SCHEDULER_add_delayed (DNS_LOOKUP_TIMEOUT, | 1176 | rh->task_id = GNUNET_SCHEDULER_add_delayed (DNS_LOOKUP_TIMEOUT, |
1125 | &fail_resolution, | 1177 | &timeout_resolution, |
1126 | rh); | 1178 | rh); |
1127 | } | 1179 | } |
1128 | if (GNUNET_SYSERR != ret) | 1180 | if (GNUNET_SYSERR != ret) |
@@ -1293,15 +1345,47 @@ vpn_allocation_cb (void *cls, | |||
1293 | 1345 | ||
1294 | 1346 | ||
1295 | /** | 1347 | /** |
1348 | * We have resolved one or more of the nameservers for a | ||
1349 | * GNS2DNS lookup. Once we have some of them, begin using | ||
1350 | * the DNSSTUB resolver. | ||
1351 | * | ||
1352 | * @param ac context for GNS2DNS resolution | ||
1353 | */ | ||
1354 | static void | ||
1355 | continue_with_gns2dns (struct AuthorityChain *ac) | ||
1356 | { | ||
1357 | struct GNS_ResolverHandle *rh = ac->rh; | ||
1358 | |||
1359 | if ( (NULL != ac->authority_info.dns_authority.gp_head) && | ||
1360 | (GNUNET_NO == ac->authority_info.dns_authority.found) ) | ||
1361 | return; /* more pending and none found yet */ | ||
1362 | if (GNUNET_NO == ac->authority_info.dns_authority.found) | ||
1363 | { | ||
1364 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1365 | "Failed to resolve DNS server for `%s' in GNS2DNS resolution\n", | ||
1366 | ac->authority_info.dns_authority.name); | ||
1367 | fail_resolution (rh); | ||
1368 | return; | ||
1369 | } | ||
1370 | if (GNUNET_NO != ac->authority_info.dns_authority.launched) | ||
1371 | return; /* already running, do not launch again! */ | ||
1372 | /* recurse */ | ||
1373 | ac->authority_info.dns_authority.launched = GNUNET_YES; | ||
1374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1375 | "Will continue resolution using DNS to resolve `%s'\n", | ||
1376 | ac->label); | ||
1377 | GNUNET_assert (NULL == rh->task_id); | ||
1378 | rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution, | ||
1379 | rh); | ||
1380 | |||
1381 | } | ||
1382 | |||
1383 | |||
1384 | /** | ||
1296 | * We've resolved the IP address for the DNS resolver to use | 1385 | * We've resolved the IP address for the DNS resolver to use |
1297 | * after encountering a GNS2DNS record. | 1386 | * after encountering a GNS2DNS record. |
1298 | * | 1387 | * |
1299 | * TODO: Right now we only foward the request to ONE DNS resolver, | 1388 | * @param cls the `struct Gns2DnsPending` used for this request |
1300 | * even if we get multiple IP addresses back; a correct implementation | ||
1301 | * should try all DNS resolvers. | ||
1302 | * | ||
1303 | * @param cls the `struct GNS_ResolverHandle` where we encountered | ||
1304 | * the GNS2DNS record | ||
1305 | * @param rd_count number of records in @a rd | 1389 | * @param rd_count number of records in @a rd |
1306 | * @param rd addresses for the DNS resolver (presumably) | 1390 | * @param rd addresses for the DNS resolver (presumably) |
1307 | */ | 1391 | */ |
@@ -1310,136 +1394,96 @@ handle_gns2dns_result (void *cls, | |||
1310 | unsigned int rd_count, | 1394 | unsigned int rd_count, |
1311 | const struct GNUNET_GNSRECORD_Data *rd) | 1395 | const struct GNUNET_GNSRECORD_Data *rd) |
1312 | { | 1396 | { |
1313 | struct GNS_ResolverHandle *rh = cls; | 1397 | struct Gns2DnsPending *gp = cls; |
1314 | struct AuthorityChain *ac; | 1398 | struct AuthorityChain *ac = gp->ac; |
1315 | struct sockaddr *sa; | 1399 | |
1316 | struct sockaddr_in v4; | 1400 | GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head, |
1317 | struct sockaddr_in6 v6; | 1401 | ac->authority_info.dns_authority.gp_tail, |
1318 | size_t sa_len; | 1402 | gp); |
1319 | 1403 | /* enable cleanup of 'rh' handle that automatically comes after we return, | |
1320 | /* find suitable A/AAAA record */ | 1404 | and which expects 'rh' to be in the #rlh_head DLL. */ |
1321 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1405 | if (NULL != gp->rh) |
1322 | "Received %u results for IP address of DNS server for GNS2DNS transition\n", | ||
1323 | rd_count); | ||
1324 | /* enable cleanup of 'rh' handle that comes next... */ | ||
1325 | if (NULL != rh->g2dc->rh) | ||
1326 | { | 1406 | { |
1327 | GNUNET_CONTAINER_DLL_insert (rlh_head, | 1407 | GNUNET_CONTAINER_DLL_insert (rlh_head, |
1328 | rlh_tail, | 1408 | rlh_tail, |
1329 | rh->g2dc->rh); | 1409 | gp->rh); |
1330 | rh->g2dc->rh = NULL; | 1410 | gp->rh = NULL; |
1331 | } | 1411 | } |
1332 | sa = NULL; | 1412 | GNUNET_free (gp); |
1333 | sa_len = 0; | 1413 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1414 | "Received %u results for IP address of DNS server for GNS2DNS transition\n", | ||
1415 | rd_count); | ||
1416 | /* find suitable A/AAAA record */ | ||
1334 | for (unsigned int j=0;j<rd_count;j++) | 1417 | for (unsigned int j=0;j<rd_count;j++) |
1335 | { | 1418 | { |
1336 | switch (rd[j].record_type) | 1419 | switch (rd[j].record_type) |
1337 | { | 1420 | { |
1338 | case GNUNET_DNSPARSER_TYPE_A: | 1421 | case GNUNET_DNSPARSER_TYPE_A: |
1339 | if (sizeof (struct in_addr) != rd[j].data_size) | ||
1340 | { | 1422 | { |
1341 | GNUNET_break_op (0); | 1423 | struct sockaddr_in v4; |
1342 | rh->proc (rh->proc_cls, 0, NULL); | 1424 | |
1343 | GNS_resolver_lookup_cancel (rh); | 1425 | if (sizeof (struct in_addr) != rd[j].data_size) |
1344 | return; | 1426 | { |
1345 | } | 1427 | GNUNET_break_op (0); |
1346 | /* FIXME: might want to check if we support IPv4 here, | 1428 | continue; |
1347 | and otherwise skip this one and hope we find another */ | 1429 | } |
1348 | memset (&v4, 0, sizeof (v4)); | 1430 | memset (&v4, |
1349 | sa_len = sizeof (v4); | 1431 | 0, |
1350 | v4.sin_family = AF_INET; | 1432 | sizeof (v4)); |
1351 | v4.sin_port = htons (53); | 1433 | v4.sin_family = AF_INET; |
1434 | v4.sin_port = htons (53); | ||
1352 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1435 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1353 | v4.sin_len = (u_char) sa_len; | 1436 | v4.sin_len = (u_char) sizeof (v4); |
1354 | #endif | 1437 | #endif |
1355 | GNUNET_memcpy (&v4.sin_addr, | 1438 | GNUNET_memcpy (&v4.sin_addr, |
1356 | rd[j].data, | 1439 | rd[j].data, |
1357 | sizeof (struct in_addr)); | 1440 | sizeof (struct in_addr)); |
1358 | sa = (struct sockaddr *) &v4; | 1441 | if (GNUNET_OK == |
1359 | break; | 1442 | GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle, |
1443 | (const struct sockaddr *) &v4)) | ||
1444 | ac->authority_info.dns_authority.found = GNUNET_YES; | ||
1445 | break; | ||
1446 | } | ||
1360 | case GNUNET_DNSPARSER_TYPE_AAAA: | 1447 | case GNUNET_DNSPARSER_TYPE_AAAA: |
1361 | if (sizeof (struct in6_addr) != rd[j].data_size) | ||
1362 | { | 1448 | { |
1363 | GNUNET_break_op (0); | 1449 | struct sockaddr_in6 v6; |
1364 | rh->proc (rh->proc_cls, 0, NULL); | 1450 | |
1365 | GNS_resolver_lookup_cancel (rh); | 1451 | if (sizeof (struct in6_addr) != rd[j].data_size) |
1366 | return; | 1452 | { |
1367 | } | 1453 | GNUNET_break_op (0); |
1368 | /* FIXME: might want to check if we support IPv6 here, | 1454 | continue; |
1369 | and otherwise skip this one and hope we find another */ | 1455 | } |
1370 | memset (&v6, 0, sizeof (v6)); | 1456 | /* FIXME: might want to check if we support IPv6 here, |
1371 | sa_len = sizeof (v6); | 1457 | and otherwise skip this one and hope we find another */ |
1372 | v6.sin6_family = AF_INET6; | 1458 | memset (&v6, |
1373 | v6.sin6_port = htons (53); | 1459 | 0, |
1460 | sizeof (v6)); | ||
1461 | v6.sin6_family = AF_INET6; | ||
1462 | v6.sin6_port = htons (53); | ||
1374 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1463 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1375 | v6.sin6_len = (u_char) sa_len; | 1464 | v6.sin6_len = (u_char) sizeof (v6); |
1376 | #endif | 1465 | #endif |
1377 | GNUNET_memcpy (&v6.sin6_addr, | 1466 | GNUNET_memcpy (&v6.sin6_addr, |
1378 | rd[j].data, | 1467 | rd[j].data, |
1379 | sizeof (struct in6_addr)); | 1468 | sizeof (struct in6_addr)); |
1380 | sa = (struct sockaddr *) &v6; | 1469 | if (GNUNET_OK == |
1381 | break; | 1470 | GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle, |
1471 | (const struct sockaddr *) &v6)) | ||
1472 | ac->authority_info.dns_authority.found = GNUNET_YES; | ||
1473 | break; | ||
1474 | } | ||
1382 | default: | 1475 | default: |
1383 | break; | 1476 | break; |
1384 | } | 1477 | } |
1385 | if (NULL != sa) | ||
1386 | break; | ||
1387 | } | ||
1388 | if (NULL == sa) | ||
1389 | { | ||
1390 | /* we cannot continue; NS without A/AAAA */ | ||
1391 | rh->proc (rh->proc_cls, 0, NULL); | ||
1392 | GNS_resolver_lookup_cancel (rh); | ||
1393 | return; | ||
1394 | } | ||
1395 | /* expand authority chain */ | ||
1396 | ac = GNUNET_new (struct AuthorityChain); | ||
1397 | ac->rh = rh; | ||
1398 | GNUNET_assert (strlen (rh->g2dc->ns) <= GNUNET_DNSPARSER_MAX_NAME_LENGTH); | ||
1399 | strcpy (ac->authority_info.dns_authority.name, | ||
1400 | rh->g2dc->ns); | ||
1401 | GNUNET_memcpy (&ac->authority_info.dns_authority.dns_ip, | ||
1402 | sa, | ||
1403 | sa_len); | ||
1404 | /* for DNS recursion, the label is the full DNS name, | ||
1405 | created from the remainder of the GNS name and the | ||
1406 | name in the NS record */ | ||
1407 | GNUNET_asprintf (&ac->label, | ||
1408 | "%.*s%s%s", | ||
1409 | (int) rh->name_resolution_pos, | ||
1410 | rh->name, | ||
1411 | (0 != rh->name_resolution_pos) ? "." : "", | ||
1412 | rh->g2dc->ns); | ||
1413 | GNUNET_free (rh->g2dc->ns); | ||
1414 | GNUNET_free (rh->g2dc); | ||
1415 | rh->g2dc = NULL; | ||
1416 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1417 | "Will continue resolution using DNS server `%s' to resolve `%s'\n", | ||
1418 | GNUNET_a2s (sa, | ||
1419 | sa_len), | ||
1420 | ac->label); | ||
1421 | GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, | ||
1422 | rh->ac_tail, | ||
1423 | ac); | ||
1424 | if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH) | ||
1425 | { | ||
1426 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1427 | _("GNS lookup resulted in DNS name that is too long (`%s')\n"), | ||
1428 | ac->label); | ||
1429 | rh->proc (rh->proc_cls, 0, NULL); | ||
1430 | GNS_resolver_lookup_cancel (rh); | ||
1431 | return; | ||
1432 | } | 1478 | } |
1433 | /* recurse */ | 1479 | continue_with_gns2dns (ac); |
1434 | rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution, | ||
1435 | rh); | ||
1436 | } | 1480 | } |
1437 | 1481 | ||
1438 | 1482 | ||
1439 | /** | 1483 | /** |
1440 | * Function called by the resolver for each address obtained from DNS. | 1484 | * Function called by the resolver for each address obtained from DNS. |
1441 | * | 1485 | * |
1442 | * @param cls closure, a `struct Gns2DnsContext *` | 1486 | * @param cls closure, a `struct Gns2DnsPending *` |
1443 | * @param addr one of the addresses of the host, NULL for the last address | 1487 | * @param addr one of the addresses of the host, NULL for the last address |
1444 | * @param addrlen length of @a addr | 1488 | * @param addrlen length of @a addr |
1445 | */ | 1489 | */ |
@@ -1448,57 +1492,270 @@ handle_gns2dns_ip (void *cls, | |||
1448 | const struct sockaddr *addr, | 1492 | const struct sockaddr *addr, |
1449 | socklen_t addrlen) | 1493 | socklen_t addrlen) |
1450 | { | 1494 | { |
1451 | struct Gns2DnsContext *g2dc = cls; | 1495 | struct Gns2DnsPending *gp = cls; |
1452 | struct GNUNET_GNSRECORD_Data rd; | 1496 | struct AuthorityChain *ac = gp->ac; |
1453 | 1497 | ||
1498 | GNUNET_RESOLVER_request_cancel (gp->dns_rh); | ||
1499 | GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head, | ||
1500 | ac->authority_info.dns_authority.gp_tail, | ||
1501 | gp); | ||
1502 | GNUNET_free (gp); | ||
1454 | if (NULL == addr) | 1503 | if (NULL == addr) |
1455 | { | 1504 | { |
1456 | /* DNS resolution failed */ | 1505 | /* DNS resolution failed */ |
1457 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1506 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1458 | "Failed to use DNS to resolve name of DNS resolver\n"); | 1507 | "Failed to use DNS to resolve name of DNS resolver\n"); |
1459 | g2dc->rh->g2dc = NULL; | ||
1460 | fail_resolution (g2dc->rh); | ||
1461 | GNUNET_free (g2dc); | ||
1462 | } | 1508 | } |
1463 | switch (addr->sa_family) | 1509 | else |
1464 | { | 1510 | { |
1465 | case AF_INET: | 1511 | if (GNUNET_OK == |
1512 | GNUNET_DNSSTUB_add_dns_sa (ac->authority_info.dns_authority.dns_handle, | ||
1513 | addr)) | ||
1514 | ac->authority_info.dns_authority.found = GNUNET_YES; | ||
1515 | } | ||
1516 | continue_with_gns2dns (ac); | ||
1517 | } | ||
1518 | |||
1519 | |||
1520 | /** | ||
1521 | * We found a CNAME record, perform recursive resolution on it. | ||
1522 | * | ||
1523 | * @param rh resolution handle | ||
1524 | * @param rd record with CNAME to resolve recursively | ||
1525 | */ | ||
1526 | static void | ||
1527 | recursive_cname_resolution (struct GNS_ResolverHandle *rh, | ||
1528 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1529 | { | ||
1530 | char *cname; | ||
1531 | size_t off; | ||
1532 | |||
1533 | off = 0; | ||
1534 | cname = GNUNET_DNSPARSER_parse_name (rd->data, | ||
1535 | rd->data_size, | ||
1536 | &off); | ||
1537 | if ( (NULL == cname) || | ||
1538 | (off != rd->data_size) ) | ||
1539 | { | ||
1540 | GNUNET_break_op (0); /* record not well-formed */ | ||
1541 | GNUNET_free_non_null (cname); | ||
1542 | fail_resolution (rh); | ||
1543 | return; | ||
1544 | } | ||
1545 | handle_gns_cname_result (rh, | ||
1546 | cname); | ||
1547 | GNUNET_free (cname); | ||
1548 | } | ||
1549 | |||
1550 | |||
1551 | /** | ||
1552 | * We found a PKEY record, perform recursive resolution on it. | ||
1553 | * | ||
1554 | * @param rh resolution handle | ||
1555 | * @param rd record with PKEY to resolve recursively | ||
1556 | */ | ||
1557 | static void | ||
1558 | recursive_pkey_resolution (struct GNS_ResolverHandle *rh, | ||
1559 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1560 | { | ||
1561 | struct AuthorityChain *ac; | ||
1562 | |||
1563 | /* delegation to another zone */ | ||
1564 | if (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) != | ||
1565 | rd->data_size) | ||
1566 | { | ||
1567 | GNUNET_break_op (0); | ||
1568 | fail_resolution (rh); | ||
1569 | return; | ||
1570 | } | ||
1571 | /* expand authority chain */ | ||
1572 | ac = GNUNET_new (struct AuthorityChain); | ||
1573 | ac->rh = rh; | ||
1574 | ac->gns_authority = GNUNET_YES; | ||
1575 | ac->suggested_shortening_label = NULL; | ||
1576 | ac->shortening_started = GNUNET_NO; | ||
1577 | GNUNET_memcpy (&ac->authority_info.gns_authority, | ||
1578 | rd->data, | ||
1579 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
1580 | ac->label = resolver_lookup_get_next_label (rh); | ||
1581 | /* add AC to tail */ | ||
1582 | GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, | ||
1583 | rh->ac_tail, | ||
1584 | ac); | ||
1585 | /* recurse */ | ||
1586 | rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution, | ||
1587 | rh); | ||
1588 | } | ||
1589 | |||
1590 | |||
1591 | /** | ||
1592 | * We found one or more GNS2DNS records, perform recursive resolution on it. | ||
1593 | * (to be precise, one or more records in @a rd is GNS2DNS, there may be others, | ||
1594 | * so this function still needs to check which ones are GNS2DNS). | ||
1595 | * | ||
1596 | * @param rh resolution handle | ||
1597 | * @param rd_count length of the @a rd array | ||
1598 | * @param rd record with PKEY to resolve recursively | ||
1599 | * @return #GNUNET_OK if this worked, #GNUNET_SYSERR if no GNS2DNS records were in @a rd | ||
1600 | */ | ||
1601 | static int | ||
1602 | recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh, | ||
1603 | unsigned int rd_count, | ||
1604 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1605 | { | ||
1606 | struct AuthorityChain *ac; | ||
1607 | const char *tld; | ||
1608 | char *ns; | ||
1609 | |||
1610 | ns = NULL; | ||
1611 | /* expand authority chain */ | ||
1612 | ac = GNUNET_new (struct AuthorityChain); | ||
1613 | ac->rh = rh; | ||
1614 | ac->authority_info.dns_authority.dns_handle = GNUNET_DNSSTUB_start (4); | ||
1615 | |||
1616 | for (unsigned int i=0;i<rd_count;i++) | ||
1617 | { | ||
1618 | char *ip; | ||
1619 | char *n; | ||
1620 | size_t off; | ||
1621 | struct Gns2DnsPending *gp; | ||
1622 | struct GNUNET_CRYPTO_EcdsaPublicKey zone; | ||
1623 | |||
1624 | if (GNUNET_GNSRECORD_TYPE_GNS2DNS != rd[i].record_type) | ||
1625 | continue; | ||
1626 | off = 0; | ||
1627 | n = GNUNET_DNSPARSER_parse_name (rd[i].data, | ||
1628 | rd[i].data_size, | ||
1629 | &off); | ||
1630 | ip = GNUNET_DNSPARSER_parse_name (rd[i].data, | ||
1631 | rd[i].data_size, | ||
1632 | &off); | ||
1633 | if ( (NULL == n) || | ||
1634 | (NULL == ip) || | ||
1635 | (off != rd[i].data_size) ) | ||
1466 | { | 1636 | { |
1467 | const struct sockaddr_in *v4 = (const struct sockaddr_in *) addr; | 1637 | GNUNET_break_op (0); |
1468 | 1638 | GNUNET_free_non_null (n); | |
1469 | GNUNET_assert (sizeof (*v4) == addrlen); | 1639 | GNUNET_free_non_null (ip); |
1470 | rd.data = v4; | 1640 | continue; |
1471 | rd.data_size = sizeof (*v4); | ||
1472 | rd.expiration_time = UINT64_MAX; | ||
1473 | rd.record_type = GNUNET_DNSPARSER_TYPE_A; | ||
1474 | rd.flags = 0; | ||
1475 | break; | ||
1476 | } | 1641 | } |
1477 | case AF_INET6: | 1642 | /* resolve 'ip' to determine the IP(s) of the DNS |
1643 | resolver to use for lookup of 'ns' */ | ||
1644 | if (NULL != ns) | ||
1478 | { | 1645 | { |
1479 | const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *) addr; | 1646 | if (0 != strcasecmp (ns, |
1480 | 1647 | n)) | |
1481 | GNUNET_assert (sizeof (*v6) == addrlen); | 1648 | { |
1482 | rd.data = v6; | 1649 | /* NS values must all be the same for all GNS2DNS records, |
1483 | rd.data_size = sizeof (v6); | 1650 | anything else leads to insanity */ |
1484 | rd.expiration_time = UINT64_MAX; | 1651 | GNUNET_break_op (0); |
1485 | rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA; | 1652 | GNUNET_free (n); |
1486 | rd.flags = 0; | 1653 | GNUNET_free (ip); |
1487 | break; | 1654 | continue; |
1655 | } | ||
1656 | GNUNET_free (n); | ||
1657 | } | ||
1658 | else | ||
1659 | { | ||
1660 | ns = n; | ||
1488 | } | 1661 | } |
1489 | default: | ||
1490 | return; | ||
1491 | } | ||
1492 | GNUNET_RESOLVER_request_cancel (g2dc->dns_rh); | ||
1493 | g2dc->dns_rh = NULL; | ||
1494 | handle_gns2dns_result (g2dc->rh, | ||
1495 | 1, | ||
1496 | &rd); | ||
1497 | 1662 | ||
1663 | /* check if 'ip' is already an IPv4/IPv6 address */ | ||
1664 | if (GNUNET_OK == | ||
1665 | GNUNET_DNSSTUB_add_dns_ip (ac->authority_info.dns_authority.dns_handle, | ||
1666 | ip)) | ||
1667 | { | ||
1668 | ac->authority_info.dns_authority.found = GNUNET_YES; | ||
1669 | GNUNET_free (ip); | ||
1670 | continue; | ||
1671 | } | ||
1672 | tld = GNS_get_tld (ip); | ||
1673 | if (0 != strcmp (tld, | ||
1674 | "+")) | ||
1675 | { | ||
1676 | /* 'ip' is a DNS name */ | ||
1677 | gp = GNUNET_new (struct Gns2DnsPending); | ||
1678 | gp->ac = ac; | ||
1679 | GNUNET_CONTAINER_DLL_insert (ac->authority_info.dns_authority.gp_head, | ||
1680 | ac->authority_info.dns_authority.gp_tail, | ||
1681 | gp); | ||
1682 | gp->dns_rh = GNUNET_RESOLVER_ip_get (ip, | ||
1683 | AF_UNSPEC, | ||
1684 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1685 | &handle_gns2dns_ip, | ||
1686 | gp); | ||
1687 | GNUNET_free (ip); | ||
1688 | continue; | ||
1689 | } | ||
1690 | /* 'ip' should be a GNS name */ | ||
1691 | gp = GNUNET_new (struct Gns2DnsPending); | ||
1692 | gp->ac = ac; | ||
1693 | GNUNET_CONTAINER_DLL_insert (ac->authority_info.dns_authority.gp_head, | ||
1694 | ac->authority_info.dns_authority.gp_tail, | ||
1695 | gp); | ||
1696 | gp->rh = GNUNET_new (struct GNS_ResolverHandle); | ||
1697 | ip = translate_dot_plus (rh, | ||
1698 | ip); | ||
1699 | tld = GNS_get_tld (ip); | ||
1700 | if (GNUNET_OK != | ||
1701 | GNUNET_GNSRECORD_zkey_to_pkey (tld, | ||
1702 | &zone)) | ||
1703 | { | ||
1704 | GNUNET_break_op (0); | ||
1705 | GNUNET_free (ip); | ||
1706 | continue; | ||
1707 | } | ||
1708 | gp->rh->authority_zone = zone; | ||
1709 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1710 | "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n", | ||
1711 | ip, | ||
1712 | ns); | ||
1713 | gp->rh->name = ip; | ||
1714 | gp->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1; | ||
1715 | gp->rh->proc = &handle_gns2dns_result; | ||
1716 | gp->rh->proc_cls = gp; | ||
1717 | gp->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY; | ||
1718 | gp->rh->options = GNUNET_GNS_LO_DEFAULT; | ||
1719 | gp->rh->loop_limiter = rh->loop_limiter + 1; | ||
1720 | gp->rh->task_id | ||
1721 | = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, | ||
1722 | gp->rh); | ||
1723 | } /* end 'for all records' */ | ||
1724 | |||
1725 | if (NULL == ns) | ||
1726 | { | ||
1727 | /* not a single GNS2DNS record found */ | ||
1728 | GNUNET_free (ac); | ||
1729 | return GNUNET_SYSERR; | ||
1730 | } | ||
1731 | GNUNET_assert (strlen (ns) <= GNUNET_DNSPARSER_MAX_NAME_LENGTH); | ||
1732 | strcpy (ac->authority_info.dns_authority.name, | ||
1733 | ns); | ||
1734 | /* for DNS recursion, the label is the full DNS name, | ||
1735 | created from the remainder of the GNS name and the | ||
1736 | name in the NS record */ | ||
1737 | GNUNET_asprintf (&ac->label, | ||
1738 | "%.*s%s%s", | ||
1739 | (int) rh->name_resolution_pos, | ||
1740 | rh->name, | ||
1741 | (0 != rh->name_resolution_pos) ? "." : "", | ||
1742 | ns); | ||
1743 | GNUNET_free (ns); | ||
1744 | GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, | ||
1745 | rh->ac_tail, | ||
1746 | ac); | ||
1747 | if (strlen (ac->label) > GNUNET_DNSPARSER_MAX_NAME_LENGTH) | ||
1748 | { | ||
1749 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1750 | _("GNS lookup resulted in DNS name that is too long (`%s')\n"), | ||
1751 | ac->label); | ||
1752 | return GNUNET_SYSERR; | ||
1753 | } | ||
1754 | continue_with_gns2dns (ac); | ||
1755 | return GNUNET_OK; | ||
1498 | } | 1756 | } |
1499 | 1757 | ||
1500 | 1758 | ||
1501 | |||
1502 | /** | 1759 | /** |
1503 | * Process a records that were decrypted from a block. | 1760 | * Process a records that were decrypted from a block. |
1504 | * | 1761 | * |
@@ -1512,7 +1769,6 @@ handle_gns_resolution_result (void *cls, | |||
1512 | const struct GNUNET_GNSRECORD_Data *rd) | 1769 | const struct GNUNET_GNSRECORD_Data *rd) |
1513 | { | 1770 | { |
1514 | struct GNS_ResolverHandle *rh = cls; | 1771 | struct GNS_ResolverHandle *rh = cls; |
1515 | struct AuthorityChain *ac; | ||
1516 | struct AuthorityChain *shorten_ac; | 1772 | struct AuthorityChain *shorten_ac; |
1517 | char *cname; | 1773 | char *cname; |
1518 | struct VpnContext *vpn_ctx; | 1774 | struct VpnContext *vpn_ctx; |
@@ -1532,6 +1788,14 @@ handle_gns_resolution_result (void *cls, | |||
1532 | rh->ac_tail->label, | 1788 | rh->ac_tail->label, |
1533 | GNUNET_GNSRECORD_z2s (&rh->ac_tail->authority_info.gns_authority), | 1789 | GNUNET_GNSRECORD_z2s (&rh->ac_tail->authority_info.gns_authority), |
1534 | rd_count); | 1790 | rd_count); |
1791 | if (0 == rd_count) | ||
1792 | { | ||
1793 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1794 | _("GNS lookup failed (zero records found)\n")); | ||
1795 | fail_resolution (rh); | ||
1796 | return; | ||
1797 | } | ||
1798 | |||
1535 | if (0 == rh->name_resolution_pos) | 1799 | if (0 == rh->name_resolution_pos) |
1536 | { | 1800 | { |
1537 | /* top-level match, are we done yet? */ | 1801 | /* top-level match, are we done yet? */ |
@@ -1547,9 +1811,8 @@ handle_gns_resolution_result (void *cls, | |||
1547 | (off != rd[0].data_size) ) | 1811 | (off != rd[0].data_size) ) |
1548 | { | 1812 | { |
1549 | GNUNET_break_op (0); | 1813 | GNUNET_break_op (0); |
1550 | rh->proc (rh->proc_cls, 0, NULL); | ||
1551 | GNS_resolver_lookup_cancel (rh); | ||
1552 | GNUNET_free_non_null (cname); | 1814 | GNUNET_free_non_null (cname); |
1815 | fail_resolution (rh); | ||
1553 | return; | 1816 | return; |
1554 | } | 1817 | } |
1555 | handle_gns_cname_result (rh, | 1818 | handle_gns_cname_result (rh, |
@@ -1573,8 +1836,7 @@ handle_gns_resolution_result (void *cls, | |||
1573 | rd[i].data_size) | 1836 | rd[i].data_size) |
1574 | { | 1837 | { |
1575 | GNUNET_break_op (0); | 1838 | GNUNET_break_op (0); |
1576 | rh->proc (rh->proc_cls, 0, NULL); | 1839 | fail_resolution (rh); |
1577 | GNS_resolver_lookup_cancel (rh); | ||
1578 | return; | 1840 | return; |
1579 | } | 1841 | } |
1580 | vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data; | 1842 | vpn = (const struct GNUNET_TUN_GnsVpnRecord *) rd[i].data; |
@@ -1582,8 +1844,7 @@ handle_gns_resolution_result (void *cls, | |||
1582 | if ('\0' != vname[rd[i].data_size - 1 - sizeof (struct GNUNET_TUN_GnsVpnRecord)]) | 1844 | if ('\0' != vname[rd[i].data_size - 1 - sizeof (struct GNUNET_TUN_GnsVpnRecord)]) |
1583 | { | 1845 | { |
1584 | GNUNET_break_op (0); | 1846 | GNUNET_break_op (0); |
1585 | rh->proc (rh->proc_cls, 0, NULL); | 1847 | fail_resolution (rh); |
1586 | GNS_resolver_lookup_cancel (rh); | ||
1587 | return; | 1848 | return; |
1588 | } | 1849 | } |
1589 | GNUNET_TUN_service_name_to_hash (vname, | 1850 | GNUNET_TUN_service_name_to_hash (vname, |
@@ -1621,7 +1882,13 @@ handle_gns_resolution_result (void *cls, | |||
1621 | /* delegation to DNS */ | 1882 | /* delegation to DNS */ |
1622 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1623 | "Found GNS2DNS record, delegating to DNS!\n"); | 1884 | "Found GNS2DNS record, delegating to DNS!\n"); |
1624 | goto do_recurse; | 1885 | if (GNUNET_OK == |
1886 | recursive_gns2dns_resolution (rh, | ||
1887 | rd_count, | ||
1888 | rd)) | ||
1889 | return; | ||
1890 | else | ||
1891 | goto fail; | ||
1625 | } | 1892 | } |
1626 | default: | 1893 | default: |
1627 | break; | 1894 | break; |
@@ -1823,7 +2090,9 @@ handle_gns_resolution_result (void *cls, | |||
1823 | GNUNET_break_op (0); | 2090 | GNUNET_break_op (0); |
1824 | break; | 2091 | break; |
1825 | } | 2092 | } |
1826 | GNUNET_memcpy (&pub, rd[i].data, rd[i].data_size); | 2093 | GNUNET_memcpy (&pub, |
2094 | rd[i].data, | ||
2095 | rd[i].data_size); | ||
1827 | rd_off++; | 2096 | rd_off++; |
1828 | if (GNUNET_GNSRECORD_TYPE_PKEY != rh->record_type) | 2097 | if (GNUNET_GNSRECORD_TYPE_PKEY != rh->record_type) |
1829 | { | 2098 | { |
@@ -1856,7 +2125,13 @@ handle_gns_resolution_result (void *cls, | |||
1856 | } | 2125 | } |
1857 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2126 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1858 | "Found GNS2DNS record, delegating to DNS!\n"); | 2127 | "Found GNS2DNS record, delegating to DNS!\n"); |
1859 | goto do_recurse; | 2128 | if (GNUNET_OK == |
2129 | recursive_gns2dns_resolution (rh, | ||
2130 | rd_count, | ||
2131 | rd)) | ||
2132 | return; | ||
2133 | else | ||
2134 | goto fail; | ||
1860 | } | 2135 | } |
1861 | case GNUNET_GNSRECORD_TYPE_BOX: | 2136 | case GNUNET_GNSRECORD_TYPE_BOX: |
1862 | { | 2137 | { |
@@ -1901,200 +2176,35 @@ handle_gns_resolution_result (void *cls, | |||
1901 | rh->proc (rh->proc_cls, | 2176 | rh->proc (rh->proc_cls, |
1902 | rd_off, | 2177 | rd_off, |
1903 | rd_new); | 2178 | rd_new); |
1904 | GNS_resolver_lookup_cancel (rh); | 2179 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, |
2180 | rh); | ||
1905 | return; | 2181 | return; |
1906 | } | 2182 | } |
1907 | do_recurse: | 2183 | |
1908 | /* need to recurse, check if we can */ | 2184 | switch (rd[0].record_type) |
1909 | for (unsigned int i=0;i<rd_count;i++) | ||
1910 | { | 2185 | { |
1911 | switch (rd[i].record_type) | 2186 | case GNUNET_DNSPARSER_TYPE_CNAME: |
1912 | { | 2187 | GNUNET_break_op (1 == rd_count); /* CNAME should be unique */ |
1913 | case GNUNET_GNSRECORD_TYPE_PKEY: | 2188 | recursive_cname_resolution (rh, |
1914 | /* delegation to another zone */ | 2189 | &rd[0]); |
1915 | if (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) != | 2190 | return; |
1916 | rd[i].data_size) | 2191 | case GNUNET_GNSRECORD_TYPE_PKEY: |
1917 | { | 2192 | GNUNET_break_op (1 == rd_count); /* PKEY should be unique */ |
1918 | GNUNET_break_op (0); | 2193 | recursive_pkey_resolution (rh, |
1919 | rh->proc (rh->proc_cls, 0, NULL); | 2194 | &rd[0]); |
1920 | GNS_resolver_lookup_cancel (rh); | 2195 | return; |
1921 | return; | 2196 | default: |
1922 | } | 2197 | if (GNUNET_OK == |
1923 | /* expand authority chain */ | 2198 | recursive_gns2dns_resolution (rh, |
1924 | ac = GNUNET_new (struct AuthorityChain); | 2199 | rd_count, |
1925 | ac->rh = rh; | 2200 | rd)) |
1926 | ac->gns_authority = GNUNET_YES; | ||
1927 | ac->suggested_shortening_label = NULL; | ||
1928 | ac->shortening_started = GNUNET_NO; | ||
1929 | GNUNET_memcpy (&ac->authority_info.gns_authority, | ||
1930 | rd[i].data, | ||
1931 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
1932 | ac->label = resolver_lookup_get_next_label (rh); | ||
1933 | /* add AC to tail */ | ||
1934 | GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head, | ||
1935 | rh->ac_tail, | ||
1936 | ac); | ||
1937 | /* recurse */ | ||
1938 | rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution, | ||
1939 | rh); | ||
1940 | return; | 2201 | return; |
1941 | case GNUNET_GNSRECORD_TYPE_GNS2DNS: | 2202 | break; |
1942 | { | ||
1943 | /* TODO: Right now we only foward the request to ONE DNS resolver, | ||
1944 | even if we get multiple IP addresses back; a correct implementation | ||
1945 | should try all DNS resolvers. */ | ||
1946 | /* resolution continues within DNS */ | ||
1947 | struct Gns2DnsContext *g2dc; | ||
1948 | char *ip; | ||
1949 | char *ns; | ||
1950 | const char *tld; | ||
1951 | struct GNUNET_CRYPTO_EcdsaPublicKey zone; | ||
1952 | struct in_addr v4; | ||
1953 | struct in6_addr v6; | ||
1954 | |||
1955 | off = 0; | ||
1956 | ns = GNUNET_DNSPARSER_parse_name (rd[i].data, | ||
1957 | rd[i].data_size, | ||
1958 | &off); | ||
1959 | ip = GNUNET_DNSPARSER_parse_name (rd[i].data, | ||
1960 | rd[i].data_size, | ||
1961 | &off); | ||
1962 | if ( (NULL == ns) || | ||
1963 | (NULL == ip) || | ||
1964 | (off != rd[i].data_size) ) | ||
1965 | { | ||
1966 | GNUNET_break_op (0); | ||
1967 | GNUNET_free_non_null (ns); | ||
1968 | GNUNET_free_non_null (ip); | ||
1969 | fail_resolution (rh); | ||
1970 | return; | ||
1971 | } | ||
1972 | /* resolve 'ip' to determine the IP(s) of the DNS | ||
1973 | resolver to use for lookup of 'ns' */ | ||
1974 | g2dc = GNUNET_new (struct Gns2DnsContext); | ||
1975 | g2dc->ns = ns; | ||
1976 | rh->g2dc = g2dc; | ||
1977 | |||
1978 | /* check if 'ip' is already an IPv4/IPv6 address */ | ||
1979 | if (1 == inet_pton (AF_INET, | ||
1980 | ip, | ||
1981 | &v4)) | ||
1982 | { | ||
1983 | /* name is IPv4 address, pretend it's an A record */ | ||
1984 | struct GNUNET_GNSRECORD_Data rd; | ||
1985 | |||
1986 | GNUNET_free (ip); | ||
1987 | rd.data = &v4; | ||
1988 | rd.data_size = sizeof (v4); | ||
1989 | rd.expiration_time = UINT64_MAX; | ||
1990 | rd.record_type = GNUNET_DNSPARSER_TYPE_A; | ||
1991 | rd.flags = 0; | ||
1992 | handle_gns2dns_result (rh, | ||
1993 | 1, | ||
1994 | &rd); | ||
1995 | return; | ||
1996 | } | ||
1997 | if (1 == inet_pton (AF_INET6, | ||
1998 | ip, | ||
1999 | &v6)) | ||
2000 | { | ||
2001 | /* name is IPv6 address, pretend it's an AAAA record */ | ||
2002 | struct GNUNET_GNSRECORD_Data rd; | ||
2003 | |||
2004 | GNUNET_free (ip); | ||
2005 | rd.data = &v6; | ||
2006 | rd.data_size = sizeof (v6); | ||
2007 | rd.expiration_time = UINT64_MAX; | ||
2008 | rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA; | ||
2009 | rd.flags = 0; | ||
2010 | handle_gns2dns_result (rh, | ||
2011 | 1, | ||
2012 | &rd); | ||
2013 | return; | ||
2014 | } | ||
2015 | |||
2016 | tld = GNS_get_tld (ip); | ||
2017 | if (0 != strcmp (tld, | ||
2018 | "+")) | ||
2019 | { | ||
2020 | /* 'ip' is a DNS name */ | ||
2021 | g2dc->dns_rh = GNUNET_RESOLVER_ip_get (ip, | ||
2022 | AF_UNSPEC, | ||
2023 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
2024 | &handle_gns2dns_ip, | ||
2025 | g2dc); | ||
2026 | GNUNET_free (ip); | ||
2027 | return; | ||
2028 | } | ||
2029 | |||
2030 | /* 'ip' should be a GNS name */ | ||
2031 | g2dc->rh = GNUNET_new (struct GNS_ResolverHandle); | ||
2032 | |||
2033 | ip = translate_dot_plus (rh, | ||
2034 | ip); | ||
2035 | tld = GNS_get_tld (ip); | ||
2036 | if (GNUNET_OK != | ||
2037 | GNUNET_GNSRECORD_zkey_to_pkey (tld, | ||
2038 | &zone)) | ||
2039 | { | ||
2040 | GNUNET_break_op (0); | ||
2041 | GNUNET_free_non_null (ns); | ||
2042 | GNUNET_free_non_null (ip); | ||
2043 | GNUNET_free (g2dc); | ||
2044 | fail_resolution (rh); | ||
2045 | return; | ||
2046 | } | ||
2047 | g2dc->rh->authority_zone = zone; | ||
2048 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2049 | "Resolving `%s' to determine IP address of DNS server for GNS2DNS transition for `%s'\n", | ||
2050 | ip, | ||
2051 | ns); | ||
2052 | g2dc->rh->name = ip; | ||
2053 | g2dc->rh->name_resolution_pos = strlen (ip) - strlen (tld) - 1; | ||
2054 | g2dc->rh->proc = &handle_gns2dns_result; | ||
2055 | g2dc->rh->proc_cls = rh; | ||
2056 | g2dc->rh->record_type = GNUNET_GNSRECORD_TYPE_ANY; | ||
2057 | g2dc->rh->options = GNUNET_GNS_LO_DEFAULT; | ||
2058 | g2dc->rh->loop_limiter = rh->loop_limiter + 1; | ||
2059 | g2dc->rh->task_id | ||
2060 | = GNUNET_SCHEDULER_add_now (&start_resolver_lookup, | ||
2061 | g2dc->rh); | ||
2062 | return; | ||
2063 | } | ||
2064 | case GNUNET_DNSPARSER_TYPE_CNAME: | ||
2065 | { | ||
2066 | char *cname; | ||
2067 | |||
2068 | off = 0; | ||
2069 | cname = GNUNET_DNSPARSER_parse_name (rd[i].data, | ||
2070 | rd[i].data_size, | ||
2071 | &off); | ||
2072 | if ( (NULL == cname) || | ||
2073 | (off != rd[i].data_size) ) | ||
2074 | { | ||
2075 | GNUNET_break_op (0); /* record not well-formed */ | ||
2076 | rh->proc (rh->proc_cls, 0, NULL); | ||
2077 | GNS_resolver_lookup_cancel (rh); | ||
2078 | GNUNET_free_non_null (cname); | ||
2079 | return; | ||
2080 | } | ||
2081 | handle_gns_cname_result (rh, | ||
2082 | cname); | ||
2083 | GNUNET_free (cname); | ||
2084 | return; | ||
2085 | } | ||
2086 | /* FIXME: handle DNAME */ | ||
2087 | default: | ||
2088 | /* skip */ | ||
2089 | break; | ||
2090 | } | ||
2091 | } | 2203 | } |
2204 | fail: | ||
2092 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2205 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2093 | _("GNS lookup recursion failed (no delegation record found)\n")); | 2206 | _("GNS lookup recursion failed (no delegation record found)\n")); |
2094 | rh->proc (rh->proc_cls, | 2207 | fail_resolution (rh); |
2095 | 0, | ||
2096 | NULL); | ||
2097 | GNS_resolver_lookup_cancel (rh); | ||
2098 | } | 2208 | } |
2099 | 2209 | ||
2100 | 2210 | ||
@@ -2176,8 +2286,7 @@ handle_dht_response (void *cls, | |||
2176 | { | 2286 | { |
2177 | /* how did this pass DHT block validation!? */ | 2287 | /* how did this pass DHT block validation!? */ |
2178 | GNUNET_break (0); | 2288 | GNUNET_break (0); |
2179 | rh->proc (rh->proc_cls, 0, NULL); | 2289 | fail_resolution (rh); |
2180 | GNS_resolver_lookup_cancel (rh); | ||
2181 | return; | 2290 | return; |
2182 | } | 2291 | } |
2183 | block = data; | 2292 | block = data; |
@@ -2188,8 +2297,7 @@ handle_dht_response (void *cls, | |||
2188 | { | 2297 | { |
2189 | /* how did this pass DHT block validation!? */ | 2298 | /* how did this pass DHT block validation!? */ |
2190 | GNUNET_break (0); | 2299 | GNUNET_break (0); |
2191 | rh->proc (rh->proc_cls, 0, NULL); | 2300 | fail_resolution (rh); |
2192 | GNS_resolver_lookup_cancel (rh); | ||
2193 | return; | 2301 | return; |
2194 | } | 2302 | } |
2195 | if (GNUNET_OK != | 2303 | if (GNUNET_OK != |
@@ -2200,8 +2308,7 @@ handle_dht_response (void *cls, | |||
2200 | rh)) | 2308 | rh)) |
2201 | { | 2309 | { |
2202 | GNUNET_break_op (0); /* block was ill-formed */ | 2310 | GNUNET_break_op (0); /* block was ill-formed */ |
2203 | rh->proc (rh->proc_cls, 0, NULL); | 2311 | fail_resolution (rh); |
2204 | GNS_resolver_lookup_cancel (rh); | ||
2205 | return; | 2312 | return; |
2206 | } | 2313 | } |
2207 | if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (block->expiration_time)).rel_value_us) | 2314 | if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (block->expiration_time)).rel_value_us) |
@@ -2252,8 +2359,7 @@ start_dht_request (struct GNS_ResolverHandle *rh, | |||
2252 | /* fail longest-standing DHT request */ | 2359 | /* fail longest-standing DHT request */ |
2253 | rx = GNUNET_CONTAINER_heap_peek (dht_lookup_heap); | 2360 | rx = GNUNET_CONTAINER_heap_peek (dht_lookup_heap); |
2254 | GNUNET_assert (NULL != rx); | 2361 | GNUNET_assert (NULL != rx); |
2255 | rx->proc (rx->proc_cls, 0, NULL); | 2362 | fail_resolution (rx); |
2256 | GNS_resolver_lookup_cancel (rx); | ||
2257 | } | 2363 | } |
2258 | } | 2364 | } |
2259 | 2365 | ||
@@ -2324,8 +2430,7 @@ handle_namecache_block_response (void *cls, | |||
2324 | "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n", | 2430 | "Resolution failed for `%s' in zone %s (DHT lookup not permitted by configuration)\n", |
2325 | ac->label, | 2431 | ac->label, |
2326 | GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority)); | 2432 | GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority)); |
2327 | rh->proc (rh->proc_cls, 0, NULL); | 2433 | fail_resolution (rh); |
2328 | GNS_resolver_lookup_cancel (rh); | ||
2329 | return; | 2434 | return; |
2330 | } | 2435 | } |
2331 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2436 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -2408,8 +2513,7 @@ handle_revocation_result (void *cls, | |||
2408 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2513 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2409 | _("Zone %s was revoked, resolution fails\n"), | 2514 | _("Zone %s was revoked, resolution fails\n"), |
2410 | GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority)); | 2515 | GNUNET_GNSRECORD_z2s (&ac->authority_info.gns_authority)); |
2411 | rh->proc (rh->proc_cls, 0, NULL); | 2516 | fail_resolution (rh); |
2412 | GNS_resolver_lookup_cancel (rh); | ||
2413 | return; | 2517 | return; |
2414 | } | 2518 | } |
2415 | recursive_gns_resolution_namecache (rh); | 2519 | recursive_gns_resolution_namecache (rh); |
@@ -2453,8 +2557,7 @@ recursive_resolution (void *cls) | |||
2453 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 2557 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2454 | "Encountered unbounded recursion resolving `%s'\n", | 2558 | "Encountered unbounded recursion resolving `%s'\n", |
2455 | rh->name); | 2559 | rh->name); |
2456 | rh->proc (rh->proc_cls, 0, NULL); | 2560 | fail_resolution (rh); |
2457 | GNS_resolver_lookup_cancel (rh); | ||
2458 | return; | 2561 | return; |
2459 | } | 2562 | } |
2460 | if (GNUNET_YES == rh->ac_tail->gns_authority) | 2563 | if (GNUNET_YES == rh->ac_tail->gns_authority) |
@@ -2491,8 +2594,12 @@ start_resolver_lookup (void *cls) | |||
2491 | rd.expiration_time = UINT64_MAX; | 2594 | rd.expiration_time = UINT64_MAX; |
2492 | rd.record_type = GNUNET_DNSPARSER_TYPE_A; | 2595 | rd.record_type = GNUNET_DNSPARSER_TYPE_A; |
2493 | rd.flags = 0; | 2596 | rd.flags = 0; |
2494 | rh->proc (rh->proc_cls, 1, &rd); | 2597 | rh->proc (rh->proc_cls, |
2495 | GNS_resolver_lookup_cancel (rh); | 2598 | 1, |
2599 | &rd); | ||
2600 | GNUNET_assert (NULL == rh->task_id); | ||
2601 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
2602 | rh); | ||
2496 | return; | 2603 | return; |
2497 | } | 2604 | } |
2498 | if (1 == inet_pton (AF_INET6, | 2605 | if (1 == inet_pton (AF_INET6, |
@@ -2507,8 +2614,12 @@ start_resolver_lookup (void *cls) | |||
2507 | rd.expiration_time = UINT64_MAX; | 2614 | rd.expiration_time = UINT64_MAX; |
2508 | rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA; | 2615 | rd.record_type = GNUNET_DNSPARSER_TYPE_AAAA; |
2509 | rd.flags = 0; | 2616 | rd.flags = 0; |
2510 | rh->proc (rh->proc_cls, 1, &rd); | 2617 | rh->proc (rh->proc_cls, |
2511 | GNS_resolver_lookup_cancel (rh); | 2618 | 1, |
2619 | &rd); | ||
2620 | GNUNET_assert (NULL == rh->task_id); | ||
2621 | rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
2622 | rh); | ||
2512 | return; | 2623 | return; |
2513 | } | 2624 | } |
2514 | 2625 | ||
@@ -2587,37 +2698,51 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh) | |||
2587 | GNUNET_CONTAINER_DLL_remove (rlh_head, | 2698 | GNUNET_CONTAINER_DLL_remove (rlh_head, |
2588 | rlh_tail, | 2699 | rlh_tail, |
2589 | rh); | 2700 | rh); |
2701 | if (NULL != rh->dns_request) | ||
2702 | { | ||
2703 | GNUNET_DNSSTUB_resolve_cancel (rh->dns_request); | ||
2704 | rh->dns_request = NULL; | ||
2705 | } | ||
2590 | while (NULL != (ac = rh->ac_head)) | 2706 | while (NULL != (ac = rh->ac_head)) |
2591 | { | 2707 | { |
2592 | GNUNET_CONTAINER_DLL_remove (rh->ac_head, | 2708 | GNUNET_CONTAINER_DLL_remove (rh->ac_head, |
2593 | rh->ac_tail, | 2709 | rh->ac_tail, |
2594 | ac); | 2710 | ac); |
2711 | if (GNUNET_NO == ac->gns_authority) | ||
2712 | { | ||
2713 | struct Gns2DnsPending *gp; | ||
2714 | |||
2715 | while (NULL != (gp = ac->authority_info.dns_authority.gp_head)) | ||
2716 | { | ||
2717 | GNUNET_CONTAINER_DLL_remove (ac->authority_info.dns_authority.gp_head, | ||
2718 | ac->authority_info.dns_authority.gp_tail, | ||
2719 | gp); | ||
2720 | if (NULL != gp->rh) | ||
2721 | { | ||
2722 | /* rh->g2dc->rh is NOT in the DLL yet, so to enable us | ||
2723 | using GNS_resolver_lookup_cancel here, we need to | ||
2724 | add it first... */ | ||
2725 | GNUNET_CONTAINER_DLL_insert (rlh_head, | ||
2726 | rlh_tail, | ||
2727 | gp->rh); | ||
2728 | GNUNET_assert (NULL == gp->rh->task_id); | ||
2729 | gp->rh->task_id = GNUNET_SCHEDULER_add_now (&GNS_resolver_lookup_cancel_, | ||
2730 | gp->rh); | ||
2731 | gp->rh = NULL; | ||
2732 | } | ||
2733 | if (NULL != gp->dns_rh) | ||
2734 | { | ||
2735 | GNUNET_RESOLVER_request_cancel (gp->dns_rh); | ||
2736 | gp->dns_rh = NULL; | ||
2737 | } | ||
2738 | GNUNET_free (gp); | ||
2739 | } | ||
2740 | GNUNET_DNSSTUB_stop (ac->authority_info.dns_authority.dns_handle); | ||
2741 | } | ||
2595 | GNUNET_free (ac->label); | 2742 | GNUNET_free (ac->label); |
2596 | GNUNET_free_non_null (ac->suggested_shortening_label); | 2743 | GNUNET_free_non_null (ac->suggested_shortening_label); |
2597 | GNUNET_free (ac); | 2744 | GNUNET_free (ac); |
2598 | } | 2745 | } |
2599 | if (NULL != rh->g2dc) | ||
2600 | { | ||
2601 | /* rh->g2dc->rh is NOT in the DLL yet, so to enable us | ||
2602 | using GNS_resolver_lookup_cancel here, we need to | ||
2603 | add it first... */ | ||
2604 | if (NULL != rh->g2dc->rh) | ||
2605 | { | ||
2606 | GNUNET_CONTAINER_DLL_insert (rlh_head, | ||
2607 | rlh_tail, | ||
2608 | rh->g2dc->rh); | ||
2609 | GNS_resolver_lookup_cancel (rh->g2dc->rh); | ||
2610 | rh->g2dc->rh = NULL; | ||
2611 | } | ||
2612 | if (NULL != rh->g2dc->dns_rh) | ||
2613 | { | ||
2614 | GNUNET_RESOLVER_request_cancel (rh->g2dc->dns_rh); | ||
2615 | rh->g2dc->rh = NULL; | ||
2616 | } | ||
2617 | GNUNET_free (rh->g2dc->ns); | ||
2618 | GNUNET_free (rh->g2dc); | ||
2619 | rh->g2dc = NULL; | ||
2620 | } | ||
2621 | if (NULL != rh->task_id) | 2746 | if (NULL != rh->task_id) |
2622 | { | 2747 | { |
2623 | GNUNET_SCHEDULER_cancel (rh->task_id); | 2748 | GNUNET_SCHEDULER_cancel (rh->task_id); |
@@ -2639,11 +2764,6 @@ GNS_resolver_lookup_cancel (struct GNS_ResolverHandle *rh) | |||
2639 | GNUNET_free (vpn_ctx->rd_data); | 2764 | GNUNET_free (vpn_ctx->rd_data); |
2640 | GNUNET_free (vpn_ctx); | 2765 | GNUNET_free (vpn_ctx); |
2641 | } | 2766 | } |
2642 | if (NULL != rh->dns_request) | ||
2643 | { | ||
2644 | GNUNET_DNSSTUB_resolve_cancel (rh->dns_request); | ||
2645 | rh->dns_request = NULL; | ||
2646 | } | ||
2647 | if (NULL != rh->namecache_qe) | 2767 | if (NULL != rh->namecache_qe) |
2648 | { | 2768 | { |
2649 | GNUNET_NAMECACHE_cancel (rh->namecache_qe); | 2769 | GNUNET_NAMECACHE_cancel (rh->namecache_qe); |
@@ -2690,8 +2810,6 @@ GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc, | |||
2690 | const struct GNUNET_CONFIGURATION_Handle *c, | 2810 | const struct GNUNET_CONFIGURATION_Handle *c, |
2691 | unsigned long long max_bg_queries) | 2811 | unsigned long long max_bg_queries) |
2692 | { | 2812 | { |
2693 | char *dns_ip; | ||
2694 | |||
2695 | cfg = c; | 2813 | cfg = c; |
2696 | namecache_handle = nc; | 2814 | namecache_handle = nc; |
2697 | dht_handle = dht; | 2815 | dht_handle = dht; |
@@ -2706,18 +2824,6 @@ GNS_resolver_init (struct GNUNET_NAMECACHE_Handle *nc, | |||
2706 | if (GNUNET_NO == use_cache) | 2824 | if (GNUNET_NO == use_cache) |
2707 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2825 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
2708 | "Namecache disabled\n"); | 2826 | "Namecache disabled\n"); |
2709 | |||
2710 | if (GNUNET_OK != | ||
2711 | GNUNET_CONFIGURATION_get_value_string (c, | ||
2712 | "gns", | ||
2713 | "DNS_RESOLVER", | ||
2714 | &dns_ip)) | ||
2715 | { | ||
2716 | /* user did not specify DNS resolver, use 8.8.8.8 */ | ||
2717 | dns_ip = GNUNET_strdup ("8.8.8.8"); | ||
2718 | } | ||
2719 | dns_handle = GNUNET_DNSSTUB_start (dns_ip); | ||
2720 | GNUNET_free (dns_ip); | ||
2721 | vpn_handle = GNUNET_VPN_connect (cfg); | 2827 | vpn_handle = GNUNET_VPN_connect (cfg); |
2722 | } | 2828 | } |
2723 | 2829 | ||
@@ -2734,7 +2840,9 @@ GNS_resolver_done () | |||
2734 | /* abort active resolutions */ | 2840 | /* abort active resolutions */ |
2735 | while (NULL != (rh = rlh_head)) | 2841 | while (NULL != (rh = rlh_head)) |
2736 | { | 2842 | { |
2737 | rh->proc (rh->proc_cls, 0, NULL); | 2843 | rh->proc (rh->proc_cls, |
2844 | 0, | ||
2845 | NULL); | ||
2738 | GNS_resolver_lookup_cancel (rh); | 2846 | GNS_resolver_lookup_cancel (rh); |
2739 | } | 2847 | } |
2740 | while (NULL != (co = co_head)) | 2848 | while (NULL != (co = co_head)) |
@@ -2747,8 +2855,6 @@ GNS_resolver_done () | |||
2747 | } | 2855 | } |
2748 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); | 2856 | GNUNET_CONTAINER_heap_destroy (dht_lookup_heap); |
2749 | dht_lookup_heap = NULL; | 2857 | dht_lookup_heap = NULL; |
2750 | GNUNET_DNSSTUB_stop (dns_handle); | ||
2751 | dns_handle = NULL; | ||
2752 | GNUNET_VPN_disconnect (vpn_handle); | 2858 | GNUNET_VPN_disconnect (vpn_handle); |
2753 | vpn_handle = NULL; | 2859 | vpn_handle = NULL; |
2754 | dht_handle = NULL; | 2860 | dht_handle = NULL; |
diff --git a/src/gns/test_gns_lookup.conf b/src/gns/test_gns_lookup.conf index ea8c7c3fc..a9a2345c7 100644 --- a/src/gns/test_gns_lookup.conf +++ b/src/gns/test_gns_lookup.conf | |||
@@ -10,7 +10,7 @@ AUTOSTART = YES | |||
10 | PLUGINS = | 10 | PLUGINS = |
11 | 11 | ||
12 | [gns] | 12 | [gns] |
13 | #PREFIX = valgrind --leak-check=full --track-origins=yes | 13 | # PREFIX = valgrind --leak-check=full --track-origins=yes |
14 | AUTOSTART = YES | 14 | AUTOSTART = YES |
15 | AUTO_IMPORT_PKEY = YES | 15 | AUTO_IMPORT_PKEY = YES |
16 | MAX_PARALLEL_BACKGROUND_QUERIES = 10 | 16 | MAX_PARALLEL_BACKGROUND_QUERIES = 10 |