aboutsummaryrefslogtreecommitdiff
path: root/src/util/gnunet-service-resolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/gnunet-service-resolver.c')
-rw-r--r--src/util/gnunet-service-resolver.c408
1 files changed, 203 insertions, 205 deletions
diff --git a/src/util/gnunet-service-resolver.c b/src/util/gnunet-service-resolver.c
index 39f31745f..f49ec3882 100644
--- a/src/util/gnunet-service-resolver.c
+++ b/src/util/gnunet-service-resolver.c
@@ -88,8 +88,7 @@ getnameinfo_resolve (struct IPCache *cache)
88 char hostname[256]; 88 char hostname[256];
89 89
90 if (0 == getnameinfo (cache->sa, 90 if (0 == getnameinfo (cache->sa,
91 cache->salen, 91 cache->salen, hostname, sizeof (hostname), NULL, 0, 0))
92 hostname, sizeof (hostname), NULL, 0, 0))
93 cache->addr = GNUNET_strdup (hostname); 92 cache->addr = GNUNET_strdup (hostname);
94} 93}
95#endif 94#endif
@@ -107,18 +106,18 @@ gethostbyaddr_resolve (struct IPCache *cache)
107 struct hostent *ent; 106 struct hostent *ent;
108 107
109 switch (cache->sa->sa_family) 108 switch (cache->sa->sa_family)
110 { 109 {
111 case AF_INET: 110 case AF_INET:
112 ent = gethostbyaddr (&((struct sockaddr_in *) cache->sa)->sin_addr, 111 ent = gethostbyaddr (&((struct sockaddr_in *) cache->sa)->sin_addr,
113 sizeof (struct in_addr), AF_INET); 112 sizeof (struct in_addr), AF_INET);
114 break; 113 break;
115 case AF_INET6: 114 case AF_INET6:
116 ent = gethostbyaddr (&((struct sockaddr_in6 *) cache->sa)->sin6_addr, 115 ent = gethostbyaddr (&((struct sockaddr_in6 *) cache->sa)->sin6_addr,
117 sizeof (struct in6_addr), AF_INET6); 116 sizeof (struct in6_addr), AF_INET6);
118 break; 117 break;
119 default: 118 default:
120 ent = NULL; 119 ent = NULL;
121 } 120 }
122 if (ent != NULL) 121 if (ent != NULL)
123 cache->addr = GNUNET_strdup (ent->h_name); 122 cache->addr = GNUNET_strdup (ent->h_name);
124} 123}
@@ -164,74 +163,74 @@ get_ip_as_string (struct GNUNET_SERVER_Client *client,
164 struct GNUNET_SERVER_TransmitContext *tc; 163 struct GNUNET_SERVER_TransmitContext *tc;
165 164
166 if (salen < sizeof (struct sockaddr)) 165 if (salen < sizeof (struct sockaddr))
167 { 166 {
168 GNUNET_break (0); 167 GNUNET_break (0);
169 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 168 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
170 return; 169 return;
171 } 170 }
172 now = GNUNET_TIME_absolute_get (); 171 now = GNUNET_TIME_absolute_get ();
173 cache = head; 172 cache = head;
174 prev = NULL; 173 prev = NULL;
175 while ((cache != NULL) && 174 while ((cache != NULL) &&
176 ((cache->salen != salen) || (0 != memcmp (cache->sa, sa, salen)))) 175 ((cache->salen != salen) || (0 != memcmp (cache->sa, sa, salen))))
176 {
177 if (GNUNET_TIME_absolute_get_duration (cache->last_request).rel_value <
178 60 * 60 * 1000)
177 { 179 {
178 if (GNUNET_TIME_absolute_get_duration (cache->last_request).rel_value < 180 if (prev != NULL)
179 60 * 60 * 1000) 181 {
180 { 182 prev->next = cache->next;
181 if (prev != NULL) 183 GNUNET_free_non_null (cache->addr);
182 { 184 GNUNET_free (cache->sa);
183 prev->next = cache->next; 185 GNUNET_free (cache);
184 GNUNET_free_non_null (cache->addr); 186 cache = prev->next;
185 GNUNET_free (cache->sa); 187 }
186 GNUNET_free (cache); 188 else
187 cache = prev->next; 189 {
188 } 190 head = cache->next;
189 else 191 GNUNET_free_non_null (cache->addr);
190 { 192 GNUNET_free (cache->sa);
191 head = cache->next; 193 GNUNET_free (cache);
192 GNUNET_free_non_null (cache->addr); 194 cache = head;
193 GNUNET_free (cache->sa); 195 }
194 GNUNET_free (cache); 196 continue;
195 cache = head;
196 }
197 continue;
198 }
199 prev = cache;
200 cache = cache->next;
201 } 197 }
198 prev = cache;
199 cache = cache->next;
200 }
202 if (cache != NULL) 201 if (cache != NULL)
202 {
203 cache->last_request = now;
204 if (GNUNET_TIME_absolute_get_duration (cache->last_request).rel_value <
205 60 * 60 * 1000)
203 { 206 {
204 cache->last_request = now; 207 GNUNET_free_non_null (cache->addr);
205 if (GNUNET_TIME_absolute_get_duration (cache->last_request).rel_value <
206 60 * 60 * 1000)
207 {
208 GNUNET_free_non_null (cache->addr);
209 cache->addr = NULL;
210 cache->salen = 0;
211 cache_resolve (cache);
212 }
213 }
214 else
215 {
216 cache = GNUNET_malloc (sizeof (struct IPCache));
217 cache->next = head;
218 cache->salen = salen;
219 cache->sa = GNUNET_malloc (salen);
220 memcpy (cache->sa, sa, salen);
221 cache->last_request = GNUNET_TIME_absolute_get ();
222 cache->last_refresh = GNUNET_TIME_absolute_get ();
223 cache->addr = NULL; 208 cache->addr = NULL;
209 cache->salen = 0;
224 cache_resolve (cache); 210 cache_resolve (cache);
225 head = cache;
226 } 211 }
212 }
213 else
214 {
215 cache = GNUNET_malloc (sizeof (struct IPCache));
216 cache->next = head;
217 cache->salen = salen;
218 cache->sa = GNUNET_malloc (salen);
219 memcpy (cache->sa, sa, salen);
220 cache->last_request = GNUNET_TIME_absolute_get ();
221 cache->last_refresh = GNUNET_TIME_absolute_get ();
222 cache->addr = NULL;
223 cache_resolve (cache);
224 head = cache;
225 }
227 tc = GNUNET_SERVER_transmit_context_create (client); 226 tc = GNUNET_SERVER_transmit_context_create (client);
228 if (cache->addr != NULL) 227 if (cache->addr != NULL)
229 GNUNET_SERVER_transmit_context_append_data (tc, 228 GNUNET_SERVER_transmit_context_append_data (tc,
230 cache->addr, 229 cache->addr,
231 strlen (cache->addr) + 1, 230 strlen (cache->addr) + 1,
232 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 231 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
233 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 232 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
234 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 233 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
235 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 234 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
236} 235}
237 236
@@ -256,35 +255,35 @@ getaddrinfo_resolve (struct GNUNET_SERVER_TransmitContext *tc,
256 hints.ai_socktype = SOCK_STREAM; /* go for TCP */ 255 hints.ai_socktype = SOCK_STREAM; /* go for TCP */
257 256
258 if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result))) 257 if (0 != (s = getaddrinfo (hostname, NULL, &hints, &result)))
259 { 258 {
260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 259 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
261 _("Could not resolve `%s' (%s): %s\n"), hostname, 260 _("Could not resolve `%s' (%s): %s\n"), hostname,
262 (domain == 261 (domain ==
263 AF_INET) ? "IPv4" : ((domain == 262 AF_INET) ? "IPv4" : ((domain ==
264 AF_INET6) ? "IPv6" : "any"), 263 AF_INET6) ? "IPv6" : "any"),
265 gai_strerror (s)); 264 gai_strerror (s));
266 if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY) 265 if ((s == EAI_BADFLAGS) || (s == EAI_MEMORY)
267#ifndef MINGW 266#ifndef MINGW
268 || (s == EAI_SYSTEM) 267 || (s == EAI_SYSTEM)
269#else 268#else
270 // FIXME NILS 269 // FIXME NILS
271 || 1 270 || 1
272#endif 271#endif
273 ) 272 )
274 return GNUNET_NO; /* other function may still succeed */ 273 return GNUNET_NO; /* other function may still succeed */
275 return GNUNET_SYSERR; 274 return GNUNET_SYSERR;
276 } 275 }
277 if (result == NULL) 276 if (result == NULL)
278 return GNUNET_SYSERR; 277 return GNUNET_SYSERR;
279 pos = result; 278 pos = result;
280 while (pos != NULL) 279 while (pos != NULL)
281 { 280 {
282 GNUNET_SERVER_transmit_context_append_data (tc, 281 GNUNET_SERVER_transmit_context_append_data (tc,
283 pos->ai_addr, 282 pos->ai_addr,
284 pos->ai_addrlen, 283 pos->ai_addrlen,
285 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 284 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
286 pos = pos->ai_next; 285 pos = pos->ai_next;
287 } 286 }
288 freeaddrinfo (result); 287 freeaddrinfo (result);
289 return GNUNET_OK; 288 return GNUNET_OK;
290} 289}
@@ -302,52 +301,52 @@ gethostbyname2_resolve (struct GNUNET_SERVER_TransmitContext *tc,
302 int ret2; 301 int ret2;
303 302
304 if (domain == AF_UNSPEC) 303 if (domain == AF_UNSPEC)
305 { 304 {
306 ret1 = gethostbyname2_resolve (tc, hostname, AF_INET); 305 ret1 = gethostbyname2_resolve (tc, hostname, AF_INET);
307 ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6); 306 ret2 = gethostbyname2_resolve (tc, hostname, AF_INET6);
308 if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK)) 307 if ((ret1 == GNUNET_OK) || (ret2 == GNUNET_OK))
309 return GNUNET_OK; 308 return GNUNET_OK;
310 if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR)) 309 if ((ret1 == GNUNET_SYSERR) || (ret2 == GNUNET_SYSERR))
311 return GNUNET_SYSERR; 310 return GNUNET_SYSERR;
312 return GNUNET_NO; 311 return GNUNET_NO;
313 } 312 }
314 hp = gethostbyname2 (hostname, domain); 313 hp = gethostbyname2 (hostname, domain);
315 if (hp == NULL) 314 if (hp == NULL)
316 { 315 {
317 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 316 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
318 _("Could not find IP of host `%s': %s\n"), 317 _("Could not find IP of host `%s': %s\n"),
319 hostname, hstrerror (h_errno)); 318 hostname, hstrerror (h_errno));
320 return GNUNET_SYSERR; 319 return GNUNET_SYSERR;
321 } 320 }
322 GNUNET_assert (hp->h_addrtype == domain); 321 GNUNET_assert (hp->h_addrtype == domain);
323 if (domain == AF_INET) 322 if (domain == AF_INET)
324 { 323 {
325 GNUNET_assert (hp->h_length == sizeof (struct in_addr)); 324 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
326 memset (&a4, 0, sizeof (a4)); 325 memset (&a4, 0, sizeof (a4));
327 a4.sin_family = AF_INET; 326 a4.sin_family = AF_INET;
328#if HAVE_SOCKADDR_IN_SIN_LEN 327#if HAVE_SOCKADDR_IN_SIN_LEN
329 a4.sin_len = (u_char) sizeof (struct sockaddr_in); 328 a4.sin_len = (u_char) sizeof (struct sockaddr_in);
330#endif 329#endif
331 memcpy (&a4.sin_addr, hp->h_addr_list[0], hp->h_length); 330 memcpy (&a4.sin_addr, hp->h_addr_list[0], hp->h_length);
332 GNUNET_SERVER_transmit_context_append_data (tc, 331 GNUNET_SERVER_transmit_context_append_data (tc,
333 &a4, 332 &a4,
334 sizeof (a4), 333 sizeof (a4),
335 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 334 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
336 } 335 }
337 else 336 else
338 { 337 {
339 GNUNET_assert (hp->h_length == sizeof (struct in6_addr)); 338 GNUNET_assert (hp->h_length == sizeof (struct in6_addr));
340 memset (&a6, 0, sizeof (a6)); 339 memset (&a6, 0, sizeof (a6));
341 a6.sin6_family = AF_INET6; 340 a6.sin6_family = AF_INET6;
342#if HAVE_SOCKADDR_IN_SIN_LEN 341#if HAVE_SOCKADDR_IN_SIN_LEN
343 a6.sin6_len = (u_char) sizeof (struct sockaddr_in6); 342 a6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
344#endif 343#endif
345 memcpy (&a6.sin6_addr, hp->h_addr_list[0], hp->h_length); 344 memcpy (&a6.sin6_addr, hp->h_addr_list[0], hp->h_length);
346 GNUNET_SERVER_transmit_context_append_data (tc, 345 GNUNET_SERVER_transmit_context_append_data (tc,
347 &a6, 346 &a6,
348 sizeof (a6), 347 sizeof (a6),
349 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 348 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
350 } 349 }
351 return GNUNET_OK; 350 return GNUNET_OK;
352} 351}
353#endif 352#endif
@@ -362,17 +361,17 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
362 361
363 hp = GETHOSTBYNAME (hostname); 362 hp = GETHOSTBYNAME (hostname);
364 if (hp == NULL) 363 if (hp == NULL)
365 { 364 {
366 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 365 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
367 _("Could not find IP of host `%s': %s\n"), 366 _("Could not find IP of host `%s': %s\n"),
368 hostname, hstrerror (h_errno)); 367 hostname, hstrerror (h_errno));
369 return GNUNET_SYSERR; 368 return GNUNET_SYSERR;
370 } 369 }
371 if (hp->h_addrtype != AF_INET) 370 if (hp->h_addrtype != AF_INET)
372 { 371 {
373 GNUNET_break (0); 372 GNUNET_break (0);
374 return GNUNET_SYSERR; 373 return GNUNET_SYSERR;
375 } 374 }
376 GNUNET_assert (hp->h_length == sizeof (struct in_addr)); 375 GNUNET_assert (hp->h_length == sizeof (struct in_addr));
377 memset (&addr, 0, sizeof (addr)); 376 memset (&addr, 0, sizeof (addr));
378 addr.sin_family = AF_INET; 377 addr.sin_family = AF_INET;
@@ -381,9 +380,9 @@ gethostbyname_resolve (struct GNUNET_SERVER_TransmitContext *tc,
381#endif 380#endif
382 memcpy (&addr.sin_addr, hp->h_addr_list[0], hp->h_length); 381 memcpy (&addr.sin_addr, hp->h_addr_list[0], hp->h_length);
383 GNUNET_SERVER_transmit_context_append_data (tc, 382 GNUNET_SERVER_transmit_context_append_data (tc,
384 &addr, 383 &addr,
385 sizeof (addr), 384 sizeof (addr),
386 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 385 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
387 return GNUNET_OK; 386 return GNUNET_OK;
388} 387}
389#endif 388#endif
@@ -418,7 +417,7 @@ get_ip_from_hostname (struct GNUNET_SERVER_Client *client,
418 gethostbyname_resolve (tc, hostname); 417 gethostbyname_resolve (tc, hostname);
419#endif 418#endif
420 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, 419 GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0,
421 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE); 420 GNUNET_MESSAGE_TYPE_RESOLVER_RESPONSE);
422 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); 421 GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
423} 422}
424 423
@@ -445,79 +444,78 @@ handle_get (void *cls,
445 444
446 msize = ntohs (message->size); 445 msize = ntohs (message->size);
447 if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage)) 446 if (msize < sizeof (struct GNUNET_RESOLVER_GetMessage))
448 { 447 {
449 GNUNET_break (0); 448 GNUNET_break (0);
450 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 449 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
451 return; 450 return;
452 } 451 }
453 msg = (const struct GNUNET_RESOLVER_GetMessage *) message; 452 msg = (const struct GNUNET_RESOLVER_GetMessage *) message;
454 size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage); 453 size = msize - sizeof (struct GNUNET_RESOLVER_GetMessage);
455 direction = ntohl (msg->direction); 454 direction = ntohl (msg->direction);
456 domain = ntohl (msg->domain); 455 domain = ntohl (msg->domain);
457 if (direction == GNUNET_NO) 456 if (direction == GNUNET_NO)
457 {
458 /* IP from hostname */
459 hostname = (const char *) &msg[1];
460 if (hostname[size - 1] != '\0')
458 { 461 {
459 /* IP from hostname */ 462 GNUNET_break (0);
460 hostname = (const char *) &msg[1]; 463 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
461 if (hostname[size - 1] != '\0') 464 return;
462 { 465 }
463 GNUNET_break (0);
464 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
465 return;
466 }
467#if DEBUG_RESOLVER 466#if DEBUG_RESOLVER
468 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
469 _("Resolver asked to look up `%s'.\n"), hostname); 468 _("Resolver asked to look up `%s'.\n"), hostname);
470#endif 469#endif
471 get_ip_from_hostname (client, hostname, domain); 470 get_ip_from_hostname (client, hostname, domain);
472 } 471 }
473 else 472 else
474 { 473 {
475#if DEBUG_RESOLVER 474#if DEBUG_RESOLVER
476 char buf[INET6_ADDRSTRLEN]; 475 char buf[INET6_ADDRSTRLEN];
477#endif
478 if (size < sizeof (struct sockaddr))
479 {
480 GNUNET_break (0);
481 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
482 return;
483 }
484 sa = (const struct sockaddr*) &msg[1];
485 switch (sa->sa_family)
486 {
487 case AF_INET:
488 if (size != sizeof (struct sockaddr_in))
489 {
490 GNUNET_break (0);
491 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
492 return;
493 }
494#if DEBUG_RESOLVER
495 inet_ntop (AF_INET, sa, buf, size);
496#endif 476#endif
497 break; 477 if (size < sizeof (struct sockaddr))
498 case AF_INET6: 478 {
499 if (size != sizeof (struct sockaddr_in6)) 479 GNUNET_break (0);
500 { 480 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
501 GNUNET_break (0); 481 return;
502 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 482 }
503 return; 483 sa = (const struct sockaddr *) &msg[1];
504 } 484 switch (sa->sa_family)
505#if DEBUG_RESOLVER 485 {
506 inet_ntop (AF_INET6, sa, buf, size); 486 case AF_INET:
487 if (size != sizeof (struct sockaddr_in))
488 {
489 GNUNET_break (0);
490 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
491 return;
492 }
493#if DEBUG_RESOLVER
494 inet_ntop (AF_INET, sa, buf, size);
507#endif 495#endif
508 break; 496 break;
509 default: 497 case AF_INET6:
510 GNUNET_break (0); 498 if (size != sizeof (struct sockaddr_in6))
511 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 499 {
512 return; 500 GNUNET_break (0);
513 } 501 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
514#if DEBUG_RESOLVER 502 return;
515 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 503 }
516 _("Resolver asked to look up IP address `%s'.\n"), 504#if DEBUG_RESOLVER
517 buf); 505 inet_ntop (AF_INET6, sa, buf, size);
518#endif 506#endif
519 get_ip_as_string (client, sa, size); 507 break;
508 default:
509 GNUNET_break (0);
510 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
511 return;
520 } 512 }
513#if DEBUG_RESOLVER
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 _("Resolver asked to look up IP address `%s'.\n"), buf);
516#endif
517 get_ip_as_string (client, sa, size);
518 }
521} 519}
522 520
523 521
@@ -561,13 +559,13 @@ main (int argc, char *const *argv)
561 &run, NULL)) ? 0 : 1; 559 &run, NULL)) ? 0 : 1;
562 560
563 while (head != NULL) 561 while (head != NULL)
564 { 562 {
565 pos = head->next; 563 pos = head->next;
566 GNUNET_free_non_null (head->addr); 564 GNUNET_free_non_null (head->addr);
567 GNUNET_free (head->sa); 565 GNUNET_free (head->sa);
568 GNUNET_free (head); 566 GNUNET_free (head);
569 head = pos; 567 head = pos;
570 } 568 }
571 return ret; 569 return ret;
572} 570}
573 571