aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/Makefile.am22
-rw-r--r--src/transport/plugin_transport_udp_nat.c176
-rw-r--r--src/transport/test_transport_api.c71
-rw-r--r--src/transport/test_transport_api_udp_nat_peer1.conf11
-rw-r--r--src/transport/test_transport_api_udp_nat_peer2.conf9
5 files changed, 215 insertions, 74 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index afcd60bc5..d4221ca03 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -62,12 +62,12 @@ gnunet_service_transport_LDADD = \
62 $(GN_LIBINTL) 62 $(GN_LIBINTL)
63 63
64 64
65
66plugin_LTLIBRARIES = \ 65plugin_LTLIBRARIES = \
67 libgnunet_plugin_transport_tcp.la \ 66 libgnunet_plugin_transport_tcp.la \
68 libgnunet_plugin_transport_udp.la \ 67 libgnunet_plugin_transport_udp.la \
68 libgnunet_plugin_transport_udp_nat.la \
69 libgnunet_plugin_transport_template.la 69 libgnunet_plugin_transport_template.la
70# TODO: add udp, http, nat, etc. 70# TODO: add http, nat, etc.
71 71
72libgnunet_plugin_transport_tcp_la_SOURCES = \ 72libgnunet_plugin_transport_tcp_la_SOURCES = \
73 plugin_transport_tcp.c 73 plugin_transport_tcp.c
@@ -94,9 +94,19 @@ libgnunet_plugin_transport_udp_la_LIBADD = \
94libgnunet_plugin_transport_udp_la_LDFLAGS = \ 94libgnunet_plugin_transport_udp_la_LDFLAGS = \
95 $(GN_PLUGIN_LDFLAGS) 95 $(GN_PLUGIN_LDFLAGS)
96 96
97libgnunet_plugin_transport_udp_nat_la_SOURCES = \
98 plugin_transport_udp_nat.c
99libgnunet_plugin_transport_udp_nat_la_LIBADD = \
100 $(top_builddir)/src/hello/libgnunethello.la \
101 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
102 $(top_builddir)/src/util/libgnunetutil.la
103libgnunet_plugin_transport_udp_nat_la_LDFLAGS = \
104 $(GN_PLUGIN_LDFLAGS)
105
97check_PROGRAMS = \ 106check_PROGRAMS = \
98 test_transport_api_tcp \ 107 test_transport_api_tcp \
99 test_transport_api_udp 108 test_transport_api_udp \
109 test_transport_api_udp_nat
100# TODO: add tests for http, nat, etc. 110# TODO: add tests for http, nat, etc.
101 111
102TESTS = $(check_PROGRAMS) 112TESTS = $(check_PROGRAMS)
@@ -112,6 +122,12 @@ test_transport_api_udp_SOURCES = \
112test_transport_api_udp_LDADD = \ 122test_transport_api_udp_LDADD = \
113 $(top_builddir)/src/transport/libgnunettransport.la \ 123 $(top_builddir)/src/transport/libgnunettransport.la \
114 $(top_builddir)/src/util/libgnunetutil.la 124 $(top_builddir)/src/util/libgnunetutil.la
125
126test_transport_api_udp_nat_SOURCES = \
127 test_transport_api.c
128test_transport_api_udp_nat_LDADD = \
129 $(top_builddir)/src/transport/libgnunettransport.la \
130 $(top_builddir)/src/util/libgnunetutil.la
115 131
116EXTRA_DIST = \ 132EXTRA_DIST = \
117 test_transport_api_data.conf \ 133 test_transport_api_data.conf \
diff --git a/src/transport/plugin_transport_udp_nat.c b/src/transport/plugin_transport_udp_nat.c
index afa731a38..e2976fdab 100644
--- a/src/transport/plugin_transport_udp_nat.c
+++ b/src/transport/plugin_transport_udp_nat.c
@@ -76,12 +76,12 @@ static struct GNUNET_RESOLVER_RequestHandle *hostname_dns;
76 * 76 *
77 * FIXME: make this value dynamic, specified by configuration 77 * FIXME: make this value dynamic, specified by configuration
78 */ 78 */
79#define UDP_NAT_LISTEN_PORTS 1 79#define UDP_NAT_LISTEN_PORTS 257
80 80
81/* 81/*
82 * Starting port for listening and sending, eventually a config value 82 * Starting port for listening and sending, eventually a config value
83 */ 83 */
84#define UDP_NAT_STARTING_PORT 24857 84#define UDP_NAT_STARTING_PORT 22086
85 85
86/** 86/**
87 * UDP Message-Packet header. 87 * UDP Message-Packet header.
@@ -329,6 +329,11 @@ struct Plugin
329 uint16_t starting_port; 329 uint16_t starting_port;
330 330
331 /** 331 /**
332 * Starting port for sending out crazy messages
333 */
334 uint32_t random_starting_port;
335
336 /**
332 * How many ports should we be using? 337 * How many ports should we be using?
333 */ 338 */
334 uint16_t num_ports; 339 uint16_t num_ports;
@@ -376,12 +381,22 @@ struct Plugin
376 381
377}; 382};
378 383
384
385struct UDP_Sock_Info
386{
387 /* The network handle */
388 struct GNUNET_NETWORK_Handle *desc;
389
390 /* The port we bound to */
391 int port;
392};
393
379/* *********** globals ************* */ 394/* *********** globals ************* */
380 395
381/** 396/**
382 * the socket that we transmit all data with 397 * the socket that we transmit all data with
383 */ 398 */
384static struct GNUNET_NETWORK_Handle *udp_nat_socks[UDP_NAT_LISTEN_PORTS]; 399static struct UDP_Sock_Info *udp_nat_socks[UDP_NAT_LISTEN_PORTS];
385 400
386 401
387/** 402/**
@@ -423,9 +438,9 @@ udp_nat_transport_server_stop (void *cls)
423 438
424 for (i = 0; i < plugin->num_ports; i++) 439 for (i = 0; i < plugin->num_ports; i++)
425 { 440 {
426 ok = GNUNET_NETWORK_socket_close (udp_nat_socks[i]); 441 ok = GNUNET_NETWORK_socket_close (udp_nat_socks[i]->desc);
427 if (ok == GNUNET_OK) 442 if (ok == GNUNET_OK)
428 udp_nat_socks[i] = NULL; 443 udp_nat_socks[i]->desc = NULL;
429 ret += ok; 444 ret += ok;
430 } 445 }
431 446
@@ -514,10 +529,6 @@ udp_nat_real_send (void *cls,
514 message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size); 529 message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size);
515 ssize = sizeof (struct UDPMessage) + msgbuf_size; 530 ssize = sizeof (struct UDPMessage) + msgbuf_size;
516 531
517#if DEBUG_UDP_NAT
518 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
519 ("In udp_nat_send, ssize is %d, sending message to %s\n"), ssize, GNUNET_a2s((const struct sockaddr *)addr, addrlen));
520#endif
521 message->header.size = htons (ssize); 532 message->header.size = htons (ssize);
522 message->header.type = htons (0); 533 message->header.type = htons (0);
523 memcpy (&message->sender, plugin->env->my_identity, 534 memcpy (&message->sender, plugin->env->my_identity,
@@ -536,10 +547,6 @@ udp_nat_real_send (void *cls,
536 cont (cont_cls, target, GNUNET_SYSERR); 547 cont (cont_cls, target, GNUNET_SYSERR);
537 else 548 else
538 { 549 {
539#if DEBUG_UDP_NAT
540 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
541 ("Successfully sent message, calling transmit continuation!\n"));
542#endif
543 cont (cont_cls, target, GNUNET_OK); 550 cont (cont_cls, target, GNUNET_OK);
544 } 551 }
545 } 552 }
@@ -634,8 +641,10 @@ udp_nat_plugin_send (void *cls,
634 * udp sock (or address, or index of udp sock array...) 641 * udp sock (or address, or index of udp sock array...)
635 */ 642 */
636 sent = 0; 643 sent = 0;
644#if DISTINGUISH
637 if (plugin->behind_nat == GNUNET_NO) 645 if (plugin->behind_nat == GNUNET_NO)
638 { 646 {
647#endif
639 peer_session = find_session(plugin, target); 648 peer_session = find_session(plugin, target);
640 if (peer_session == NULL) /* We have a new peer to add */ 649 if (peer_session == NULL) /* We have a new peer to add */
641 { 650 {
@@ -690,11 +699,13 @@ udp_nat_plugin_send (void *cls,
690 peer_session->messages = temp_message; 699 peer_session->messages = temp_message;
691 } 700 }
692 } 701 }
702#if DISTINGUISH
693 } 703 }
694 else /* We are behind a NAT, so we can just send the message as is */ 704 else /* We are behind a NAT, so we can just send the message as is */
695 { 705 {
696 sent = udp_nat_real_send(cls, udp_nat_socks[0], target, msgbuf, msgbuf_size, priority, timeout, addr, addrlen, cont, cont_cls); 706 sent = udp_nat_real_send(cls, udp_nat_socks[0], target, msgbuf, msgbuf_size, priority, timeout, addr, addrlen, cont, cont_cls);
697 } 707 }
708#endif
698 709
699 return sent; 710 return sent;
700} 711}
@@ -796,23 +807,23 @@ send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc
796 message = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessage)); 807 message = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessage));
797 message->header.size = htons(sizeof(struct UDP_NAT_ProbeMessage)); 808 message->header.size = htons(sizeof(struct UDP_NAT_ProbeMessage));
798 message->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE); 809 message->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE);
799 //message->port = htons(probe->index + plugin->starting_port); 810 /* Try the agreed upon port first, then go in order starting with our randomly chosen port */
800 probe->sock_addr.sin_port = htons(probe->index + plugin->starting_port); 811 if (probe->index == 0)
812 probe->sock_addr.sin_port = htons(plugin->starting_port);
813 else
814 probe->sock_addr.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a non-root port */
801#if DEBUG_UDP_NAT 815#if DEBUG_UDP_NAT
802 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", 816 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
803 _("Sending a probe on port %d\n"), ntohs(probe->sock_addr.sin_port)); 817 _("Sending a probe to port %d\n"), ntohs(probe->sock_addr.sin_port));
804#endif
805#if DEBUG_UDP_NAT
806 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
807 ("about to send probe, ssize is %d, sending message to %s\n"), ntohs(message->header.size), GNUNET_a2s((const struct sockaddr *)&probe->sock_addr, sizeof(probe->sock_addr)));
808#endif 818#endif
809 sent = udp_nat_real_send(plugin, udp_nat_socks[probe->index], NULL, (char *)message, ntohs(message->header.size), 0, GNUNET_TIME_relative_get_unit(), &probe->sock_addr, sizeof(probe->sock_addr), &udp_probe_continuation, probe);
810
811 if (probe->index + 1 < plugin->num_ports) 819 if (probe->index + 1 < plugin->num_ports)
812 probe->index += 1; 820 probe->index += 1;
813 else 821 else
814 probe->index = 0; 822 probe->index = 0;
815 823
824 sent = udp_nat_real_send(plugin, udp_nat_socks[probe->index]->desc, NULL, (char *)message, ntohs(message->header.size), 0, GNUNET_TIME_relative_get_unit(), &probe->sock_addr, sizeof(probe->sock_addr), &udp_probe_continuation, probe);
825
826 GNUNET_free(message);
816} 827}
817 828
818 829
@@ -836,14 +847,19 @@ udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int
836 847
837 if (result == GNUNET_OK) 848 if (result == GNUNET_OK)
838 { 849 {
850 if (probe->index == 0)
851 {
839#if DEBUG_UDP_NAT 852#if DEBUG_UDP_NAT
840 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", 853 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
841 _("Successfully sent a probe\n")); 854 _("Scheduling next probe for 10000 milliseconds\n"));
842#endif 855#endif
843 if (probe->index == 0) 856 probe->task = GNUNET_SCHEDULER_add_delayed(plugin->env->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 10000), &send_udp_probe_message, probe);
844 probe->task = GNUNET_SCHEDULER_add_delayed(plugin->env->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 5000), &send_udp_probe_message, probe); 857 }
858
845 else 859 else
846 probe->task = GNUNET_SCHEDULER_add_delayed(plugin->env->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500), &send_udp_probe_message, probe); 860 {
861 probe->task = GNUNET_SCHEDULER_add_delayed(plugin->env->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 50), &send_udp_probe_message, probe);
862 }
847 } 863 }
848 else /* Destroy the probe context? */ 864 else /* Destroy the probe context? */
849 { 865 {
@@ -916,7 +932,7 @@ udp_nat_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext
916 _("nat-server-read read: %s\n"), &mybuf); 932 _("nat-server-read read: %s\n"), &mybuf);
917#endif 933#endif
918 934
919 /* Schedule sending of messages to peer on each open port */ 935 /* Schedule sending of messages to peer on random ports */
920 temp_probe = find_probe(plugin, &mybuf[0]); 936 temp_probe = find_probe(plugin, &mybuf[0]);
921 937
922 if (temp_probe == NULL) 938 if (temp_probe == NULL)
@@ -947,7 +963,7 @@ udp_nat_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext
947 * 963 *
948 */ 964 */
949static void 965static void
950udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *currhdr, struct sockaddr_storage *sender_addr, socklen_t fromlen, int receiving_port) 966udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *currhdr, struct sockaddr_storage *sender_addr, socklen_t fromlen, struct UDP_Sock_Info *sockinfo)
951{ 967{
952 struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply; 968 struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply;
953 struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation; 969 struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation;
@@ -962,6 +978,15 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
962 struct MessageQueue *pending_message_temp; 978 struct MessageQueue *pending_message_temp;
963 int sent; 979 int sent;
964 980
981 if (memcmp(sender, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)) == 0)
982 {
983#if DEBUG_UDP_NAT
984 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
985 _("Received a message from myself, dropping!!!\n"));
986#endif
987 return;
988 }
989
965 switch (ntohs(currhdr->type)) 990 switch (ntohs(currhdr->type))
966 { 991 {
967 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE: 992 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE:
@@ -973,13 +998,13 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
973 998
974#if DEBUG_UDP_NAT 999#if DEBUG_UDP_NAT
975 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", 1000 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
976 _("Received a probe from port %d, sent_from port %d\n"), receiving_port, ((struct sockaddr_in *)sender_addr)->sin_port); 1001 _("Received a probe on listen port %d, sent_from port %d\n"), sockinfo->port, ntohs(((struct sockaddr_in *)sender_addr)->sin_port));
977#endif 1002#endif
978 1003
979 sent = udp_nat_real_send(plugin, udp_nat_socks[0], NULL, (char *)outgoing_probe_reply, ntohs(outgoing_probe_reply->header.size), 0, GNUNET_TIME_relative_get_unit(), sender_addr, fromlen, &dummy_continuation, NULL); 1004 sent = udp_nat_real_send(plugin, sockinfo->desc, NULL, (char *)outgoing_probe_reply, ntohs(outgoing_probe_reply->header.size), 0, GNUNET_TIME_relative_get_unit(), sender_addr, fromlen, &dummy_continuation, NULL);
980#if DEBUG_UDP_NAT 1005#if DEBUG_UDP_NAT
981 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", 1006 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
982 _("Sent %d byes of PROBE REPLY\n"), sent); 1007 _("Sent PROBE REPLY to port %d on outgoing port %d\n"), ntohs(((struct sockaddr_in *)sender_addr)->sin_port), sockinfo->port);
983#endif 1008#endif
984 1009
985 break; 1010 break;
@@ -987,8 +1012,8 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
987 /* Check for existing probe, check ports returned, send confirmation if all is well */ 1012 /* Check for existing probe, check ports returned, send confirmation if all is well */
988 incoming_probe_reply = (struct UDP_NAT_ProbeMessageReply *)currhdr; 1013 incoming_probe_reply = (struct UDP_NAT_ProbeMessageReply *)currhdr;
989#if DEBUG_UDP_NAT 1014#if DEBUG_UDP_NAT
990 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat", 1015 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
991 _("Received a probe reply with ss_family %d!\n"), sender_addr->ss_family); 1016 _("Received PROBE REPLY from port %d on incoming port %d\n"), ntohs(((struct sockaddr_in *)sender_addr)->sin_port), sockinfo->port);
992#endif 1017#endif
993 /* FIXME: use nonce, then IPv6 replies could work I think... */ 1018 /* FIXME: use nonce, then IPv6 replies could work I think... */
994 if (sender_addr->ss_family == AF_INET) 1019 if (sender_addr->ss_family == AF_INET)
@@ -1000,12 +1025,12 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
1000 { 1025 {
1001#if DEBUG_UDP_NAT 1026#if DEBUG_UDP_NAT
1002 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", 1027 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
1003 _("Sending confirmation that were were reached!\n")); 1028 _("Sending confirmation that we were reached!\n"));
1004#endif 1029#endif
1005 outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); 1030 outgoing_probe_confirmation = GNUNET_malloc(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1006 outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation)); 1031 outgoing_probe_confirmation->header.size = htons(sizeof(struct UDP_NAT_ProbeMessageConfirmation));
1007 outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM); 1032 outgoing_probe_confirmation->header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE_CONFIRM);
1008 sent = udp_nat_real_send(plugin, udp_nat_socks[receiving_port - plugin->starting_port], NULL, (char *)outgoing_probe_confirmation, ntohs(outgoing_probe_confirmation->header.size), 0, GNUNET_TIME_relative_get_unit(), sender_addr, fromlen, &dummy_continuation, NULL); 1033 sent = udp_nat_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, &dummy_continuation, NULL);
1009 if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK) 1034 if (outgoing_probe->task != GNUNET_SCHEDULER_NO_TASK)
1010 { 1035 {
1011 GNUNET_SCHEDULER_cancel(plugin->env->sched, outgoing_probe->task); 1036 GNUNET_SCHEDULER_cancel(plugin->env->sched, outgoing_probe->task);
@@ -1032,14 +1057,28 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
1032 if (peer_session == NULL) /* Shouldn't this NOT happen? */ 1057 if (peer_session == NULL) /* Shouldn't this NOT happen? */
1033 { 1058 {
1034#if DEBUG_UDP_NAT 1059#if DEBUG_UDP_NAT
1035 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat", 1060 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat",
1036 _("Received a probe confirmation, but don't remember this peer!\n")); 1061 _("Peer not in list, adding (THIS MAY BE A MISTAKE) %s\n"), GNUNET_i2s(sender));
1037#endif 1062#endif
1063 peer_session = GNUNET_malloc(sizeof(struct PeerSession));
1064 peer_session->connect_addr = GNUNET_malloc(fromlen);
1065 memcpy(peer_session->connect_addr, sender_addr, fromlen);
1066 peer_session->connect_alen = fromlen;
1067 peer_session->plugin = plugin;
1068 peer_session->sock = sockinfo->desc;
1069 memcpy(&peer_session->target, sender, sizeof(struct GNUNET_PeerIdentity));
1070 peer_session->expecting_welcome = GNUNET_NO;
1071
1072 peer_session->next = plugin->sessions;
1073 plugin->sessions = peer_session;
1074
1075 peer_session->messages = NULL;
1038 } 1076 }
1039 else if (peer_session->expecting_welcome == GNUNET_YES) 1077 else if (peer_session->expecting_welcome == GNUNET_YES)
1040 { 1078 {
1041 peer_session->expecting_welcome = GNUNET_NO; 1079 peer_session->expecting_welcome = GNUNET_NO;
1042 peer_session->sock = udp_nat_socks[receiving_port - plugin->starting_port]; /* This may matter, not sure right now... */ 1080 /* FIXME: There is no way to find this based on receiving port at the moment! */
1081 peer_session->sock = sockinfo->desc; /* This may matter, not sure right now... */
1043 ((struct sockaddr_in *)peer_session->connect_addr)->sin_port = ((struct sockaddr_in *) sender_addr)->sin_port; 1082 ((struct sockaddr_in *)peer_session->connect_addr)->sin_port = ((struct sockaddr_in *) sender_addr)->sin_port;
1044#if DEBUG_UDP_NAT 1083#if DEBUG_UDP_NAT
1045 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat", 1084 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat",
@@ -1052,13 +1091,23 @@ udp_nat_demultiplexer(struct Plugin *plugin, struct GNUNET_PeerIdentity *sender,
1052 _("Received a probe confirmation, sending queued messages.\n")); 1091 _("Received a probe confirmation, sending queued messages.\n"));
1053#endif 1092#endif
1054 pending_message = peer_session->messages; 1093 pending_message = peer_session->messages;
1094 int count = 0;
1055 while (pending_message != NULL) 1095 while (pending_message != NULL)
1056 { 1096 {
1057 udp_nat_real_send(plugin, peer_session->sock, &peer_session->target, pending_message->msgbuf, pending_message->msgbuf_size, 0, GNUNET_TIME_relative_get_unit(), peer_session->connect_addr, peer_session->connect_alen, &dummy_continuation, NULL); 1097#if DEBUG_UDP_NAT
1098 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat",
1099 _("sending queued message %d\n"), count);
1100#endif
1101 udp_nat_real_send(plugin, peer_session->sock, &peer_session->target, pending_message->msgbuf, pending_message->msgbuf_size, 0, GNUNET_TIME_relative_get_unit(), peer_session->connect_addr, peer_session->connect_alen, pending_message->cont, pending_message->cont_cls);
1058 pending_message_temp = pending_message; 1102 pending_message_temp = pending_message;
1059 pending_message = pending_message->next; 1103 pending_message = pending_message->next;
1060 GNUNET_free(pending_message_temp->msgbuf); 1104 GNUNET_free(pending_message_temp->msgbuf);
1061 GNUNET_free(pending_message_temp); 1105 GNUNET_free(pending_message_temp);
1106#if DEBUG_UDP_NAT
1107 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp-nat",
1108 _("finished sending queued message %d\n"), count);
1109#endif
1110 count++;
1062 } 1111 }
1063 } 1112 }
1064 1113
@@ -1116,16 +1165,16 @@ udp_nat_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1116 1165
1117 for (i = 0; i < plugin->num_ports; i++) 1166 for (i = 0; i < plugin->num_ports; i++)
1118 { 1167 {
1119 buflen = GNUNET_NETWORK_socket_recvfrom_amount (udp_nat_socks[i]); 1168 buflen = GNUNET_NETWORK_socket_recvfrom_amount (udp_nat_socks[i]->desc);
1120 1169
1121 if (buflen == GNUNET_NO) 1170 if (buflen == GNUNET_NO)
1122 break; 1171 continue;
1123 1172
1124 buf = GNUNET_malloc (buflen); 1173 buf = GNUNET_malloc (buflen);
1125 fromlen = sizeof (addr); 1174 fromlen = sizeof (addr);
1126 memset (&addr, 0, fromlen); 1175 memset (&addr, 0, fromlen);
1127 ret = 1176 ret =
1128 GNUNET_NETWORK_socket_recvfrom (udp_nat_socks[i], buf, buflen, 1177 GNUNET_NETWORK_socket_recvfrom (udp_nat_socks[i]->desc, buf, buflen,
1129 (struct sockaddr *) &addr, &fromlen); 1178 (struct sockaddr *) &addr, &fromlen);
1130 1179
1131#if DEBUG_UDP_NAT 1180#if DEBUG_UDP_NAT
@@ -1137,7 +1186,7 @@ udp_nat_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1137 if (ret <= 0) 1186 if (ret <= 0)
1138 { 1187 {
1139 GNUNET_free (buf); 1188 GNUNET_free (buf);
1140 break; 1189 continue;
1141 } 1190 }
1142 msg = (struct UDPMessage *) buf; 1191 msg = (struct UDPMessage *) buf;
1143 1192
@@ -1149,7 +1198,7 @@ udp_nat_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1149 if (ntohs (msg->header.size) < sizeof (struct UDPMessage)) 1198 if (ntohs (msg->header.size) < sizeof (struct UDPMessage))
1150 { 1199 {
1151 GNUNET_free (buf); 1200 GNUNET_free (buf);
1152 break; 1201 continue;
1153 } 1202 }
1154 hdr = (const struct GNUNET_MessageHeader *) &msg[1]; 1203 hdr = (const struct GNUNET_MessageHeader *) &msg[1];
1155 msgbuf = (char *)&msg[1]; 1204 msgbuf = (char *)&msg[1];
@@ -1168,8 +1217,12 @@ udp_nat_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1168 ("processing msg %d: type %d, size %d at offset %d\n"), 1217 ("processing msg %d: type %d, size %d at offset %d\n"),
1169 count, ntohs(currhdr->type), ntohs(currhdr->size), offset); 1218 count, ntohs(currhdr->type), ntohs(currhdr->size), offset);
1170#endif 1219#endif
1171 udp_nat_demultiplexer(plugin, sender, currhdr, &addr, fromlen, plugin->starting_port + i); 1220 udp_nat_demultiplexer(plugin, sender, currhdr, &addr, fromlen, udp_nat_socks[i]);
1172 1221#if DEBUG_UDP_NAT
1222 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
1223 ("processing done msg %d: type %d, size %d at offset %d\n"),
1224 count, ntohs(currhdr->type), ntohs(currhdr->size), offset);
1225#endif
1173 offset += ntohs(currhdr->size); 1226 offset += ntohs(currhdr->size);
1174 count++; 1227 count++;
1175 } 1228 }
@@ -1239,7 +1292,8 @@ udp_nat_transport_server_start (void *cls)
1239 /* Open all our sockets for reading/writing */ 1292 /* Open all our sockets for reading/writing */
1240 for (i = 0; i < plugin->num_ports; i++) 1293 for (i = 0; i < plugin->num_ports; i++)
1241 { 1294 {
1242 udp_nat_socks[i] = NULL; 1295 udp_nat_socks[i] = GNUNET_malloc(sizeof(struct UDP_Sock_Info));
1296 udp_nat_socks[i]->desc = NULL;
1243#if IPV6 1297#if IPV6
1244 if (GNUNET_YES != 1298 if (GNUNET_YES !=
1245 GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "GNUNETD", 1299 GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "GNUNETD",
@@ -1260,10 +1314,10 @@ udp_nat_transport_server_start (void *cls)
1260 } 1314 }
1261 } 1315 }
1262#endif 1316#endif
1263 if (NULL == udp_nat_socks[i]) 1317 if (NULL == udp_nat_socks[i]->desc)
1264 { 1318 {
1265 udp_nat_socks[i] = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 17); 1319 udp_nat_socks[i]->desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 17);
1266 if (NULL == udp_nat_socks[i]) 1320 if (NULL == udp_nat_socks[i]->desc)
1267 { 1321 {
1268 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", "socket"); 1322 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp-nat", "socket");
1269 return sockets_created; 1323 return sockets_created;
@@ -1279,29 +1333,30 @@ udp_nat_transport_server_start (void *cls)
1279 if (i == 0) 1333 if (i == 0)
1280 serverAddrv4.sin_port = htons (plugin->starting_port); 1334 serverAddrv4.sin_port = htons (plugin->starting_port);
1281 else 1335 else
1282 serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 64537) + 1000); /* Find a non-root port */ 1336 serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a non-root port */
1283 addrlen = sizeof (serverAddrv4); 1337 addrlen = sizeof (serverAddrv4);
1284 serverAddr = (struct sockaddr *) &serverAddrv4; 1338 serverAddr = (struct sockaddr *) &serverAddrv4;
1285 } 1339 }
1286 } 1340 }
1287 1341
1288 if (udp_nat_socks[i] != NULL) 1342 if (udp_nat_socks[i]->desc != NULL)
1289 { 1343 {
1290#if DEBUG_UDP_NAT 1344#if DEBUG_UDP_NAT
1291 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1345 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1292 "udp_nat", 1346 "udp_nat",
1293 "Binding to port %d\n", ntohs(serverAddrv4.sin_port)); 1347 "Binding to port %d\n", ntohs(serverAddrv4.sin_port));
1294#endif 1348#endif
1295 while (GNUNET_NETWORK_socket_bind (udp_nat_socks[i], serverAddr, addrlen) != 1349 while (GNUNET_NETWORK_socket_bind (udp_nat_socks[i]->desc, serverAddr, addrlen) !=
1296 GNUNET_OK) 1350 GNUNET_OK)
1297 { 1351 {
1298 serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, 64537) + 1000); /* Find a non-root port */ 1352 serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */
1299#if DEBUG_UDP_NAT 1353#if DEBUG_UDP_NAT
1300 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1354 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1301 "udp_nat", 1355 "udp_nat",
1302 "Binding failed, trying new port %d\n", ntohs(serverAddrv4.sin_port)); 1356 "Binding failed, trying new port %d\n", ntohs(serverAddrv4.sin_port));
1303#endif 1357#endif
1304 } 1358 }
1359 udp_nat_socks[i]->port = ntohs(serverAddrv4.sin_port);
1305 sockets_created++; 1360 sockets_created++;
1306 } 1361 }
1307 } 1362 }
@@ -1312,7 +1367,7 @@ udp_nat_transport_server_start (void *cls)
1312 1367
1313 for (i = 0; i < plugin->num_ports; i++) 1368 for (i = 0; i < plugin->num_ports; i++)
1314 { 1369 {
1315 GNUNET_NETWORK_fdset_set (plugin->rs, udp_nat_socks[i]); 1370 GNUNET_NETWORK_fdset_set (plugin->rs, udp_nat_socks[i]->desc);
1316 } 1371 }
1317 1372
1318 plugin->select_task = 1373 plugin->select_task =
@@ -1336,8 +1391,10 @@ udp_nat_transport_server_start (void *cls)
1336static uint16_t 1391static uint16_t
1337check_port (struct Plugin *plugin, uint16_t in_port) 1392check_port (struct Plugin *plugin, uint16_t in_port)
1338{ 1393{
1339 int i;
1340 1394
1395 /* FIXME: remember what ports we are using to better respond to this */
1396 return in_port;
1397 /*
1341 for (i = plugin->starting_port; i < plugin->num_ports + plugin->starting_port; i++) 1398 for (i = plugin->starting_port; i < plugin->num_ports + plugin->starting_port; i++)
1342 { 1399 {
1343 if (in_port == i) 1400 if (in_port == i)
@@ -1346,6 +1403,7 @@ check_port (struct Plugin *plugin, uint16_t in_port)
1346 1403
1347 return GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1404 return GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1348 plugin->num_ports) + plugin->starting_port; 1405 plugin->num_ports) + plugin->starting_port;
1406 */
1349} 1407}
1350 1408
1351 1409
@@ -1552,7 +1610,7 @@ libgnunet_plugin_transport_udp_nat_init (void *cls)
1552 1610
1553 GNUNET_CONFIGURATION_get_value_string (env->cfg, 1611 GNUNET_CONFIGURATION_get_value_string (env->cfg,
1554 "transport-udp-nat", 1612 "transport-udp-nat",
1555 "STARTING_PORT", 1613 "PORT",
1556 &starting_port); 1614 &starting_port);
1557 1615
1558 mtu = 1240; 1616 mtu = 1240;
@@ -1587,6 +1645,8 @@ libgnunet_plugin_transport_udp_nat_init (void *cls)
1587 1645
1588 plugin->service = service; 1646 plugin->service = service;
1589 1647
1648 plugin->random_starting_port = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000;
1649
1590 /* FIXME: do the two calls below periodically again and 1650 /* FIXME: do the two calls below periodically again and
1591 not just once (since the info we get might change...) */ 1651 not just once (since the info we get might change...) */
1592 GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); 1652 GNUNET_OS_network_interfaces_list (&process_interfaces, plugin);
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c
index 2db990e82..50bc02956 100644
--- a/src/transport/test_transport_api.c
+++ b/src/transport/test_transport_api.c
@@ -36,7 +36,7 @@
36#include "gnunet_transport_service.h" 36#include "gnunet_transport_service.h"
37#include "transport.h" 37#include "transport.h"
38 38
39#define VERBOSE GNUNET_YES 39#define VERBOSE GNUNET_NO
40 40
41#define VERBOSE_ARM GNUNET_NO 41#define VERBOSE_ARM GNUNET_NO
42 42
@@ -335,20 +335,83 @@ check ()
335 return ok; 335 return ok;
336} 336}
337 337
338
339static char *
340get_path_from_PATH ()
341{
342 char *path;
343 char *pos;
344 char *end;
345 char *buf;
346 const char *p;
347
348 p = getenv ("PATH");
349 if (p == NULL)
350 return NULL;
351 path = GNUNET_strdup (p); /* because we write on it */
352 buf = GNUNET_malloc (strlen (path) + 20);
353 pos = path;
354
355 while (NULL != (end = strchr (pos, ':')))
356 {
357 *end = '\0';
358 sprintf (buf, "%s/%s", pos, "gnunet-nat-server");
359 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
360 {
361 pos = GNUNET_strdup (buf);
362 GNUNET_free (buf);
363 GNUNET_free (path);
364 return pos;
365 }
366 pos = end + 1;
367 }
368 sprintf (buf, "%s/%s", pos, "gnunet-nat-server");
369 if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
370 {
371 pos = GNUNET_strdup (buf);
372 GNUNET_free (buf);
373 GNUNET_free (path);
374 return pos;
375 }
376 GNUNET_free (buf);
377 GNUNET_free (path);
378 return NULL;
379}
380
381
382static int check_gnunet_nat_server()
383{
384 struct stat statbuf;
385
386 stat(get_path_from_PATH(), &statbuf);
387 if ((statbuf.st_mode & S_ISUID) && (statbuf.st_uid == 0))
388 {
389 return GNUNET_YES;
390 }
391 else
392 {
393 return GNUNET_NO;
394 }
395}
396
338int 397int
339main (int argc, char *argv[]) 398main (int argc, char *argv[])
340{ 399{
341 int ret; 400 int ret;
342 401#ifdef MINGW
402 return GNUNET_SYSERR;
403#endif
343 if (strstr(argv[0], "tcp") != NULL) 404 if (strstr(argv[0], "tcp") != NULL)
344 { 405 {
345
346 is_tcp = GNUNET_YES; 406 is_tcp = GNUNET_YES;
347 } 407 }
348 else if (strstr(argv[0], "udp_nat") != NULL) 408 else if (strstr(argv[0], "udp_nat") != NULL)
349 { 409 {
350 fprintf(stderr, "this is a udp_nat test!\n");
351 is_udp_nat = GNUNET_YES; 410 is_udp_nat = GNUNET_YES;
411 if (check_gnunet_nat_server() == GNUNET_NO)
412 {
413 return GNUNET_SYSERR;
414 }
352 } 415 }
353 else if (strstr(argv[0], "udp") != NULL) 416 else if (strstr(argv[0], "udp") != NULL)
354 { 417 {
diff --git a/src/transport/test_transport_api_udp_nat_peer1.conf b/src/transport/test_transport_api_udp_nat_peer1.conf
index 56978a5d6..8bff71dee 100644
--- a/src/transport/test_transport_api_udp_nat_peer1.conf
+++ b/src/transport/test_transport_api_udp_nat_peer1.conf
@@ -1,8 +1,9 @@
1[transport-udp-nat] 1[transport-udp-nat]
2PORT = 12368 2PORT = 12368
3BEHIND_NAT = NO 3BEHIND_NAT = YES
4EXTERNAL_ADDRESS = 127.0.0.1 4EXTERNAL_ADDRESS = 127.0.0.1
5STARTING_PORT = 22222 5STARTING_PORT = 40000
6RANDOM_START_PORT = 50000
6 7
7[fs] 8[fs]
8ALLOW_SHUTDOWN = YES 9ALLOW_SHUTDOWN = YES
@@ -64,18 +65,18 @@ PORT = 2092
64 65
65[transport] 66[transport]
66PLUGINS = udp_nat 67PLUGINS = udp_nat
67DEBUG = YES 68#DEBUG = YES
68ALLOW_SHUTDOWN = YES 69ALLOW_SHUTDOWN = YES
69ACCEPT_FROM6 = ::1; 70ACCEPT_FROM6 = ::1;
70ACCEPT_FROM = 127.0.0.1; 71ACCEPT_FROM = 127.0.0.1;
71NEIGHBOUR_LIMIT = 50 72NEIGHBOUR_LIMIT = 50
72BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport 73BINARY = gnunet-service-transport
73CONFIG = $DEFAULTCONFIG 74CONFIG = $DEFAULTCONFIG
74HOME = $SERVICEHOME 75HOME = $SERVICEHOME
75HOSTNAME = localhost 76HOSTNAME = localhost
76PORT = 12365 77PORT = 12365
77#PREFIX = valgrind --track-origins=yes --leak-check=full --log-file=valgrind_udp_peer1.log 78#PREFIX = valgrind --track-origins=yes --leak-check=full --log-file=valgrind_udp_peer1.log
78PREFIX = xterm -e xterm -T transport -e gdb --args 79#PREFIX = xterm -e xterm -T transport -e gdb --args
79 80
80[peerinfo] 81[peerinfo]
81TRUST = $SERVICEHOME/data/credit/ 82TRUST = $SERVICEHOME/data/credit/
diff --git a/src/transport/test_transport_api_udp_nat_peer2.conf b/src/transport/test_transport_api_udp_nat_peer2.conf
index d0dbe9653..d7284cc56 100644
--- a/src/transport/test_transport_api_udp_nat_peer2.conf
+++ b/src/transport/test_transport_api_udp_nat_peer2.conf
@@ -2,7 +2,8 @@
2PORT = 22368 2PORT = 22368
3BEHIND_NAT = YES 3BEHIND_NAT = YES
4EXTERNAL_ADDRESS = 127.0.0.1 4EXTERNAL_ADDRESS = 127.0.0.1
5STARTING_PORT = 22222 5STARTING_PORT = 50000
6RANDOM_START_PORT = 40000
6 7
7[fs] 8[fs]
8ALLOW_SHUTDOWN = YES 9ALLOW_SHUTDOWN = YES
@@ -64,18 +65,18 @@ PORT = 2092
64 65
65[transport] 66[transport]
66PLUGINS = udp_nat 67PLUGINS = udp_nat
67DEBUG = YES 68#DEBUG = YES
68PREFIX = 69PREFIX =
69ALLOW_SHUTDOWN = YES 70ALLOW_SHUTDOWN = YES
70ACCEPT_FROM6 = ::1; 71ACCEPT_FROM6 = ::1;
71ACCEPT_FROM = 127.0.0.1; 72ACCEPT_FROM = 127.0.0.1;
72NEIGHBOUR_LIMIT = 50 73NEIGHBOUR_LIMIT = 50
73BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport 74BINARY = gnunet-service-transport
74CONFIG = $DEFAULTCONFIG 75CONFIG = $DEFAULTCONFIG
75HOME = $SERVICEHOME 76HOME = $SERVICEHOME
76HOSTNAME = localhost 77HOSTNAME = localhost
77PORT = 22365 78PORT = 22365
78PREFIX = xterm -e xterm -T transport -e gdb --args 79#PREFIX = xterm -e xterm -T transport -e gdb --args
79 80
80[peerinfo] 81[peerinfo]
81TRUST = $SERVICEHOME/data/credit/ 82TRUST = $SERVICEHOME/data/credit/