From 84ac615276e428c6d941aa83dbd99f63d8b08865 Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Tue, 17 Aug 2010 16:35:47 +0000 Subject: [PATCH] fixing tcp nat implementation, WINDOWS SUPPORT NOTWITHSTANDING --- src/transport/gnunet-service-transport.c | 75 ++++++++++++++++++++---- src/transport/plugin_transport_tcp.c | 31 +++++++--- 2 files changed, 89 insertions(+), 17 deletions(-) diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index a9a06ac77..03543f23d 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -2696,6 +2696,10 @@ add_hello_for_peer (void *cls, if (peer == NULL) { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + -1, + GNUNET_NO); n->piter = NULL; return; } @@ -2777,6 +2781,14 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer, &neighbour_timeout_task, n); if (do_hello) { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# peerinfo iterate requests"), + 1, + GNUNET_NO); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + 1, + GNUNET_NO); n->piter = GNUNET_PEERINFO_iterate (peerinfo, peer, GNUNET_TIME_UNIT_FOREVER_REL, &add_hello_for_peer, n); @@ -3370,13 +3382,19 @@ handle_payload_message (const struct GNUNET_MessageHeader *message, msize = ntohs (message->size); if (n->received_pong == GNUNET_NO) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received message of type %u and size %u from `%4s', but no pong yet!!\n", + ntohs (message->type), + ntohs (message->size), + GNUNET_i2s (&n->id)); GNUNET_free_non_null (n->pre_connect_message_buffer); n->pre_connect_message_buffer = GNUNET_malloc (msize); memcpy (n->pre_connect_message_buffer, message, msize); return; } + #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received message of type %u and size %u from `%4s', sending to all clients.\n", ntohs (message->type), ntohs (message->size), @@ -3468,7 +3486,7 @@ check_pending_validation (void *cls, addr = (const char*) &pong[1]; slen = strlen (ve->transport_name) + 1; if ( (ps - sizeof (struct TransportPongMessage) != ve->addrlen + slen) || - (ve->challenge != challenge) || + (ve->challenge != challenge) || (addr[slen-1] != '\0') || (0 != strcmp (addr, ve->transport_name)) || (ntohl (pong->purpose.size) @@ -3476,7 +3494,10 @@ check_pending_validation (void *cls, sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + sizeof (struct GNUNET_PeerIdentity) + ve->addrlen + slen) ) - return GNUNET_YES; + { + return GNUNET_YES; + } + alen = ps - sizeof (struct TransportPongMessage) - slen; switch (ntohl (pong->purpose.purpose)) { @@ -3485,7 +3506,9 @@ check_pending_validation (void *cls, (0 != memcmp (&addr[slen], ve->addr, ve->addrlen)) ) - return GNUNET_YES; /* different entry, keep trying! */ + { + return GNUNET_YES; /* different entry, keep trying! */ + } if (0 != memcmp (&pong->pid, key, sizeof (struct GNUNET_PeerIdentity))) @@ -3502,6 +3525,13 @@ check_pending_validation (void *cls, GNUNET_break_op (0); return GNUNET_NO; } + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", + GNUNET_h2s (key), + a2s (ve->transport_name, + (const struct sockaddr *) ve->addr, + ve->addrlen), + ve->transport_name); #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", @@ -3514,7 +3544,9 @@ check_pending_validation (void *cls, break; case GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING: if (ve->addrlen != 0) - return GNUNET_YES; /* different entry, keep trying */ + { + return GNUNET_YES; /* different entry, keep trying */ + } if ( (0 != memcmp (&pong->pid, &my_identity, sizeof (struct GNUNET_PeerIdentity))) || @@ -3541,7 +3573,7 @@ check_pending_validation (void *cls, } if (oal == NULL) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Not accepting PONG with address `%s' since I cannot confirm having this address.\n"), a2s (ve->transport_name, &addr[slen], @@ -3557,6 +3589,7 @@ check_pending_validation (void *cls, GNUNET_break_op (0); return GNUNET_NO; } + #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Confirmed that peer `%4s' is talking to us using address `%s' (%s) for us.\n", @@ -3961,6 +3994,10 @@ check_hello_validated (void *cls, if (peer == NULL) { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + -1, + GNUNET_NO); chvc->piter = NULL; if (GNUNET_NO == chvc->hello_known) { @@ -4161,6 +4198,14 @@ process_hello (struct TransportPlugin *plugin, chvc); /* finally, check if HELLO was previously validated (continuation will then schedule actual validation) */ + GNUNET_STATISTICS_update (stats, + gettext_noop ("# peerinfo iterate requests"), + 1, + GNUNET_NO); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + 1, + GNUNET_NO); chvc->piter = GNUNET_PEERINFO_iterate (peerinfo, &target, HELLO_VERIFICATION_TIMEOUT, @@ -4297,6 +4342,10 @@ disconnect_neighbour (struct NeighbourList *n, int check) if (n->piter != NULL) { GNUNET_PEERINFO_iterate_cancel (n->piter); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + -1, + GNUNET_NO); n->piter = NULL; } /* finally, free n itself */ @@ -4590,7 +4639,6 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, uint16_t msize; struct NeighbourList *n; struct GNUNET_TIME_Relative ret; - if (is_blacklisted (peer, plugin)) return GNUNET_TIME_UNIT_FOREVER_REL; @@ -4653,6 +4701,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_NO); return GNUNET_CONSTANTS_QUOTA_VIOLATION_TIMEOUT; } + #if DEBUG_PING_PONG GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u and size %u from `%4s', sending to all clients.\n", @@ -4683,7 +4732,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, ret = GNUNET_BANDWIDTH_tracker_get_delay (&n->in_tracker, 0); if (ret.value > 0) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling read (%llu bytes excess at %u b/s), waiting %llums before reading more.\n", (unsigned long long) n->in_tracker.consumption_since_last_update__, (unsigned int) n->in_tracker.available_bytes_per_s__, @@ -4952,7 +5001,7 @@ handle_set_quota (void *cls, qsm->quota); if (0 == ntohl (qsm->quota.value__)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n", GNUNET_i2s(&n->id), "SET_QUOTA"); disconnect_neighbour (n, GNUNET_NO); @@ -5258,7 +5307,13 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { chvc_head = chvc->next; if (chvc->piter != NULL) - GNUNET_PEERINFO_iterate_cancel (chvc->piter); + { + GNUNET_PEERINFO_iterate_cancel (chvc->piter); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# outstanding peerinfo iterate requests"), + -1, + GNUNET_NO); + } else GNUNET_break (0); GNUNET_assert (chvc->ve_count == 0); diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 5e9e2b80c..a872ecd3b 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -935,6 +935,7 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen) char *port_as_string; pid_t pid; const struct sockaddr *sa = (const struct sockaddr *)addr; + #if DEBUG_TCP_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("called run_gnunet_nat_client addrlen %d others are %d and %d\n"), addrlen, sizeof (struct sockaddr), sizeof (struct sockaddr_in)); @@ -1187,7 +1188,7 @@ tcp_plugin_send (void *cls, GNUNET_i2s (target), GNUNET_a2s (sb, sbs)); #endif - run_gnunet_nat_client(plugin, sb, sbs); + run_gnunet_nat_client (plugin, sb, sbs); return 0; } else if ((plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) @@ -1541,7 +1542,7 @@ handle_tcp_nat_probe (void *cls, struct IPv6TcpAddress *t6; const struct sockaddr_in *s4; const struct sockaddr_in6 *s6; - + static struct GNUNET_MessageHeader fake_pong; #if DEBUG_TCP_NAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received tcp NAT probe\n"); #endif @@ -1572,7 +1573,12 @@ handle_tcp_nat_probe (void *cls, GNUNET_SERVER_client_keep (client); session->client = client; session->last_activity = GNUNET_TIME_absolute_get (); - + /* FIXME: Should this be inbound or outbound? + * I think it should be outbound because we technically + * initiated it... But something goes wrong somewhere. */ + /* session->inbound = GNUNET_YES; */ + //session->inbound = GNUNET_YES; + //session->expecting_welcome = GNUNET_NO; if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) { @@ -1611,7 +1617,12 @@ handle_tcp_nat_probe (void *cls, } GNUNET_free (vaddr); } - + fake_pong.size = sizeof(struct GNUNET_MessageHeader); + fake_pong.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); + plugin->env->receive(session->plugin->env->cls, &session->target, &fake_pong, 1, session, session->connect_addr, session->connect_alen); +#if DEBUG_TCP_NAT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Giving fake pong to transport service so hopefully it will schedule validation of THIS address!\n"); +#endif session->next = plugin->sessions; plugin->sessions = session; GNUNET_STATISTICS_update (plugin->env->stats, @@ -1626,6 +1637,8 @@ handle_tcp_nat_probe (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Did NOT find session for NAT probe!\n"); #endif } + + GNUNET_SERVER_receive_done (client, GNUNET_OK); } /** @@ -1651,7 +1664,6 @@ handle_tcp_welcome (void *cls, const struct sockaddr_in *s4; const struct sockaddr_in6 *s6; - #if DEBUG_TCP GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %s message from a `%4s/%p'.\n", @@ -2088,6 +2100,8 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc */ sock = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, AF_INET, (struct sockaddr *)&in_addr, sizeof(in_addr)); + + if (sock == NULL) { plugin->server_read_task = @@ -2098,10 +2112,10 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc } else { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending TCP probe message!\n"), &mybuf, port); - tcp_probe_ctx = GNUNET_malloc(sizeof(struct TCPProbeContext)); + tcp_probe_ctx = GNUNET_malloc(sizeof(struct TCPProbeContext)); tcp_probe_ctx->message.header.size = htons(sizeof(struct TCP_NAT_ProbeMessage)); tcp_probe_ctx->message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE); memcpy(&tcp_probe_ctx->message.clientIdentity, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)); @@ -2114,6 +2128,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc } + /*GNUNET_SERVER_connect_socket(plugin->server, sock);*/ plugin->server_read_task = GNUNET_SCHEDULER_add_read_file (plugin->env->sched, GNUNET_TIME_UNIT_FOREVER_REL, @@ -2456,6 +2471,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of address %s:0\n", plugin->external_address); t4.t_port = htons(0); + add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); plugin->env->notify_address (plugin->env->cls, "tcp", &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); @@ -2463,6 +2479,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, plugin->external_address, &t4.ipv4_addr) == 1)) { t4.t_port = htons(plugin->adv_port); + add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); plugin->env->notify_address (plugin->env->cls, "tcp", &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); -- 2.25.1