diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-05-02 11:48:52 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-05-02 11:48:52 +0000 |
commit | f4b1f639e8799d29e823a7cd563a97d314d4f471 (patch) | |
tree | be4854b5c5591ea04b2de4032e554dc392f8d0e0 /src/transport/plugin_transport_udp.c | |
parent | f1df9f057d50cd695ee3b86538f27306ea74369f (diff) | |
download | gnunet-f4b1f639e8799d29e823a7cd563a97d314d4f471.tar.gz gnunet-f4b1f639e8799d29e823a7cd563a97d314d4f471.zip |
fixing major issue with how IP addresses go over the network (previously ill-defined) -- thanks amatus
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 325 |
1 files changed, 267 insertions, 58 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 3e59f89dc..c7be2e18e 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -71,13 +71,64 @@ struct UDPMessage | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | 73 | ||
74 | /** | ||
75 | * Network format for IPv4 addresses. | ||
76 | */ | ||
77 | struct IPv4UdpAddress | ||
78 | { | ||
79 | /** | ||
80 | * IPv4 address, in network byte order. | ||
81 | */ | ||
82 | uint32_t ipv4_addr; | ||
83 | |||
84 | /** | ||
85 | * Port number, in network byte order. | ||
86 | */ | ||
87 | uint16_t u_port; | ||
88 | |||
89 | }; | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Network format for IPv6 addresses. | ||
94 | */ | ||
95 | struct IPv6UdpAddress | ||
96 | { | ||
97 | /** | ||
98 | * IPv6 address. | ||
99 | */ | ||
100 | unsigned char ipv6_addr[16]; | ||
101 | |||
102 | /** | ||
103 | * Port number, in network byte order. | ||
104 | */ | ||
105 | uint16_t u6_port; | ||
106 | |||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
111 | * | ||
112 | */ | ||
74 | struct PrettyPrinterContext | 113 | struct PrettyPrinterContext |
75 | { | 114 | { |
115 | /** | ||
116 | * | ||
117 | */ | ||
76 | GNUNET_TRANSPORT_AddressStringCallback asc; | 118 | GNUNET_TRANSPORT_AddressStringCallback asc; |
119 | |||
120 | /** | ||
121 | * Closure for 'asc'. | ||
122 | */ | ||
77 | void *asc_cls; | 123 | void *asc_cls; |
124 | |||
125 | /** | ||
126 | * | ||
127 | */ | ||
78 | uint16_t port; | 128 | uint16_t port; |
79 | }; | 129 | }; |
80 | 130 | ||
131 | |||
81 | /** | 132 | /** |
82 | * Encapsulation of all of the state of the plugin. | 133 | * Encapsulation of all of the state of the plugin. |
83 | */ | 134 | */ |
@@ -134,7 +185,7 @@ struct Plugin | |||
134 | /* *********** globals ************* */ | 185 | /* *********** globals ************* */ |
135 | 186 | ||
136 | /** | 187 | /** |
137 | * the socket that we transmit all data with | 188 | * The socket that we transmit all data with |
138 | */ | 189 | */ |
139 | static struct GNUNET_NETWORK_Handle *udp_sock; | 190 | static struct GNUNET_NETWORK_Handle *udp_sock; |
140 | 191 | ||
@@ -146,7 +197,8 @@ static struct GNUNET_NETWORK_Handle *udp_sock; | |||
146 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed | 197 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed |
147 | */ | 198 | */ |
148 | void | 199 | void |
149 | udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 200 | udp_disconnect (void *cls, |
201 | const struct GNUNET_PeerIdentity *target) | ||
150 | { | 202 | { |
151 | /* nothing to do, UDP is stateless */ | 203 | /* nothing to do, UDP is stateless */ |
152 | } | 204 | } |
@@ -154,6 +206,8 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | |||
154 | /** | 206 | /** |
155 | * Shutdown the server process (stop receiving inbound traffic). Maybe | 207 | * Shutdown the server process (stop receiving inbound traffic). Maybe |
156 | * restarted later! | 208 | * restarted later! |
209 | * | ||
210 | * @param cls closure, the 'struct Plugin*' | ||
157 | */ | 211 | */ |
158 | static int | 212 | static int |
159 | udp_transport_server_stop (void *cls) | 213 | udp_transport_server_stop (void *cls) |
@@ -178,7 +232,7 @@ udp_transport_server_stop (void *cls) | |||
178 | * Function that can be used by the transport service to transmit | 232 | * Function that can be used by the transport service to transmit |
179 | * a message using the plugin. | 233 | * a message using the plugin. |
180 | * | 234 | * |
181 | * @param cls closure | 235 | * @param cls closure, the 'struct Plugin*' |
182 | * @param target who should receive this message (ignored by UDP) | 236 | * @param target who should receive this message (ignored by UDP) |
183 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together | 237 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together |
184 | * @param msgbuf_size the size of the msgbuf to send | 238 | * @param msgbuf_size the size of the msgbuf to send |
@@ -217,6 +271,13 @@ udp_plugin_send (void *cls, | |||
217 | struct UDPMessage *message; | 271 | struct UDPMessage *message; |
218 | int ssize; | 272 | int ssize; |
219 | ssize_t sent; | 273 | ssize_t sent; |
274 | int af; | ||
275 | const void *sb; | ||
276 | size_t sbs; | ||
277 | struct sockaddr_in a4; | ||
278 | struct sockaddr_in6 a6; | ||
279 | const struct IPv4UdpAddress *t4; | ||
280 | const struct IPv6UdpAddress *t6; | ||
220 | 281 | ||
221 | GNUNET_assert (NULL == session); | 282 | GNUNET_assert (NULL == session); |
222 | GNUNET_assert(udp_sock != NULL); | 283 | GNUNET_assert(udp_sock != NULL); |
@@ -231,13 +292,45 @@ udp_plugin_send (void *cls, | |||
231 | if (force_address == GNUNET_SYSERR) | 292 | if (force_address == GNUNET_SYSERR) |
232 | return -1; /* never reliable */ | 293 | return -1; /* never reliable */ |
233 | 294 | ||
295 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
296 | { | ||
297 | t6 = addr; | ||
298 | af = AF_INET6; | ||
299 | memset (&a6, 0, sizeof (a6)); | ||
300 | a6.sin6_family = AF_INET6; | ||
301 | a6.sin6_port = t6->u6_port; | ||
302 | memcpy (a6.sin6_addr.s6_addr, | ||
303 | t6->ipv6_addr, | ||
304 | 16); | ||
305 | sb = &a6; | ||
306 | sbs = sizeof (a6); | ||
307 | } | ||
308 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
309 | { | ||
310 | t4 = addr; | ||
311 | af = AF_INET; | ||
312 | memset (&a4, 0, sizeof (a4)); | ||
313 | a4.sin_family = AF_INET; | ||
314 | a4.sin_port = t4->u_port; | ||
315 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
316 | sb = &a4; | ||
317 | sbs = sizeof (a4); | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | GNUNET_break_op (0); | ||
322 | return -1; | ||
323 | } | ||
324 | |||
234 | /* Build the message to be sent */ | 325 | /* Build the message to be sent */ |
235 | message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size); | 326 | message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size); |
236 | ssize = sizeof (struct UDPMessage) + msgbuf_size; | 327 | ssize = sizeof (struct UDPMessage) + msgbuf_size; |
237 | 328 | ||
238 | #if DEBUG_UDP | 329 | #if DEBUG_UDP |
239 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 330 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", |
240 | ("In udp_send, ssize is %d, sending message to %s\n"), ssize, GNUNET_a2s((const struct sockaddr *)addr, addrlen)); | 331 | "In udp_send, ssize is %d, sending message to `%s'\n", |
332 | ssize, | ||
333 | GNUNET_a2s(sb, sbs)); | ||
241 | #endif | 334 | #endif |
242 | message->header.size = htons (ssize); | 335 | message->header.size = htons (ssize); |
243 | message->header.type = htons (0); | 336 | message->header.type = htons (0); |
@@ -246,8 +339,7 @@ udp_plugin_send (void *cls, | |||
246 | memcpy (&message[1], msgbuf, msgbuf_size); | 339 | memcpy (&message[1], msgbuf, msgbuf_size); |
247 | sent = | 340 | sent = |
248 | GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize, | 341 | GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize, |
249 | addr, | 342 | sb, sbs); |
250 | addrlen); | ||
251 | if ( (cont != NULL) && | 343 | if ( (cont != NULL) && |
252 | (sent != -1) ) | 344 | (sent != -1) ) |
253 | cont (cont_cls, target, GNUNET_OK); | 345 | cont (cont_cls, target, GNUNET_OK); |
@@ -259,6 +351,13 @@ udp_plugin_send (void *cls, | |||
259 | /** | 351 | /** |
260 | * Add the IP of our network interface to the list of | 352 | * Add the IP of our network interface to the list of |
261 | * our external IP addresses. | 353 | * our external IP addresses. |
354 | * | ||
355 | * @param cls closure (the 'struct Plugin*') | ||
356 | * @param name name of the interface (can be NULL for unknown) | ||
357 | * @param isDefault is this presumably the default interface | ||
358 | * @param addr address of this interface (can be NULL for unknown or unassigned) | ||
359 | * @param addrlen length of the address | ||
360 | * @return GNUNET_OK to continue iterating | ||
262 | */ | 361 | */ |
263 | static int | 362 | static int |
264 | process_interfaces (void *cls, | 363 | process_interfaces (void *cls, |
@@ -268,29 +367,42 @@ process_interfaces (void *cls, | |||
268 | { | 367 | { |
269 | struct Plugin *plugin = cls; | 368 | struct Plugin *plugin = cls; |
270 | int af; | 369 | int af; |
271 | struct sockaddr_in *v4; | 370 | struct IPv4UdpAddress t4; |
272 | struct sockaddr_in6 *v6; | 371 | struct IPv6UdpAddress t6; |
372 | void *arg; | ||
373 | uint16_t args; | ||
273 | 374 | ||
274 | af = addr->sa_family; | 375 | af = addr->sa_family; |
275 | if (af == AF_INET) | 376 | if (af == AF_INET) |
276 | { | 377 | { |
277 | v4 = (struct sockaddr_in *) addr; | 378 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
278 | v4->sin_port = htons (plugin->adv_port); | 379 | t4.u_port = htons (plugin->adv_port); |
380 | arg = &t4; | ||
381 | args = sizeof (t4); | ||
382 | } | ||
383 | else if (af == AF_INET6) | ||
384 | { | ||
385 | memcpy (t6.ipv6_addr, | ||
386 | ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, | ||
387 | 16); | ||
388 | t6.u6_port = htons (plugin->adv_port); | ||
389 | arg = &t6; | ||
390 | args = sizeof (t6); | ||
279 | } | 391 | } |
280 | else | 392 | else |
281 | { | 393 | { |
282 | GNUNET_assert (af == AF_INET6); | 394 | GNUNET_break (0); |
283 | v6 = (struct sockaddr_in6 *) addr; | 395 | return GNUNET_OK; |
284 | v6->sin6_port = htons (plugin->adv_port); | ||
285 | } | 396 | } |
286 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | 397 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | |
287 | GNUNET_ERROR_TYPE_BULK, | 398 | GNUNET_ERROR_TYPE_BULK, |
288 | "udp", _("Found address `%s' (%s)\n"), | 399 | "udp", |
289 | GNUNET_a2s (addr, addrlen), name); | 400 | _("Found address `%s' (%s)\n"), |
401 | GNUNET_a2s (addr, addrlen), | ||
402 | name); | ||
290 | plugin->env->notify_address (plugin->env->cls, | 403 | plugin->env->notify_address (plugin->env->cls, |
291 | "udp", | 404 | "udp", |
292 | addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); | 405 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); |
293 | |||
294 | return GNUNET_OK; | 406 | return GNUNET_OK; |
295 | } | 407 | } |
296 | 408 | ||
@@ -346,6 +458,12 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
346 | int tsize; | 458 | int tsize; |
347 | char *msgbuf; | 459 | char *msgbuf; |
348 | const struct GNUNET_MessageHeader *currhdr; | 460 | const struct GNUNET_MessageHeader *currhdr; |
461 | struct IPv4UdpAddress t4; | ||
462 | struct IPv6UdpAddress t6; | ||
463 | const struct sockaddr_in *s4; | ||
464 | const struct sockaddr_in6 *s6; | ||
465 | const void *ca; | ||
466 | size_t calen; | ||
349 | 467 | ||
350 | #if DEBUG_UDP | 468 | #if DEBUG_UDP |
351 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 469 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ |
@@ -411,6 +529,31 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
411 | ("offset is %d, tsize is %d (UDPMessage size is %d)\n"), | 529 | ("offset is %d, tsize is %d (UDPMessage size is %d)\n"), |
412 | offset, tsize, sizeof(struct UDPMessage)); | 530 | offset, tsize, sizeof(struct UDPMessage)); |
413 | #endif | 531 | #endif |
532 | |||
533 | if (fromlen == sizeof (struct sockaddr_in)) | ||
534 | { | ||
535 | s4 = (const struct sockaddr_in*) &addr; | ||
536 | t4.u_port = s4->sin_port; | ||
537 | t4.ipv4_addr = s4->sin_addr.s_addr; | ||
538 | ca = &t4; | ||
539 | calen = sizeof (struct IPv4UdpAddress); | ||
540 | } | ||
541 | else if (fromlen == sizeof (struct sockaddr_in6)) | ||
542 | { | ||
543 | s6 = (const struct sockaddr_in6*) &addr; | ||
544 | t6.u6_port = s6->sin6_port; | ||
545 | memcpy (t6.ipv6_addr, | ||
546 | s6->sin6_addr.s6_addr, | ||
547 | 16); | ||
548 | ca = &t6; | ||
549 | calen = sizeof (struct IPv6UdpAddress); | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | GNUNET_break (0); | ||
554 | ca = NULL; | ||
555 | calen = 0; | ||
556 | } | ||
414 | while (offset < tsize) | 557 | while (offset < tsize) |
415 | { | 558 | { |
416 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; | 559 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; |
@@ -421,7 +564,7 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
421 | #endif | 564 | #endif |
422 | plugin->env->receive (plugin->env->cls, | 565 | plugin->env->receive (plugin->env->cls, |
423 | sender, currhdr, UDP_DIRECT_DISTANCE, | 566 | sender, currhdr, UDP_DIRECT_DISTANCE, |
424 | NULL, (const char *)&addr, fromlen); | 567 | NULL, ca, calen); |
425 | offset += ntohs(currhdr->size); | 568 | offset += ntohs(currhdr->size); |
426 | #if DEBUG_UDP | 569 | #if DEBUG_UDP |
427 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 570 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ |
@@ -446,6 +589,7 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
446 | /** | 589 | /** |
447 | * Create a UDP socket. If possible, use IPv6, otherwise | 590 | * Create a UDP socket. If possible, use IPv6, otherwise |
448 | * try IPv4. | 591 | * try IPv4. |
592 | * @param cls closure, the 'struct Plugin*' | ||
449 | */ | 593 | */ |
450 | static struct GNUNET_NETWORK_Handle * | 594 | static struct GNUNET_NETWORK_Handle * |
451 | udp_transport_server_start (void *cls) | 595 | udp_transport_server_start (void *cls) |
@@ -550,43 +694,30 @@ check_port (struct Plugin *plugin, uint16_t in_port) | |||
550 | * @param addrlen length of addr | 694 | * @param addrlen length of addr |
551 | * @return GNUNET_OK if this is a plausible address for this peer | 695 | * @return GNUNET_OK if this is a plausible address for this peer |
552 | * and transport, GNUNET_SYSERR if not | 696 | * and transport, GNUNET_SYSERR if not |
553 | * | ||
554 | * TODO: perhaps make everything work with sockaddr_storage, it may | ||
555 | * be a cleaner way to handle addresses in UDP | ||
556 | */ | 697 | */ |
557 | static int | 698 | static int |
558 | udp_check_address (void *cls, void *addr, size_t addrlen) | 699 | udp_check_address (void *cls, void *addr, size_t addrlen) |
559 | { | 700 | { |
560 | struct Plugin *plugin = cls; | 701 | struct Plugin *plugin = cls; |
561 | char buf[sizeof (struct sockaddr_in6)]; | 702 | struct IPv4UdpAddress *v4; |
562 | 703 | struct IPv6UdpAddress *v6; | |
563 | struct sockaddr_in *v4; | ||
564 | struct sockaddr_in6 *v6; | ||
565 | 704 | ||
566 | if ((addrlen != sizeof (struct sockaddr_in)) && | 705 | if ((addrlen != sizeof (struct IPv4UdpAddress)) && |
567 | (addrlen != sizeof (struct sockaddr_in6))) | 706 | (addrlen != sizeof (struct IPv6UdpAddress))) |
568 | { | 707 | { |
569 | GNUNET_break_op (0); | 708 | GNUNET_break_op (0); |
570 | return GNUNET_SYSERR; | 709 | return GNUNET_SYSERR; |
571 | } | 710 | } |
572 | memcpy (buf, addr, sizeof (struct sockaddr_in6)); | 711 | if (addrlen == sizeof (struct IPv4UdpAddress)) |
573 | if (addrlen == sizeof (struct sockaddr_in)) | ||
574 | { | 712 | { |
575 | v4 = (struct sockaddr_in *) buf; | 713 | v4 = (struct IPv4UdpAddress *) addr; |
576 | v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port))); | 714 | v4->u_port = htons (check_port (plugin, ntohs (v4->u_port))); |
577 | } | 715 | } |
578 | else | 716 | else |
579 | { | 717 | { |
580 | v6 = (struct sockaddr_in6 *) buf; | 718 | v6 = (struct IPv6UdpAddress *) addr; |
581 | v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port))); | 719 | v6->u6_port = htons (check_port (plugin, ntohs (v6->u6_port))); |
582 | } | 720 | } |
583 | #if DEBUG_UDP | ||
584 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
585 | "tcp", | ||
586 | "Informing transport service about my address `%s'.\n", | ||
587 | GNUNET_a2s (addr, addrlen)); | ||
588 | #endif | ||
589 | return GNUNET_OK; | ||
590 | return GNUNET_OK; | 721 | return GNUNET_OK; |
591 | } | 722 | } |
592 | 723 | ||
@@ -637,12 +768,43 @@ udp_plugin_address_pretty_printer (void *cls, | |||
637 | void *asc_cls) | 768 | void *asc_cls) |
638 | { | 769 | { |
639 | struct Plugin *plugin = cls; | 770 | struct Plugin *plugin = cls; |
640 | const struct sockaddr_in *v4; | ||
641 | const struct sockaddr_in6 *v6; | ||
642 | struct PrettyPrinterContext *ppc; | 771 | struct PrettyPrinterContext *ppc; |
772 | const void *sb; | ||
773 | struct sockaddr_in a4; | ||
774 | struct sockaddr_in6 a6; | ||
775 | const struct IPv4UdpAddress *t4; | ||
776 | const struct IPv6UdpAddress *t6; | ||
777 | int af; | ||
778 | size_t sbs; | ||
779 | uint16_t port; | ||
643 | 780 | ||
644 | if ((addrlen != sizeof (struct sockaddr_in)) && | 781 | if (addrlen == sizeof (struct IPv6UdpAddress)) |
645 | (addrlen != sizeof (struct sockaddr_in6))) | 782 | { |
783 | t6 = addr; | ||
784 | af = AF_INET6; | ||
785 | memset (&a6, 0, sizeof (a6)); | ||
786 | a6.sin6_family = AF_INET6; | ||
787 | a6.sin6_port = t6->u6_port; | ||
788 | port = ntohs (t6->u6_port); | ||
789 | memcpy (a6.sin6_addr.s6_addr, | ||
790 | t6->ipv6_addr, | ||
791 | 16); | ||
792 | sb = &a6; | ||
793 | sbs = sizeof (a6); | ||
794 | } | ||
795 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
796 | { | ||
797 | t4 = addr; | ||
798 | af = AF_INET; | ||
799 | memset (&a4, 0, sizeof (a4)); | ||
800 | a4.sin_family = AF_INET; | ||
801 | a4.sin_port = t4->u_port; | ||
802 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
803 | port = ntohs (t4->u_port); | ||
804 | sb = &a4; | ||
805 | sbs = sizeof (a4); | ||
806 | } | ||
807 | else | ||
646 | { | 808 | { |
647 | /* invalid address */ | 809 | /* invalid address */ |
648 | GNUNET_break_op (0); | 810 | GNUNET_break_op (0); |
@@ -652,28 +814,75 @@ udp_plugin_address_pretty_printer (void *cls, | |||
652 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); | 814 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); |
653 | ppc->asc = asc; | 815 | ppc->asc = asc; |
654 | ppc->asc_cls = asc_cls; | 816 | ppc->asc_cls = asc_cls; |
655 | if (addrlen == sizeof (struct sockaddr_in)) | 817 | ppc->port = port; |
818 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, | ||
819 | plugin->env->cfg, | ||
820 | sb, | ||
821 | sbs, | ||
822 | !numeric, timeout, &append_port, ppc); | ||
823 | } | ||
824 | |||
825 | |||
826 | |||
827 | /** | ||
828 | * Function called for a quick conversion of the binary address to | ||
829 | * a numeric address. Note that the caller must not free the | ||
830 | * address and that the next call to this function is allowed | ||
831 | * to override the address again. | ||
832 | * | ||
833 | * @param cls closure | ||
834 | * @param addr binary address | ||
835 | * @param addr_len length of the address | ||
836 | * @return string representing the same address | ||
837 | */ | ||
838 | static const char* | ||
839 | udp_address_to_string (void *cls, | ||
840 | const void *addr, | ||
841 | size_t addrlen) | ||
842 | { | ||
843 | static char buf[INET6_ADDRSTRLEN]; | ||
844 | const void *sb; | ||
845 | struct sockaddr_in a4; | ||
846 | struct sockaddr_in6 a6; | ||
847 | const struct IPv4UdpAddress *t4; | ||
848 | const struct IPv6UdpAddress *t6; | ||
849 | int af; | ||
850 | |||
851 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
656 | { | 852 | { |
657 | v4 = (const struct sockaddr_in *) addr; | 853 | t6 = addr; |
658 | ppc->port = ntohs (v4->sin_port); | 854 | af = AF_INET6; |
855 | memset (&a6, 0, sizeof (a6)); | ||
856 | a6.sin6_family = AF_INET6; | ||
857 | a6.sin6_port = t6->u6_port; | ||
858 | memcpy (a6.sin6_addr.s6_addr, | ||
859 | t6->ipv6_addr, | ||
860 | 16); | ||
861 | sb = &a6; | ||
659 | } | 862 | } |
660 | else | 863 | else if (addrlen == sizeof (struct IPv4UdpAddress)) |
661 | { | 864 | { |
662 | v6 = (const struct sockaddr_in6 *) addr; | 865 | t4 = addr; |
663 | ppc->port = ntohs (v6->sin6_port); | 866 | af = AF_INET; |
664 | 867 | memset (&a4, 0, sizeof (a4)); | |
868 | a4.sin_family = AF_INET; | ||
869 | a4.sin_port = t4->u_port; | ||
870 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
871 | sb = &a4; | ||
665 | } | 872 | } |
666 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, | 873 | else |
667 | plugin->env->cfg, | 874 | return NULL; |
668 | addr, | 875 | |
669 | addrlen, | 876 | return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN); |
670 | !numeric, timeout, &append_port, ppc); | ||
671 | } | 877 | } |
672 | 878 | ||
673 | 879 | ||
674 | /** | 880 | /** |
675 | * The exported method. Makes the core api available via a global and | 881 | * The exported method. Makes the core api available via a global and |
676 | * returns the udp transport API. | 882 | * returns the udp transport API. |
883 | * | ||
884 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | ||
885 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error | ||
677 | */ | 886 | */ |
678 | void * | 887 | void * |
679 | libgnunet_plugin_transport_udp_init (void *cls) | 888 | libgnunet_plugin_transport_udp_init (void *cls) |
@@ -737,7 +946,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
737 | api->disconnect = &udp_disconnect; | 946 | api->disconnect = &udp_disconnect; |
738 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; | 947 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; |
739 | api->check_address = &udp_check_address; | 948 | api->check_address = &udp_check_address; |
740 | 949 | api->address_to_string = &udp_address_to_string; | |
741 | plugin->service = service; | 950 | plugin->service = service; |
742 | 951 | ||
743 | /* FIXME: do the two calls below periodically again and | 952 | /* FIXME: do the two calls below periodically again and |