diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-07-18 20:17:35 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-07-18 20:17:35 +0000 |
commit | ed5ede797347e5decdfc56085815dcdf2843609d (patch) | |
tree | 7910588558a39de534026395274779cc793ea203 | |
parent | 2eba86ef5f0496f32b99b2bcb668a3f7d0acffbc (diff) | |
download | gnunet-ed5ede797347e5decdfc56085815dcdf2843609d.tar.gz gnunet-ed5ede797347e5decdfc56085815dcdf2843609d.zip |
fixing UDP bug
-rw-r--r-- | src/transport/gnunet-service-transport.c | 64 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 4 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 438 | ||||
-rw-r--r-- | src/transport/test_transport_api.c | 22 | ||||
-rw-r--r-- | src/transport/test_transport_api_udp_peer1.conf | 2 | ||||
-rw-r--r-- | src/transport/test_transport_api_udp_peer2.conf | 2 |
6 files changed, 328 insertions, 204 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 12db541ac..0d33ac5ca 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -43,8 +43,6 @@ | |||
43 | 43 | ||
44 | #define DEBUG_PING_PONG GNUNET_NO | 44 | #define DEBUG_PING_PONG GNUNET_NO |
45 | 45 | ||
46 | #define SIGN_USELESS GNUNET_NO | ||
47 | |||
48 | #define DEBUG_TRANSPORT_HELLO GNUNET_YES | 46 | #define DEBUG_TRANSPORT_HELLO GNUNET_YES |
49 | 47 | ||
50 | /** | 48 | /** |
@@ -2011,6 +2009,48 @@ remove_session_validations (void *cls, | |||
2011 | 2009 | ||
2012 | 2010 | ||
2013 | /** | 2011 | /** |
2012 | * We've been disconnected from the other peer (for some | ||
2013 | * connection-oriented transport). Either quickly | ||
2014 | * re-establish the connection or signal the disconnect | ||
2015 | * to the CORE. | ||
2016 | * | ||
2017 | * @param p overall plugin context | ||
2018 | * @param nl neighbour that was disconnected | ||
2019 | */ | ||
2020 | static void | ||
2021 | try_fast_reconnect (struct TransportPlugin *p, | ||
2022 | struct NeighbourList *nl) | ||
2023 | { | ||
2024 | /* FIXME-MW: fast reconnect / transport switching not implemented... */ | ||
2025 | /* Note: the idea here is to hide problems with transports (or | ||
2026 | switching between plugins) from the core to eliminate the need to | ||
2027 | re-negotiate session keys and the like; OTOH, we should tell core | ||
2028 | quickly (much faster than timeout) `if a connection was lost and | ||
2029 | could not be re-established (i.e. other peer went down or is | ||
2030 | unable / refuses to communicate); | ||
2031 | |||
2032 | So we should consider: | ||
2033 | 1) ideally: our own willingness / need to connect | ||
2034 | 2) prior failures to connect to this peer (by plugin) | ||
2035 | 3) ideally: reaons why other peer terminated (as far as knowable) | ||
2036 | |||
2037 | Most importantly, it must be POSSIBLE for another peer to terminate | ||
2038 | a connection for a while (without us instantly re-establishing it). | ||
2039 | Similarly, if another peer is gone we should quickly notify CORE. | ||
2040 | OTOH, if there was a minor glitch (i.e. crash of gnunet-service-transport | ||
2041 | on the other end), we should reconnect in such a way that BOTH CORE | ||
2042 | services never even notice. | ||
2043 | Furthermore, the same mechanism (or small variation) could be used | ||
2044 | to switch to a better-performing plugin (ATS). | ||
2045 | |||
2046 | Finally, this needs to be tested throughly... */ | ||
2047 | |||
2048 | /* No reconnect, signal disconnect instead! */ | ||
2049 | disconnect_neighbour (nl, GNUNET_NO); | ||
2050 | } | ||
2051 | |||
2052 | |||
2053 | /** | ||
2014 | * Function that will be called whenever the plugin internally | 2054 | * Function that will be called whenever the plugin internally |
2015 | * cleans up a session pointer and hence the service needs to | 2055 | * cleans up a session pointer and hence the service needs to |
2016 | * discard all of those sessions as well. Plugins that do not | 2056 | * discard all of those sessions as well. Plugins that do not |
@@ -2037,7 +2077,7 @@ plugin_env_session_end (void *cls, | |||
2037 | session); | 2077 | session); |
2038 | nl = find_neighbour (peer); | 2078 | nl = find_neighbour (peer); |
2039 | if (nl == NULL) | 2079 | if (nl == NULL) |
2040 | return; | 2080 | return; /* was never marked as connected */ |
2041 | rl = nl->plugins; | 2081 | rl = nl->plugins; |
2042 | while (rl != NULL) | 2082 | while (rl != NULL) |
2043 | { | 2083 | { |
@@ -2046,7 +2086,7 @@ plugin_env_session_end (void *cls, | |||
2046 | rl = rl->next; | 2086 | rl = rl->next; |
2047 | } | 2087 | } |
2048 | if (rl == NULL) | 2088 | if (rl == NULL) |
2049 | return; | 2089 | return; /* was never marked as connected */ |
2050 | prev = NULL; | 2090 | prev = NULL; |
2051 | pos = rl->addresses; | 2091 | pos = rl->addresses; |
2052 | while ( (pos != NULL) && | 2092 | while ( (pos != NULL) && |
@@ -2056,10 +2096,15 @@ plugin_env_session_end (void *cls, | |||
2056 | pos = pos->next; | 2096 | pos = pos->next; |
2057 | } | 2097 | } |
2058 | if (pos == NULL) | 2098 | if (pos == NULL) |
2059 | return; | 2099 | return; /* was never marked as connected */ |
2060 | pos->session = NULL; | 2100 | pos->session = NULL; |
2061 | if (pos->addrlen != 0) | 2101 | if (pos->addrlen != 0) |
2062 | return; | 2102 | { |
2103 | if (nl->received_pong != GNUNET_NO) | ||
2104 | try_fast_reconnect (p, nl); | ||
2105 | return; | ||
2106 | } | ||
2107 | /* was inbound connection, free 'pos' */ | ||
2063 | if (prev == NULL) | 2108 | if (prev == NULL) |
2064 | rl->addresses = pos->next; | 2109 | rl->addresses = pos->next; |
2065 | else | 2110 | else |
@@ -2072,13 +2117,16 @@ plugin_env_session_end (void *cls, | |||
2072 | } | 2117 | } |
2073 | GNUNET_free (pos); | 2118 | GNUNET_free (pos); |
2074 | if (nl->received_pong == GNUNET_NO) | 2119 | if (nl->received_pong == GNUNET_NO) |
2075 | return; /* nothing to do */ | 2120 | return; /* nothing to do, never connected... */ |
2076 | /* check if we have any validated addresses left */ | 2121 | /* check if we have any validated addresses left */ |
2077 | pos = rl->addresses; | 2122 | pos = rl->addresses; |
2078 | while (pos != NULL) | 2123 | while (pos != NULL) |
2079 | { | 2124 | { |
2080 | if (pos->validated) | 2125 | if (pos->validated) |
2081 | return; | 2126 | { |
2127 | try_fast_reconnect (p, nl); | ||
2128 | return; | ||
2129 | } | ||
2082 | pos = pos->next; | 2130 | pos = pos->next; |
2083 | } | 2131 | } |
2084 | /* no valid addresses left, signal disconnect! */ | 2132 | /* no valid addresses left, signal disconnect! */ |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 93ee4c88e..3d12f6909 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -827,8 +827,8 @@ disconnect_session (struct Session *session) | |||
827 | else | 827 | else |
828 | prev->next = session->next; | 828 | prev->next = session->next; |
829 | session->plugin->env->session_end (session->plugin->env->cls, | 829 | session->plugin->env->session_end (session->plugin->env->cls, |
830 | &session->target, | 830 | &session->target, |
831 | session); | 831 | session); |
832 | /* clean up state */ | 832 | /* clean up state */ |
833 | if (session->transmit_handle != NULL) | 833 | if (session->transmit_handle != NULL) |
834 | { | 834 | { |
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 582d083dc..5dbb94bcb 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -329,6 +329,23 @@ struct UDP_NAT_Probes | |||
329 | 329 | ||
330 | 330 | ||
331 | /** | 331 | /** |
332 | * Information we keep for each of our listen sockets. | ||
333 | */ | ||
334 | struct UDP_Sock_Info | ||
335 | { | ||
336 | /** | ||
337 | * The network handle | ||
338 | */ | ||
339 | struct GNUNET_NETWORK_Handle *desc; | ||
340 | |||
341 | /** | ||
342 | * The port we bound to | ||
343 | */ | ||
344 | uint16_t port; | ||
345 | }; | ||
346 | |||
347 | |||
348 | /** | ||
332 | * Encapsulation of all of the state of the plugin. | 349 | * Encapsulation of all of the state of the plugin. |
333 | */ | 350 | */ |
334 | struct Plugin | 351 | struct Plugin |
@@ -405,6 +422,21 @@ struct Plugin | |||
405 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | 422 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; |
406 | 423 | ||
407 | /** | 424 | /** |
425 | * Probes in flight | ||
426 | */ | ||
427 | struct UDP_NAT_Probes *probes; | ||
428 | |||
429 | /** | ||
430 | * socket that we transmit all IPv4 data with | ||
431 | */ | ||
432 | struct UDP_Sock_Info udp_sockv4; | ||
433 | |||
434 | /** | ||
435 | * socket that we transmit all IPv6 data with | ||
436 | */ | ||
437 | struct UDP_Sock_Info udp_sockv6; | ||
438 | |||
439 | /** | ||
408 | * ID of select gnunet-nat-server stdout read task | 440 | * ID of select gnunet-nat-server stdout read task |
409 | */ | 441 | */ |
410 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | 442 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; |
@@ -431,31 +463,9 @@ struct Plugin | |||
431 | */ | 463 | */ |
432 | pid_t server_pid; | 464 | pid_t server_pid; |
433 | 465 | ||
434 | /** | ||
435 | * Probes in flight | ||
436 | */ | ||
437 | struct UDP_NAT_Probes *probes; | ||
438 | |||
439 | }; | 466 | }; |
440 | 467 | ||
441 | 468 | ||
442 | struct UDP_Sock_Info | ||
443 | { | ||
444 | /* The network handle */ | ||
445 | struct GNUNET_NETWORK_Handle *desc; | ||
446 | |||
447 | /* The port we bound to */ | ||
448 | int port; | ||
449 | }; | ||
450 | |||
451 | /* *********** globals ************* */ | ||
452 | |||
453 | /** | ||
454 | * the socket that we transmit all data with | ||
455 | */ | ||
456 | static struct UDP_Sock_Info udp_sock; | ||
457 | |||
458 | |||
459 | /** | 469 | /** |
460 | * Forward declaration. | 470 | * Forward declaration. |
461 | */ | 471 | */ |
@@ -490,38 +500,35 @@ static int | |||
490 | udp_transport_server_stop (void *cls) | 500 | udp_transport_server_stop (void *cls) |
491 | { | 501 | { |
492 | struct Plugin *plugin = cls; | 502 | struct Plugin *plugin = cls; |
493 | int ret; | ||
494 | int ok; | ||
495 | 503 | ||
496 | ret = 0; | ||
497 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) | 504 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) |
498 | { | 505 | { |
499 | GNUNET_SCHEDULER_cancel (plugin->env->sched, plugin->select_task); | 506 | GNUNET_SCHEDULER_cancel (plugin->env->sched, plugin->select_task); |
500 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | 507 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; |
501 | } | 508 | } |
502 | 509 | if (plugin->udp_sockv4.desc != NULL) | |
503 | ok = GNUNET_NETWORK_socket_close (udp_sock.desc); | 510 | { |
504 | if (ok == GNUNET_OK) | 511 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc)); |
505 | udp_sock.desc = NULL; | 512 | plugin->udp_sockv4.desc = NULL; |
506 | ret += ok; | 513 | } |
507 | 514 | if (plugin->udp_sockv6.desc != NULL) | |
515 | { | ||
516 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc)); | ||
517 | plugin->udp_sockv6.desc = NULL; | ||
518 | } | ||
508 | if (plugin->behind_nat == GNUNET_YES) | 519 | if (plugin->behind_nat == GNUNET_YES) |
509 | { | 520 | { |
510 | if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM)) | 521 | if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM)) |
511 | { | 522 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
512 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
513 | } | ||
514 | GNUNET_OS_process_wait (plugin->server_pid); | 523 | GNUNET_OS_process_wait (plugin->server_pid); |
515 | } | 524 | } |
516 | 525 | return GNUNET_OK; | |
517 | if (ret != GNUNET_OK) | ||
518 | return GNUNET_SYSERR; | ||
519 | return ret; | ||
520 | } | 526 | } |
521 | 527 | ||
522 | 528 | ||
523 | struct PeerSession * | 529 | struct PeerSession * |
524 | find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) | 530 | find_session (struct Plugin *plugin, |
531 | const struct GNUNET_PeerIdentity *peer) | ||
525 | { | 532 | { |
526 | struct PeerSession *pos; | 533 | struct PeerSession *pos; |
527 | 534 | ||
@@ -559,16 +566,16 @@ find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) | |||
559 | */ | 566 | */ |
560 | static ssize_t | 567 | static ssize_t |
561 | udp_real_send (void *cls, | 568 | udp_real_send (void *cls, |
562 | struct GNUNET_NETWORK_Handle *send_handle, | 569 | struct GNUNET_NETWORK_Handle *send_handle, |
563 | const struct GNUNET_PeerIdentity *target, | 570 | const struct GNUNET_PeerIdentity *target, |
564 | const char *msgbuf, | 571 | const char *msgbuf, |
565 | size_t msgbuf_size, | 572 | size_t msgbuf_size, |
566 | unsigned int priority, | 573 | unsigned int priority, |
567 | struct GNUNET_TIME_Relative timeout, | 574 | struct GNUNET_TIME_Relative timeout, |
568 | const void *addr, | 575 | const void *addr, |
569 | size_t addrlen, | 576 | size_t addrlen, |
570 | GNUNET_TRANSPORT_TransmitContinuation cont, | 577 | GNUNET_TRANSPORT_TransmitContinuation cont, |
571 | void *cont_cls) | 578 | void *cont_cls) |
572 | { | 579 | { |
573 | struct Plugin *plugin = cls; | 580 | struct Plugin *plugin = cls; |
574 | struct UDPMessage *message; | 581 | struct UDPMessage *message; |
@@ -581,11 +588,19 @@ udp_real_send (void *cls, | |||
581 | const void *sb; | 588 | const void *sb; |
582 | size_t sbs; | 589 | size_t sbs; |
583 | 590 | ||
591 | if (send_handle == NULL) | ||
592 | { | ||
593 | /* failed to open send socket for AF */ | ||
594 | if (cont != NULL) | ||
595 | cont (cont_cls, target, GNUNET_SYSERR); | ||
596 | return 0; | ||
597 | } | ||
584 | if ((addr == NULL) || (addrlen == 0)) | 598 | if ((addr == NULL) || (addrlen == 0)) |
585 | { | 599 | { |
586 | #if DEBUG_UDP | 600 | #if DEBUG_UDP |
587 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 601 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
588 | ("udp_real_send called without address, returning!\n")); | 602 | "udp", |
603 | "udp_real_send called without address, returning!\n"); | ||
589 | #endif | 604 | #endif |
590 | if (cont != NULL) | 605 | if (cont != NULL) |
591 | cont (cont_cls, target, GNUNET_SYSERR); | 606 | cont (cont_cls, target, GNUNET_SYSERR); |
@@ -642,7 +657,12 @@ udp_real_send (void *cls, | |||
642 | GNUNET_NETWORK_socket_sendto (send_handle, message, ssize, | 657 | GNUNET_NETWORK_socket_sendto (send_handle, message, ssize, |
643 | sb, | 658 | sb, |
644 | sbs); | 659 | sbs); |
645 | 660 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | |
661 | "UDP transmit %u-byte message to %s (%d: %s)\n", | ||
662 | (unsigned int) ssize, | ||
663 | GNUNET_a2s (sb, sbs), | ||
664 | (int) sent, | ||
665 | (sent < 0) ? STRERROR (errno) : "ok"); | ||
646 | if (cont != NULL) | 666 | if (cont != NULL) |
647 | { | 667 | { |
648 | if (sent == GNUNET_SYSERR) | 668 | if (sent == GNUNET_SYSERR) |
@@ -758,7 +778,6 @@ udp_plugin_send (void *cls, | |||
758 | } | 778 | } |
759 | 779 | ||
760 | sent = 0; | 780 | sent = 0; |
761 | |||
762 | if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES)) | 781 | if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES)) |
763 | { | 782 | { |
764 | peer_session = find_session(plugin, target); | 783 | peer_session = find_session(plugin, target); |
@@ -798,7 +817,13 @@ udp_plugin_send (void *cls, | |||
798 | { | 817 | { |
799 | if (peer_session->expecting_welcome == GNUNET_NO) /* We are "connected" */ | 818 | if (peer_session->expecting_welcome == GNUNET_NO) /* We are "connected" */ |
800 | { | 819 | { |
801 | sent = udp_real_send(cls, peer_session->sock, target, msgbuf, msgbuf_size, priority, timeout, peer_session->connect_addr, peer_session->connect_alen, cont, cont_cls); | 820 | sent = udp_real_send(cls, |
821 | peer_session->sock, | ||
822 | target, | ||
823 | msgbuf, msgbuf_size, | ||
824 | priority, timeout, | ||
825 | peer_session->connect_addr, peer_session->connect_alen, | ||
826 | cont, cont_cls); | ||
802 | } | 827 | } |
803 | else /* Haven't gotten a response from this peer, queue message */ | 828 | else /* Haven't gotten a response from this peer, queue message */ |
804 | { | 829 | { |
@@ -816,17 +841,23 @@ udp_plugin_send (void *cls, | |||
816 | } | 841 | } |
817 | else if (other_peer_natd == GNUNET_NO) /* Other peer not behind a NAT, so we can just send the message as is */ | 842 | else if (other_peer_natd == GNUNET_NO) /* Other peer not behind a NAT, so we can just send the message as is */ |
818 | { | 843 | { |
819 | sent = udp_real_send(cls, udp_sock.desc, target, msgbuf, msgbuf_size, priority, timeout, addr, addrlen, cont, cont_cls); | 844 | sent = udp_real_send(cls, |
845 | (addrlen == sizeof (struct IPv4UdpAddress)) ? plugin->udp_sockv4.desc : plugin->udp_sockv6.desc, | ||
846 | target, | ||
847 | msgbuf, msgbuf_size, | ||
848 | priority, timeout, addr, addrlen, | ||
849 | cont, cont_cls); | ||
820 | } | 850 | } |
821 | else /* Other peer is NAT'd, but we don't want to play with them (or can't!) */ | 851 | else /* Other peer is NAT'd, but we don't want to play with them (or can't!) */ |
822 | return GNUNET_SYSERR; | 852 | { |
853 | return GNUNET_SYSERR; | ||
854 | } | ||
823 | 855 | ||
824 | /* When GNUNET_SYSERR is returned from udp_real_send, we will still call | 856 | /* When GNUNET_SYSERR is returned from udp_real_send, we will still call |
825 | * the callback so must not return GNUNET_SYSERR! | 857 | * the callback so must not return GNUNET_SYSERR! |
826 | * If we do, then transport context get freed twice. */ | 858 | * If we did, then transport context would get freed twice. */ |
827 | if (sent == GNUNET_SYSERR) | 859 | if (sent == GNUNET_SYSERR) |
828 | return 0; | 860 | return 0; |
829 | |||
830 | return sent; | 861 | return sent; |
831 | } | 862 | } |
832 | 863 | ||
@@ -1011,12 +1042,12 @@ static void | |||
1011 | send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1042 | send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1012 | { | 1043 | { |
1013 | struct UDP_NAT_Probes *probe = cls; | 1044 | struct UDP_NAT_Probes *probe = cls; |
1014 | struct UDP_NAT_ProbeMessage *message; | 1045 | struct UDP_NAT_ProbeMessage message; |
1015 | struct Plugin *plugin = probe->plugin; | 1046 | struct Plugin *plugin = probe->plugin; |
1016 | 1047 | ||
1017 | message = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessage)); | 1048 | memset (&message, 0, sizeof (message)); |
1018 | message->header.size = htons(sizeof(struct UDP_NAT_ProbeMessage)); | 1049 | message.header.size = htons(sizeof(struct UDP_NAT_ProbeMessage)); |
1019 | message->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE); | 1050 | message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE); |
1020 | /* If they gave us a port, use that. If not, try our port. */ | 1051 | /* If they gave us a port, use that. If not, try our port. */ |
1021 | if (ntohs(probe->addr.u_port) == 0) | 1052 | if (ntohs(probe->addr.u_port) == 0) |
1022 | probe->addr.u_port = htons(plugin->port); | 1053 | probe->addr.u_port = htons(plugin->port); |
@@ -1025,16 +1056,14 @@ send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1025 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", | 1056 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", |
1026 | _("Sending a probe to port %d\n"), ntohs(probe->addr.u_port)); | 1057 | _("Sending a probe to port %d\n"), ntohs(probe->addr.u_port)); |
1027 | #endif | 1058 | #endif |
1028 | |||
1029 | probe->count++; | 1059 | probe->count++; |
1030 | 1060 | udp_real_send(plugin, | |
1031 | udp_real_send(plugin, udp_sock.desc, NULL, | 1061 | plugin->udp_sockv4.desc, |
1032 | (char *)message, ntohs(message->header.size), 0, | 1062 | NULL, |
1033 | GNUNET_TIME_relative_get_unit(), | 1063 | (char *)&message, ntohs(message.header.size), 0, |
1034 | &probe->addr, sizeof(probe->addr), | 1064 | GNUNET_TIME_relative_get_unit(), |
1035 | &udp_probe_continuation, probe); | 1065 | &probe->addr, sizeof(struct IPv4UdpAddress), |
1036 | 1066 | &udp_probe_continuation, probe); | |
1037 | GNUNET_free(message); | ||
1038 | } | 1067 | } |
1039 | 1068 | ||
1040 | 1069 | ||
@@ -1247,7 +1276,8 @@ udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
1247 | 1276 | ||
1248 | #if DEBUG_UDP | 1277 | #if DEBUG_UDP |
1249 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", | 1278 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", |
1250 | _("Received a probe on listen port %d, sent_from port %d\n"), sockinfo->port, incoming_port); | 1279 | _("Received a probe on listen port %d, sent_from port %d\n"), |
1280 | sockinfo->port, incoming_port); | ||
1251 | #endif | 1281 | #endif |
1252 | 1282 | ||
1253 | udp_real_send(plugin, sockinfo->desc, NULL, | 1283 | udp_real_send(plugin, sockinfo->desc, NULL, |
@@ -1259,7 +1289,8 @@ udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
1259 | 1289 | ||
1260 | #if DEBUG_UDP | 1290 | #if DEBUG_UDP |
1261 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", | 1291 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", |
1262 | _("Sent PROBE REPLY to port %d on outgoing port %d\n"), incoming_port, sockinfo->port); | 1292 | _("Sent PROBE REPLY to port %d on outgoing port %d\n"), |
1293 | incoming_port, sockinfo->port); | ||
1263 | #endif | 1294 | #endif |
1264 | GNUNET_free(outgoing_probe_reply); | 1295 | GNUNET_free(outgoing_probe_reply); |
1265 | break; | 1296 | break; |
@@ -1289,8 +1320,11 @@ udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
1289 | outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); | 1320 | outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); |
1290 | outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); | 1321 | outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); |
1291 | outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM); | 1322 | outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM); |
1292 | 1323 | udp_real_send(plugin, sockinfo->desc, NULL, | |
1293 | udp_real_send(plugin, sockinfo->desc, NULL, (char *)outgoing_probe_confirmation, ntohs(outgoing_probe_confirmation->header.size), 0, GNUNET_TIME_relative_get_unit(), sender_addr, fromlen, NULL, NULL); | 1324 | (char *)outgoing_probe_confirmation, |
1325 | ntohs(outgoing_probe_confirmation->header.size), 0, | ||
1326 | GNUNET_TIME_relative_get_unit(), | ||
1327 | sender_addr, fromlen, NULL, NULL); | ||
1294 | 1328 | ||
1295 | if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK) | 1329 | if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK) |
1296 | { | 1330 | { |
@@ -1425,13 +1459,13 @@ udp_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, | |||
1425 | * | 1459 | * |
1426 | */ | 1460 | */ |
1427 | static void | 1461 | static void |
1428 | udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1462 | udp_plugin_select (void *cls, |
1463 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1429 | { | 1464 | { |
1430 | struct Plugin *plugin = cls; | 1465 | struct Plugin *plugin = cls; |
1431 | char *buf; | 1466 | char buf[65536]; |
1432 | struct UDPMessage *msg; | 1467 | struct UDPMessage *msg; |
1433 | struct GNUNET_PeerIdentity *sender; | 1468 | struct GNUNET_PeerIdentity sender; |
1434 | unsigned int buflen; | ||
1435 | socklen_t fromlen; | 1469 | socklen_t fromlen; |
1436 | char addr[32]; | 1470 | char addr[32]; |
1437 | ssize_t ret; | 1471 | ssize_t ret; |
@@ -1446,26 +1480,27 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1446 | const struct sockaddr_in6 *s6; | 1480 | const struct sockaddr_in6 *s6; |
1447 | const void *ca; | 1481 | const void *ca; |
1448 | size_t calen; | 1482 | size_t calen; |
1449 | 1483 | struct UDP_Sock_Info *udp_sock; | |
1450 | 1484 | ||
1451 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | 1485 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; |
1452 | |||
1453 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 1486 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) |
1454 | return; | 1487 | return; |
1455 | 1488 | udp_sock = NULL; | |
1456 | buf = NULL; | 1489 | if (GNUNET_NETWORK_fdset_isset (tc->read_ready, |
1457 | sender = NULL; | 1490 | plugin->udp_sockv4.desc)) |
1458 | 1491 | udp_sock = &plugin->udp_sockv4; | |
1459 | buflen = GNUNET_NETWORK_socket_recvfrom_amount (udp_sock.desc); | 1492 | else if (GNUNET_NETWORK_fdset_isset (tc->read_ready, |
1460 | 1493 | plugin->udp_sockv6.desc)) | |
1461 | if (buflen == GNUNET_NO) | 1494 | udp_sock = &plugin->udp_sockv6; |
1462 | return; | 1495 | if (NULL == udp_sock) |
1463 | 1496 | { | |
1464 | buf = GNUNET_malloc (buflen); | 1497 | GNUNET_break (0); |
1498 | return; | ||
1499 | } | ||
1465 | fromlen = sizeof (addr); | 1500 | fromlen = sizeof (addr); |
1466 | memset (&addr, 0, sizeof(addr)); | 1501 | memset (&addr, 0, sizeof(addr)); |
1467 | ret = | 1502 | ret = |
1468 | GNUNET_NETWORK_socket_recvfrom (udp_sock.desc, buf, buflen, | 1503 | GNUNET_NETWORK_socket_recvfrom (udp_sock->desc, buf, sizeof (buf), |
1469 | (struct sockaddr *)&addr, &fromlen); | 1504 | (struct sockaddr *)&addr, &fromlen); |
1470 | 1505 | ||
1471 | if (AF_INET == ((struct sockaddr *)addr)->sa_family) | 1506 | if (AF_INET == ((struct sockaddr *)addr)->sa_family) |
@@ -1492,39 +1527,41 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1492 | ca = NULL; | 1527 | ca = NULL; |
1493 | calen = 0; | 1528 | calen = 0; |
1494 | } | 1529 | } |
1495 | 1530 | if (ret < sizeof (struct UDPMessage)) | |
1496 | if (ret <= 0) | ||
1497 | { | 1531 | { |
1498 | GNUNET_free (buf); | 1532 | GNUNET_break_op (0); |
1533 | plugin->select_task = | ||
1534 | GNUNET_SCHEDULER_add_select (plugin->env->sched, | ||
1535 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1536 | GNUNET_SCHEDULER_NO_TASK, | ||
1537 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
1538 | NULL, &udp_plugin_select, plugin); | ||
1499 | return; | 1539 | return; |
1500 | } | 1540 | } |
1501 | msg = (struct UDPMessage *) buf; | 1541 | msg = (struct UDPMessage *) buf; |
1502 | |||
1503 | if (ntohs (msg->header.size) < sizeof (struct UDPMessage)) | 1542 | if (ntohs (msg->header.size) < sizeof (struct UDPMessage)) |
1504 | { | 1543 | { |
1505 | GNUNET_free (buf); | 1544 | GNUNET_break_op (0); |
1545 | plugin->select_task = | ||
1546 | GNUNET_SCHEDULER_add_select (plugin->env->sched, | ||
1547 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1548 | GNUNET_SCHEDULER_NO_TASK, | ||
1549 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
1550 | NULL, &udp_plugin_select, plugin); | ||
1506 | return; | 1551 | return; |
1507 | } | 1552 | } |
1508 | |||
1509 | msgbuf = (char *)&msg[1]; | 1553 | msgbuf = (char *)&msg[1]; |
1510 | sender = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity)); | 1554 | memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity)); |
1511 | memcpy (sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity)); | ||
1512 | |||
1513 | offset = 0; | 1555 | offset = 0; |
1514 | count = 0; | 1556 | count = 0; |
1515 | tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage); | 1557 | tsize = ntohs (msg->header.size) - sizeof(struct UDPMessage); |
1516 | |||
1517 | while (offset < tsize) | 1558 | while (offset < tsize) |
1518 | { | 1559 | { |
1519 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; | 1560 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; |
1520 | udp_demultiplexer(plugin, sender, currhdr, ca, calen, &udp_sock); | 1561 | udp_demultiplexer(plugin, &sender, currhdr, ca, calen, udp_sock); |
1521 | offset += ntohs(currhdr->size); | 1562 | offset += ntohs(currhdr->size); |
1522 | count++; | 1563 | count++; |
1523 | } | 1564 | } |
1524 | GNUNET_free_non_null (buf); | ||
1525 | GNUNET_free_non_null (sender); | ||
1526 | |||
1527 | |||
1528 | plugin->select_task = | 1565 | plugin->select_task = |
1529 | GNUNET_SCHEDULER_add_select (plugin->env->sched, | 1566 | GNUNET_SCHEDULER_add_select (plugin->env->sched, |
1530 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 1567 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
@@ -1535,13 +1572,11 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1535 | } | 1572 | } |
1536 | 1573 | ||
1537 | /** | 1574 | /** |
1538 | * Create a slew of UDP sockets. If possible, use IPv6, otherwise | 1575 | * Create a slew of UDP sockets. If possible, use IPv6 and IPv4. |
1539 | * try IPv4. | ||
1540 | * | 1576 | * |
1541 | * @param cls closure for server start, should be a struct Plugin * | 1577 | * @param cls closure for server start, should be a struct Plugin * |
1542 | * | ||
1543 | * @return number of sockets created or GNUNET_SYSERR on error | 1578 | * @return number of sockets created or GNUNET_SYSERR on error |
1544 | */ | 1579 | */ |
1545 | static int | 1580 | static int |
1546 | udp_transport_server_start (void *cls) | 1581 | udp_transport_server_start (void *cls) |
1547 | { | 1582 | { |
@@ -1551,9 +1586,9 @@ udp_transport_server_start (void *cls) | |||
1551 | struct sockaddr *serverAddr; | 1586 | struct sockaddr *serverAddr; |
1552 | socklen_t addrlen; | 1587 | socklen_t addrlen; |
1553 | int sockets_created; | 1588 | int sockets_created; |
1589 | int tries; | ||
1554 | 1590 | ||
1555 | sockets_created = 0; | 1591 | sockets_created = 0; |
1556 | |||
1557 | if (plugin->behind_nat == GNUNET_YES) | 1592 | if (plugin->behind_nat == GNUNET_YES) |
1558 | { | 1593 | { |
1559 | /* Pipe to read from started processes stdout (on read end) */ | 1594 | /* Pipe to read from started processes stdout (on read end) */ |
@@ -1561,12 +1596,18 @@ udp_transport_server_start (void *cls) | |||
1561 | if (plugin->server_stdout == NULL) | 1596 | if (plugin->server_stdout == NULL) |
1562 | return sockets_created; | 1597 | return sockets_created; |
1563 | #if DEBUG_UDP | 1598 | #if DEBUG_UDP |
1564 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1599 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1565 | "udp", | 1600 | "udp", |
1566 | "Starting gnunet-nat-server process cmd: %s %s\n", "gnunet-nat-server", plugin->internal_address); | 1601 | "Starting gnunet-nat-server process cmd: %s %s\n", |
1602 | "gnunet-nat-server", | ||
1603 | plugin->internal_address); | ||
1567 | #endif | 1604 | #endif |
1568 | /* Start the server process */ | 1605 | /* Start the server process */ |
1569 | plugin->server_pid = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL); | 1606 | plugin->server_pid = GNUNET_OS_start_process(NULL, |
1607 | plugin->server_stdout, | ||
1608 | "gnunet-nat-server", | ||
1609 | "gnunet-nat-server", | ||
1610 | plugin->internal_address, NULL); | ||
1570 | if (plugin->server_pid == GNUNET_SYSERR) | 1611 | if (plugin->server_pid == GNUNET_SYSERR) |
1571 | { | 1612 | { |
1572 | #if DEBUG_UDP | 1613 | #if DEBUG_UDP |
@@ -1578,62 +1619,25 @@ udp_transport_server_start (void *cls) | |||
1578 | } | 1619 | } |
1579 | /* Close the write end of the read pipe */ | 1620 | /* Close the write end of the read pipe */ |
1580 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE); | 1621 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE); |
1581 | 1622 | ||
1582 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); | 1623 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); |
1583 | plugin->server_read_task = | 1624 | plugin->server_read_task = |
1584 | GNUNET_SCHEDULER_add_read_file (plugin->env->sched, | 1625 | GNUNET_SCHEDULER_add_read_file (plugin->env->sched, |
1585 | GNUNET_TIME_UNIT_FOREVER_REL, | 1626 | GNUNET_TIME_UNIT_FOREVER_REL, |
1586 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | 1627 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); |
1587 | } | 1628 | } |
1588 | 1629 | ||
1589 | udp_sock.desc = NULL; | 1630 | if ( (GNUNET_YES != |
1590 | 1631 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "GNUNETD", | |
1591 | 1632 | "DISABLE-IPV6"))) | |
1592 | udp_sock.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 17); | ||
1593 | if (NULL == udp_sock.desc) | ||
1594 | { | ||
1595 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket"); | ||
1596 | return sockets_created; | ||
1597 | } | ||
1598 | else | ||
1599 | { | ||
1600 | memset (&serverAddrv4, 0, sizeof (serverAddrv4)); | ||
1601 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1602 | serverAddrv4.sin_len = sizeof (serverAddrv4); | ||
1603 | #endif | ||
1604 | serverAddrv4.sin_family = AF_INET; | ||
1605 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | ||
1606 | serverAddrv4.sin_port = htons (plugin->port); | ||
1607 | addrlen = sizeof (serverAddrv4); | ||
1608 | serverAddr = (struct sockaddr *) &serverAddrv4; | ||
1609 | #if DEBUG_UDP | ||
1610 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1611 | "udp", | ||
1612 | "Binding to port %d\n", ntohs(serverAddrv4.sin_port)); | ||
1613 | #endif | ||
1614 | while (GNUNET_NETWORK_socket_bind (udp_sock.desc, serverAddr, addrlen) != | ||
1615 | GNUNET_OK) | ||
1616 | { | ||
1617 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1618 | #if DEBUG_UDP | ||
1619 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1620 | "udp", | ||
1621 | "Binding failed, trying new port %d\n", | ||
1622 | ntohs(serverAddrv4.sin_port)); | ||
1623 | #endif | ||
1624 | } | ||
1625 | udp_sock.port = ntohs(serverAddrv4.sin_port); | ||
1626 | sockets_created++; | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | if ((udp_sock.desc == NULL) && (GNUNET_YES != | ||
1631 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "GNUNETD", | ||
1632 | "DISABLE-IPV6"))) | ||
1633 | { | 1633 | { |
1634 | udp_sock.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 17); | 1634 | plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 17); |
1635 | if (udp_sock.desc != NULL) | 1635 | if (NULL == plugin->udp_sockv6.desc) |
1636 | { | 1636 | { |
1637 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket"); | ||
1638 | } | ||
1639 | else | ||
1640 | { | ||
1637 | memset (&serverAddrv6, 0, sizeof (serverAddrv6)); | 1641 | memset (&serverAddrv6, 0, sizeof (serverAddrv6)); |
1638 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1642 | #if HAVE_SOCKADDR_IN_SIN_LEN |
1639 | serverAddrv6.sin6_len = sizeof (serverAddrv6); | 1643 | serverAddrv6.sin6_len = sizeof (serverAddrv6); |
@@ -1643,24 +1647,101 @@ udp_transport_server_start (void *cls) | |||
1643 | serverAddrv6.sin6_port = htons (plugin->port); | 1647 | serverAddrv6.sin6_port = htons (plugin->port); |
1644 | addrlen = sizeof (serverAddrv6); | 1648 | addrlen = sizeof (serverAddrv6); |
1645 | serverAddr = (struct sockaddr *) &serverAddrv6; | 1649 | serverAddr = (struct sockaddr *) &serverAddrv6; |
1646 | sockets_created++; | 1650 | #if DEBUG_UDP |
1647 | } | 1651 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1652 | "udp", | ||
1653 | "Binding to IPv6 port %d\n", | ||
1654 | ntohs(serverAddrv6.sin6_port)); | ||
1655 | #endif | ||
1656 | tries = 0; | ||
1657 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) != | ||
1658 | GNUNET_OK) | ||
1659 | { | ||
1660 | serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1661 | #if DEBUG_UDP | ||
1662 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1663 | "udp", | ||
1664 | "IPv6 Binding failed, trying new port %d\n", | ||
1665 | ntohs(serverAddrv6.sin6_port)); | ||
1666 | #endif | ||
1667 | tries++; | ||
1668 | if (tries > 10) | ||
1669 | { | ||
1670 | GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc); | ||
1671 | plugin->udp_sockv6.desc = NULL; | ||
1672 | break; | ||
1673 | } | ||
1674 | } | ||
1675 | if (plugin->udp_sockv6.desc != NULL) | ||
1676 | { | ||
1677 | plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port); | ||
1678 | sockets_created++; | ||
1679 | } | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 17); | ||
1684 | if (NULL == plugin->udp_sockv4.desc) | ||
1685 | { | ||
1686 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket"); | ||
1687 | } | ||
1688 | else | ||
1689 | { | ||
1690 | memset (&serverAddrv4, 0, sizeof (serverAddrv4)); | ||
1691 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1692 | serverAddrv4.sin_len = sizeof (serverAddrv4); | ||
1693 | #endif | ||
1694 | serverAddrv4.sin_family = AF_INET; | ||
1695 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | ||
1696 | serverAddrv4.sin_port = htons (plugin->port); | ||
1697 | addrlen = sizeof (serverAddrv4); | ||
1698 | serverAddr = (struct sockaddr *) &serverAddrv4; | ||
1699 | #if DEBUG_UDP | ||
1700 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1701 | "udp", | ||
1702 | "Binding to IPv4 port %d\n", | ||
1703 | ntohs(serverAddrv4.sin_port)); | ||
1704 | #endif | ||
1705 | tries = 0; | ||
1706 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) != | ||
1707 | GNUNET_OK) | ||
1708 | { | ||
1709 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1710 | #if DEBUG_UDP | ||
1711 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1712 | "udp", | ||
1713 | "IPv4 Binding failed, trying new port %d\n", | ||
1714 | ntohs(serverAddrv4.sin_port)); | ||
1715 | #endif | ||
1716 | tries++; | ||
1717 | if (tries > 10) | ||
1718 | { | ||
1719 | GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc); | ||
1720 | plugin->udp_sockv4.desc = NULL; | ||
1721 | break; | ||
1722 | } | ||
1723 | } | ||
1724 | if (plugin->udp_sockv4.desc != NULL) | ||
1725 | { | ||
1726 | plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port); | ||
1727 | sockets_created++; | ||
1728 | } | ||
1648 | } | 1729 | } |
1649 | 1730 | ||
1650 | plugin->rs = GNUNET_NETWORK_fdset_create (); | 1731 | plugin->rs = GNUNET_NETWORK_fdset_create (); |
1651 | |||
1652 | GNUNET_NETWORK_fdset_zero (plugin->rs); | 1732 | GNUNET_NETWORK_fdset_zero (plugin->rs); |
1653 | 1733 | if (NULL != plugin->udp_sockv4.desc) | |
1654 | 1734 | GNUNET_NETWORK_fdset_set (plugin->rs, | |
1655 | GNUNET_NETWORK_fdset_set (plugin->rs, udp_sock.desc); | 1735 | plugin->udp_sockv4.desc); |
1656 | 1736 | if (NULL != plugin->udp_sockv6.desc) | |
1737 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
1738 | plugin->udp_sockv6.desc); | ||
1657 | plugin->select_task = | 1739 | plugin->select_task = |
1658 | GNUNET_SCHEDULER_add_select (plugin->env->sched, | 1740 | GNUNET_SCHEDULER_add_select (plugin->env->sched, |
1659 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, | 1741 | GNUNET_SCHEDULER_PRIORITY_DEFAULT, |
1660 | GNUNET_SCHEDULER_NO_TASK, | 1742 | GNUNET_SCHEDULER_NO_TASK, |
1661 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | 1743 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, |
1662 | NULL, &udp_plugin_select, plugin); | 1744 | NULL, &udp_plugin_select, plugin); |
1663 | |||
1664 | return sockets_created; | 1745 | return sockets_created; |
1665 | } | 1746 | } |
1666 | 1747 | ||
@@ -2167,9 +2248,10 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2167 | } | 2248 | } |
2168 | 2249 | ||
2169 | sockets_created = udp_transport_server_start (plugin); | 2250 | sockets_created = udp_transport_server_start (plugin); |
2170 | 2251 | if (sockets_created == 0) | |
2171 | GNUNET_assert (sockets_created == 1); | 2252 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
2172 | 2253 | "udp", | |
2254 | _("Failed to open UDP sockets\n")); | ||
2173 | return api; | 2255 | return api; |
2174 | } | 2256 | } |
2175 | 2257 | ||
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index cd09511ac..52b9282de 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -269,6 +269,7 @@ exchange_hello (void *cls, | |||
269 | GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2); | 269 | GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2); |
270 | } | 270 | } |
271 | 271 | ||
272 | |||
272 | static void | 273 | static void |
273 | run (void *cls, | 274 | run (void *cls, |
274 | struct GNUNET_SCHEDULER_Handle *s, | 275 | struct GNUNET_SCHEDULER_Handle *s, |
@@ -278,7 +279,6 @@ run (void *cls, | |||
278 | GNUNET_assert (ok == 1); | 279 | GNUNET_assert (ok == 1); |
279 | OKPP; | 280 | OKPP; |
280 | sched = s; | 281 | sched = s; |
281 | |||
282 | die_task = GNUNET_SCHEDULER_add_delayed (sched, | 282 | die_task = GNUNET_SCHEDULER_add_delayed (sched, |
283 | TIMEOUT, | 283 | TIMEOUT, |
284 | &end_badly, NULL); | 284 | &end_badly, NULL); |
@@ -318,8 +318,7 @@ run (void *cls, | |||
318 | static int | 318 | static int |
319 | check () | 319 | check () |
320 | { | 320 | { |
321 | 321 | static char *const argv[] = { "test-transport-api", | |
322 | char *const argv[] = { "test-transport-api", | ||
323 | "-c", | 322 | "-c", |
324 | "test_transport_api_data.conf", | 323 | "test_transport_api_data.conf", |
325 | #if VERBOSE | 324 | #if VERBOSE |
@@ -327,15 +326,13 @@ check () | |||
327 | #endif | 326 | #endif |
328 | NULL | 327 | NULL |
329 | }; | 328 | }; |
329 | static struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
330 | GNUNET_GETOPT_OPTION_END | ||
331 | }; | ||
330 | 332 | ||
331 | #if WRITECONFIG | 333 | #if WRITECONFIG |
332 | setTransportOptions("test_transport_api_data.conf"); | 334 | setTransportOptions("test_transport_api_data.conf"); |
333 | #endif | 335 | #endif |
334 | |||
335 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
336 | GNUNET_GETOPT_OPTION_END | ||
337 | }; | ||
338 | |||
339 | ok = 1; | 336 | ok = 1; |
340 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, | 337 | GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, |
341 | argv, "test-transport-api", "nohelp", | 338 | argv, "test-transport-api", "nohelp", |
@@ -374,13 +371,10 @@ get_path_from_PATH () | |||
374 | pos = end + 1; | 371 | pos = end + 1; |
375 | } | 372 | } |
376 | sprintf (buf, "%s/%s", pos, "gnunet-nat-server"); | 373 | sprintf (buf, "%s/%s", pos, "gnunet-nat-server"); |
374 | GNUNET_free (path); | ||
377 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | 375 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) |
378 | { | 376 | return buf; |
379 | GNUNET_free (path); | ||
380 | return buf; | ||
381 | } | ||
382 | GNUNET_free (buf); | 377 | GNUNET_free (buf); |
383 | GNUNET_free (path); | ||
384 | return NULL; | 378 | return NULL; |
385 | } | 379 | } |
386 | 380 | ||
diff --git a/src/transport/test_transport_api_udp_peer1.conf b/src/transport/test_transport_api_udp_peer1.conf index 49efbff63..53e11f4c2 100644 --- a/src/transport/test_transport_api_udp_peer1.conf +++ b/src/transport/test_transport_api_udp_peer1.conf | |||
@@ -34,7 +34,7 @@ AUTOSTART = NO | |||
34 | 34 | ||
35 | [transport] | 35 | [transport] |
36 | PLUGINS = udp | 36 | PLUGINS = udp |
37 | DEBUG = NO | 37 | DEBUG = YES |
38 | ACCEPT_FROM6 = ::1; | 38 | ACCEPT_FROM6 = ::1; |
39 | ACCEPT_FROM = 127.0.0.1; | 39 | ACCEPT_FROM = 127.0.0.1; |
40 | NEIGHBOUR_LIMIT = 50 | 40 | NEIGHBOUR_LIMIT = 50 |
diff --git a/src/transport/test_transport_api_udp_peer2.conf b/src/transport/test_transport_api_udp_peer2.conf index 284f09b21..764674ba1 100644 --- a/src/transport/test_transport_api_udp_peer2.conf +++ b/src/transport/test_transport_api_udp_peer2.conf | |||
@@ -31,7 +31,7 @@ MINIMUM-FRIENDS = 0 | |||
31 | 31 | ||
32 | [transport] | 32 | [transport] |
33 | PLUGINS = udp | 33 | PLUGINS = udp |
34 | DEBUG = NO | 34 | DEBUG = YES |
35 | PREFIX = | 35 | PREFIX = |
36 | ACCEPT_FROM6 = ::1; | 36 | ACCEPT_FROM6 = ::1; |
37 | ACCEPT_FROM = 127.0.0.1; | 37 | ACCEPT_FROM = 127.0.0.1; |