aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_tcp.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-02-16 11:54:12 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-02-16 11:54:12 +0000
commite686141383bfc85a709d125f6d37d23918937028 (patch)
tree610904ca7be7977afc51114a112d671468fc2c64 /src/transport/plugin_transport_tcp.c
parent6788139a93a9f114971c3702bb449158f1f87746 (diff)
downloadgnunet-e686141383bfc85a709d125f6d37d23918937028.tar.gz
gnunet-e686141383bfc85a709d125f6d37d23918937028.zip
- fixing assertion in gnunet_service_ats_addresses
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r--src/transport/plugin_transport_tcp.c356
1 files changed, 195 insertions, 161 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index 325ebaf8b..83db537fc 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -270,19 +270,22 @@ struct Session
270 /** 270 /**
271 * Address of the other peer (either based on our 'connect' 271 * Address of the other peer (either based on our 'connect'
272 * call or on our 'accept' call). 272 * call or on our 'accept' call).
273 *
274 * struct IPv4TcpAddress or struct IPv6TcpAddress
275 *
273 */ 276 */
274 void *connect_addr; 277 void *addr;
275 278
276 /** 279 /**
277 * Last activity on this connection. Used to select preferred 280 * Length of connect_addr.
278 * connection.
279 */ 281 */
280 struct GNUNET_TIME_Absolute last_activity; 282 size_t addrlen;
281 283
282 /** 284 /**
283 * Length of connect_addr. 285 * Last activity on this connection. Used to select preferred
286 * connection.
284 */ 287 */
285 size_t connect_alen; 288 struct GNUNET_TIME_Absolute last_activity;
286 289
287 /** 290 /**
288 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO) 291 * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
@@ -326,11 +329,6 @@ struct Plugin
326 */ 329 */
327 struct GNUNET_NAT_Handle *nat; 330 struct GNUNET_NAT_Handle *nat;
328 331
329 /**
330 * List of open TCP sessions.
331 */
332 struct Session *sessions;
333
334 struct GNUNET_CONTAINER_MultiHashMap * sessionmap; 332 struct GNUNET_CONTAINER_MultiHashMap * sessionmap;
335 333
336 /** 334 /**
@@ -527,6 +525,27 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
527} 525}
528 526
529 527
528struct SessionClientCtx
529{
530 const struct GNUNET_SERVER_Client *client;
531 struct Session *ret;
532};
533
534int session_lookup_by_client_it (void *cls,
535 const GNUNET_HashCode * key,
536 void *value)
537{
538 struct SessionClientCtx *sc_ctx = cls;
539 struct Session *s = value;
540
541 if (s->client == sc_ctx->client)
542 {
543 sc_ctx->ret = s;
544 return GNUNET_NO;
545 }
546 return GNUNET_YES;
547}
548
530/** 549/**
531 * Find the session handle for the given client. 550 * Find the session handle for the given client.
532 * 551 *
@@ -535,15 +554,16 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
535 * @return NULL if no matching session exists 554 * @return NULL if no matching session exists
536 */ 555 */
537static struct Session * 556static struct Session *
538find_session_by_client (struct Plugin *plugin, 557lookup_session_by_client (struct Plugin *plugin,
539 const struct GNUNET_SERVER_Client *client) 558 const struct GNUNET_SERVER_Client *client)
540{ 559{
541 struct Session *ret; 560 struct SessionClientCtx sc_ctx;
561 sc_ctx.client = client;
562 sc_ctx.ret = NULL;
542 563
543 ret = plugin->sessions; 564 GNUNET_CONTAINER_multihashmap_iterate (plugin->sessionmap, &session_lookup_by_client_it, &sc_ctx);
544 while ((ret != NULL) && (client != ret->client)) 565
545 ret = ret->next; 566 return sc_ctx.ret;
546 return ret;
547} 567}
548 568
549 569
@@ -570,20 +590,15 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
570 GNUNET_assert (client != NULL); 590 GNUNET_assert (client != NULL);
571 else 591 else
572 GNUNET_assert (client == NULL); 592 GNUNET_assert (client == NULL);
573#if DEBUG_TCP 593
574 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 594 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
575 "Creating new session for peer `%4s'\n", 595 "Creating new session for peer `%4s'\n",
576 GNUNET_i2s (target)); 596 GNUNET_i2s (target));
577#endif 597
578 ret = GNUNET_malloc (sizeof (struct Session)); 598 ret = GNUNET_malloc (sizeof (struct Session));
579 ret->last_activity = GNUNET_TIME_absolute_get (); 599 ret->last_activity = GNUNET_TIME_absolute_get ();
580 ret->plugin = plugin; 600 ret->plugin = plugin;
581 ret->is_nat = is_nat; 601 ret->is_nat = is_nat;
582 if (is_nat != GNUNET_YES) /* If not a NAT WAIT conn, add it to global list */
583 {
584 ret->next = plugin->sessions;
585 plugin->sessions = ret;
586 }
587 ret->client = client; 602 ret->client = client;
588 ret->target = *target; 603 ret->target = *target;
589 ret->expecting_welcome = GNUNET_YES; 604 ret->expecting_welcome = GNUNET_YES;
@@ -783,32 +798,16 @@ process_pending_messages (struct Session *session)
783static void 798static void
784disconnect_session (struct Session *session) 799disconnect_session (struct Session *session)
785{ 800{
786 struct Session *prev;
787 struct Session *pos;
788 struct PendingMessage *pm; 801 struct PendingMessage *pm;
802 struct Plugin * plugin = session->plugin;
789 803
790#if DEBUG_TCP
791 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 804 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
792 "Disconnecting from `%4s' at %s.\n", 805 "Disconnecting session %p for peer `%s' address `%s'\n",
806 session,
793 GNUNET_i2s (&session->target), 807 GNUNET_i2s (&session->target),
794 (session->connect_addr != 808 tcp_address_to_string(NULL, session->addr, session->addrlen));
795 NULL) ? tcp_address_to_string (session->plugin, 809
796 session->connect_addr, 810 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap, &session->target.hashPubKey, session));
797 session->connect_alen) :
798 "*");
799#endif
800 /* remove from session list */
801 prev = NULL;
802 pos = session->plugin->sessions;
803 while (pos != session)
804 {
805 prev = pos;
806 pos = pos->next;
807 }
808 if (prev == NULL)
809 session->plugin->sessions = session->next;
810 else
811 prev->next = session->next;
812 811
813 /* clean up state */ 812 /* clean up state */
814 if (session->transmit_handle != NULL) 813 if (session->transmit_handle != NULL)
@@ -856,7 +855,7 @@ disconnect_session (struct Session *session)
856 GNUNET_STATISTICS_update (session->plugin->env->stats, 855 GNUNET_STATISTICS_update (session->plugin->env->stats,
857 gettext_noop ("# TCP sessions active"), -1, 856 gettext_noop ("# TCP sessions active"), -1,
858 GNUNET_NO); 857 GNUNET_NO);
859 GNUNET_free_non_null (session->connect_addr); 858 GNUNET_free_non_null (session->addr);
860 GNUNET_assert (NULL == session->transmit_handle); 859 GNUNET_assert (NULL == session->transmit_handle);
861 GNUNET_free (session); 860 GNUNET_free (session);
862} 861}
@@ -921,11 +920,11 @@ tcp_plugin_send (void *cls,
921 /* append pm to pending_messages list */ 920 /* append pm to pending_messages list */
922 GNUNET_CONTAINER_DLL_insert_tail (session->pending_messages_head, 921 GNUNET_CONTAINER_DLL_insert_tail (session->pending_messages_head,
923 session->pending_messages_tail, pm); 922 session->pending_messages_tail, pm);
924#if DEBUG_TCP 923
925 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 924 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
926 "Asked to transmit %u bytes to `%s', added message to list.\n", 925 "Asked to transmit %u bytes to `%s', added message to list.\n",
927 msgbuf_size, GNUNET_i2s (&session->target)); 926 msgbuf_size, GNUNET_i2s (&session->target));
928#endif 927
929 process_pending_messages (session); 928 process_pending_messages (session);
930 return msgbuf_size; 929 return msgbuf_size;
931} 930}
@@ -937,18 +936,44 @@ struct SessionItCtx
937 struct Session * result; 936 struct Session * result;
938}; 937};
939 938
940int session_it (void *cls, 939int session_lookup_it (void *cls,
941 const GNUNET_HashCode * key, 940 const GNUNET_HashCode * key,
942 void *value) 941 void *value)
943{ 942{
944 struct SessionItCtx * si_ctx = cls; 943 struct SessionItCtx * si_ctx = cls;
945 struct Session * session = value; 944 struct Session * session = value;
946 945#if 0
947 if (session->connect_alen != si_ctx->addrlen) 946 char * a1 = strdup (tcp_address_to_string(NULL, session->addr, session->addrlen));
947 char * a2 = strdup (tcp_address_to_string(NULL, si_ctx->addr, si_ctx->addrlen));
948 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp",
949 "Comparing: %s %u <-> %s %u\n",
950 a1,
951 session->addrlen,
952 a2,
953 si_ctx->addrlen);
954 GNUNET_free (a1);
955 GNUNET_free (a2);
956#endif
957 if (session->addrlen != si_ctx->addrlen)
958 {
948 return GNUNET_YES; 959 return GNUNET_YES;
949 if (0 != memcmp (&session->connect_addr, si_ctx->addr, si_ctx->addrlen)) 960 }
961 if (0 != memcmp (session->addr, si_ctx->addr, si_ctx->addrlen))
962 {
950 return GNUNET_YES; 963 return GNUNET_YES;
951 964 }
965#if 0
966 a1 = strdup (tcp_address_to_string(NULL, session->addr, session->addrlen));
967 a2 = strdup (tcp_address_to_string(NULL, si_ctx->addr, si_ctx->addrlen));
968 GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "tcp",
969 "Comparing: %s %u <-> %s %u , OK!\n",
970 a1,
971 session->addrlen,
972 a2,
973 si_ctx->addrlen);
974 GNUNET_free (a1);
975 GNUNET_free (a2);
976#endif
952 /* Found existing session */ 977 /* Found existing session */
953 si_ctx->result = session; 978 si_ctx->result = session;
954 return GNUNET_NO; 979 return GNUNET_NO;
@@ -987,12 +1012,33 @@ tcp_plugin_get_session (void *cls,
987 1012
988 addrlen = address->address_length; 1013 addrlen = address->address_length;
989 1014
990#if DEBUG_TCP
991 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1015 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
992 "Trying to get session for `%s' address length %i\n", 1016 "Trying to get session for `%s' address length %i\n",
993 tcp_address_to_string(NULL, address->address, address->address_length), 1017 tcp_address_to_string(NULL, address->address, address->address_length),
994 addrlen); 1018 addrlen);
995#endif 1019
1020 /* look for existing session */
1021 if (GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, &address->peer.hashPubKey))
1022 {
1023 struct SessionItCtx si_ctx;
1024
1025 si_ctx.addr = (void *) address->address;
1026 si_ctx.addrlen = address->address_length;
1027
1028 si_ctx.result = NULL;
1029
1030 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, &address->peer.hashPubKey, &session_lookup_it, &si_ctx);
1031 if (si_ctx.result != NULL)
1032 {
1033 session = si_ctx.result;
1034 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1035 "Found exisiting session for `%s' address `%s' session %p\n",
1036 GNUNET_i2s (&address->peer),
1037 tcp_address_to_string(NULL, address->address, address->address_length),
1038 session);
1039 return session;
1040 }
1041 }
996 1042
997 if (addrlen == sizeof (struct IPv6TcpAddress)) 1043 if (addrlen == sizeof (struct IPv6TcpAddress))
998 { 1044 {
@@ -1036,21 +1082,6 @@ tcp_plugin_get_session (void *cls,
1036 return NULL; 1082 return NULL;
1037 } 1083 }
1038 1084
1039 /* look for existing session */
1040 if (GNUNET_CONTAINER_multihashmap_contains(plugin->sessionmap, &address->peer.hashPubKey))
1041 {
1042 struct SessionItCtx si_ctx;
1043 si_ctx.addr = &sbs;
1044 si_ctx.addrlen = sbs;
1045 si_ctx.result = NULL;
1046 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, &address->peer.hashPubKey, &session_it, &si_ctx);
1047 if (si_ctx.result != NULL)
1048 {
1049 session = si_ctx.result;
1050 return session;
1051 }
1052 }
1053
1054 if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) 1085 if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress)))
1055 return NULL; /* NAT client only works with IPv4 addresses */ 1086 return NULL; /* NAT client only works with IPv4 addresses */
1056 1087
@@ -1073,6 +1104,8 @@ tcp_plugin_get_session (void *cls,
1073 _("Found valid IPv4 NAT address (creating session)!\n")); 1104 _("Found valid IPv4 NAT address (creating session)!\n"));
1074#endif 1105#endif
1075 session = create_session (plugin, &address->peer, NULL, GNUNET_YES); 1106 session = create_session (plugin, &address->peer, NULL, GNUNET_YES);
1107 session->addrlen = 0;
1108 session->addr = NULL;
1076 GNUNET_assert (session != NULL); 1109 GNUNET_assert (session != NULL);
1077 1110
1078 GNUNET_assert (GNUNET_CONTAINER_multihashmap_put 1111 GNUNET_assert (GNUNET_CONTAINER_multihashmap_put
@@ -1100,18 +1133,18 @@ tcp_plugin_get_session (void *cls,
1100 return NULL; 1133 return NULL;
1101 } 1134 }
1102 plugin->max_connections--; 1135 plugin->max_connections--;
1103#if DEBUG_TCP_NAT 1136
1104 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1137 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1105 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", 1138 "Asked to transmit to `%4s', creating fresh session using address `%s'.\n",
1106 GNUNET_i2s (&session->target), GNUNET_a2s (sb, sbs)); 1139 GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs));
1107#endif 1140
1108 session = create_session (plugin, 1141 session = create_session (plugin,
1109 &address->peer, 1142 &address->peer,
1110 GNUNET_SERVER_connect_socket (plugin->server, sa), 1143 GNUNET_SERVER_connect_socket (plugin->server, sa),
1111 GNUNET_NO); 1144 GNUNET_NO);
1112 session->connect_addr = GNUNET_malloc (addrlen); 1145 session->addr = GNUNET_malloc (addrlen);
1113 memcpy (session->connect_addr, address->address, addrlen); 1146 memcpy (session->addr, address->address, addrlen);
1114 session->connect_alen = addrlen; 1147 session->addrlen = addrlen;
1115 if (addrlen != 0) 1148 if (addrlen != 0)
1116 { 1149 {
1117 struct GNUNET_ATS_Information ats; 1150 struct GNUNET_ATS_Information ats;
@@ -1123,6 +1156,12 @@ tcp_plugin_get_session (void *cls,
1123 1156
1124 GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &address->peer.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 1157 GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &address->peer.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1125 1158
1159 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1160 "Creating new session for `%s' address `%s' session %p\n",
1161 GNUNET_i2s (&address->peer),
1162 tcp_address_to_string(NULL, address->address, address->address_length),
1163 session);
1164
1126 /* Send TCP Welcome */ 1165 /* Send TCP Welcome */
1127 process_pending_messages (session); 1166 process_pending_messages (session);
1128 1167
@@ -1130,6 +1169,20 @@ tcp_plugin_get_session (void *cls,
1130} 1169}
1131 1170
1132 1171
1172int session_disconnect_it (void *cls,
1173 const GNUNET_HashCode * key,
1174 void *value)
1175{
1176 struct Session *session = value;
1177
1178 GNUNET_STATISTICS_update (session->plugin->env->stats,
1179 gettext_noop
1180 ("# transport-service disconnect requests for TCP"),
1181 1, GNUNET_NO);
1182 disconnect_session (session);
1183 return GNUNET_YES;
1184}
1185
1133/** 1186/**
1134 * Function that can be called to force a disconnect from the 1187 * Function that can be called to force a disconnect from the
1135 * specified neighbour. This should also cancel all previously 1188 * specified neighbour. This should also cancel all previously
@@ -1150,34 +1203,11 @@ static void
1150tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 1203tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
1151{ 1204{
1152 struct Plugin *plugin = cls; 1205 struct Plugin *plugin = cls;
1153 struct Session *session;
1154 struct Session *next;
1155 struct PendingMessage *pm;
1156 1206
1157#if DEBUG_TCP
1158 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1207 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1159 "Asked to cancel session with `%4s'\n", GNUNET_i2s (target)); 1208 "Disconnecting peer `%4s'\n", GNUNET_i2s (target));
1160#endif 1209
1161 next = plugin->sessions; 1210 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessionmap, &target->hashPubKey, session_disconnect_it, plugin);
1162 while (NULL != (session = next))
1163 {
1164 next = session->next;
1165 if (0 !=
1166 memcmp (target, &session->target, sizeof (struct GNUNET_PeerIdentity)))
1167 continue;
1168 pm = session->pending_messages_head;
1169 while (pm != NULL)
1170 {
1171 pm->transmit_cont = NULL;
1172 pm->transmit_cont_cls = NULL;
1173 pm = pm->next;
1174 }
1175 GNUNET_STATISTICS_update (session->plugin->env->stats,
1176 gettext_noop
1177 ("# transport-service disconnect requests for TCP"),
1178 1, GNUNET_NO);
1179 disconnect_session (session);
1180 }
1181} 1211}
1182 1212
1183 1213
@@ -1466,16 +1496,16 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client,
1466 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1496 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1467 t4->t4_port = s4->sin_port; 1497 t4->t4_port = s4->sin_port;
1468 t4->ipv4_addr = s4->sin_addr.s_addr; 1498 t4->ipv4_addr = s4->sin_addr.s_addr;
1469 session->connect_addr = t4; 1499 session->addr = t4;
1470 session->connect_alen = sizeof (struct IPv4TcpAddress); 1500 session->addrlen = sizeof (struct IPv4TcpAddress);
1471 break; 1501 break;
1472 case AF_INET6: 1502 case AF_INET6:
1473 s6 = vaddr; 1503 s6 = vaddr;
1474 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1504 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1475 t6->t6_port = s6->sin6_port; 1505 t6->t6_port = s6->sin6_port;
1476 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr)); 1506 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1477 session->connect_addr = t6; 1507 session->addr = t6;
1478 session->connect_alen = sizeof (struct IPv6TcpAddress); 1508 session->addrlen = sizeof (struct IPv6TcpAddress);
1479 break; 1509 break;
1480 default: 1510 default:
1481 GNUNET_break_op (0); 1511 GNUNET_break_op (0);
@@ -1491,8 +1521,8 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client,
1491 } 1521 }
1492 GNUNET_free (vaddr); 1522 GNUNET_free (vaddr);
1493 1523
1494 session->next = plugin->sessions; 1524 GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &session->target.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1495 plugin->sessions = session; 1525
1496 GNUNET_STATISTICS_update (plugin->env->stats, 1526 GNUNET_STATISTICS_update (plugin->env->stats,
1497 gettext_noop ("# TCP sessions active"), 1, 1527 gettext_noop ("# TCP sessions active"), 1,
1498 GNUNET_NO); 1528 GNUNET_NO);
@@ -1531,42 +1561,42 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1531 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1561 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1532 return; 1562 return;
1533 } 1563 }
1534#if DEBUG_TCP 1564
1535 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1565 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1536 "Received %s message from `%4s'.\n", "WELCOME", 1566 "Received %s message from `%4s'\n", "WELCOME",
1537 GNUNET_i2s (&wm->clientIdentity)); 1567 GNUNET_i2s (&wm->clientIdentity));
1538#endif
1539 GNUNET_STATISTICS_update (plugin->env->stats, 1568 GNUNET_STATISTICS_update (plugin->env->stats,
1540 gettext_noop ("# TCP WELCOME messages received"), 1, 1569 gettext_noop ("# TCP WELCOME messages received"), 1,
1541 GNUNET_NO); 1570 GNUNET_NO);
1542 session = find_session_by_client (plugin, client);
1543 1571
1544 if (session == NULL) 1572 session = lookup_session_by_client (plugin, client);
1573 if (session != NULL)
1545 { 1574 {
1546#if DEBUG_TCP_NAT
1547 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1548 "Received %s message from a `%4s', creating new session\n",
1549 "WELCOME", GNUNET_i2s (&wm->clientIdentity));
1550#endif
1551 GNUNET_SERVER_client_keep (client);
1552 session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO);
1553 session->inbound = GNUNET_YES;
1554 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) 1575 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1555 { 1576 {
1556#if DEBUG_TCP_NAT
1557 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1577 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1558 "Found address `%s' for incoming connection\n", 1578 "Found existing session %p for peer `%s'\n",
1579 session,
1559 GNUNET_a2s (vaddr, alen)); 1580 GNUNET_a2s (vaddr, alen));
1560#endif 1581 GNUNET_free (vaddr);
1582 }
1583 }
1584 else
1585 {
1586 GNUNET_SERVER_client_keep (client);
1587 session = create_session (plugin, &wm->clientIdentity, client, GNUNET_NO);
1588 session->inbound = GNUNET_YES;
1561 1589
1590 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1591 {
1562 if (alen == sizeof (struct sockaddr_in)) 1592 if (alen == sizeof (struct sockaddr_in))
1563 { 1593 {
1564 s4 = vaddr; 1594 s4 = vaddr;
1565 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1595 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1566 t4->t4_port = s4->sin_port; 1596 t4->t4_port = s4->sin_port;
1567 t4->ipv4_addr = s4->sin_addr.s_addr; 1597 t4->ipv4_addr = s4->sin_addr.s_addr;
1568 session->connect_addr = t4; 1598 session->addr = t4;
1569 session->connect_alen = sizeof (struct IPv4TcpAddress); 1599 session->addrlen = sizeof (struct IPv4TcpAddress);
1570 } 1600 }
1571 else if (alen == sizeof (struct sockaddr_in6)) 1601 else if (alen == sizeof (struct sockaddr_in6))
1572 { 1602 {
@@ -1574,8 +1604,8 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1574 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1604 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1575 t6->t6_port = s6->sin6_port; 1605 t6->t6_port = s6->sin6_port;
1576 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr)); 1606 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1577 session->connect_addr = t6; 1607 session->addr = t6;
1578 session->connect_alen = sizeof (struct IPv6TcpAddress); 1608 session->addrlen = sizeof (struct IPv6TcpAddress);
1579 } 1609 }
1580 1610
1581 struct GNUNET_ATS_Information ats; 1611 struct GNUNET_ATS_Information ats;
@@ -1591,19 +1621,7 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1591 "Did not obtain TCP socket address for incoming connection\n"); 1621 "Did not obtain TCP socket address for incoming connection\n");
1592#endif 1622#endif
1593 } 1623 }
1594 process_pending_messages (session); 1624 GNUNET_CONTAINER_multihashmap_put(plugin->sessionmap, &wm->clientIdentity.hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
1595 }
1596 else
1597 {
1598#if DEBUG_TCP_NAT
1599 if (GNUNET_OK == GNUNET_SERVER_client_get_address (client, &vaddr, &alen))
1600 {
1601 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1602 "Found address `%s' (already have session)\n",
1603 GNUNET_a2s (vaddr, alen));
1604 GNUNET_free (vaddr);
1605 }
1606#endif
1607 } 1625 }
1608 1626
1609 if (session->expecting_welcome != GNUNET_YES) 1627 if (session->expecting_welcome != GNUNET_YES)
@@ -1614,6 +1632,10 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1614 } 1632 }
1615 session->last_activity = GNUNET_TIME_absolute_get (); 1633 session->last_activity = GNUNET_TIME_absolute_get ();
1616 session->expecting_welcome = GNUNET_NO; 1634 session->expecting_welcome = GNUNET_NO;
1635
1636
1637 process_pending_messages (session);
1638
1617 GNUNET_SERVER_client_set_timeout (client, 1639 GNUNET_SERVER_client_set_timeout (client,
1618 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 1640 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1619 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1641 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -1672,20 +1694,30 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client,
1672 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1694 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1673 return; 1695 return;
1674 } 1696 }
1675 session = find_session_by_client (plugin, client); 1697 session = lookup_session_by_client (plugin, client);
1676 if ((NULL == session) || (GNUNET_YES == session->expecting_welcome)) 1698 if (NULL == session)
1677 { 1699 {
1700 /* No inbound session found */
1701 GNUNET_break_op (0);
1702 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1703 return;
1704 }
1705 else if (GNUNET_YES == session->expecting_welcome)
1706 {
1707 /* Session is expecting WELCOME message */
1708 GNUNET_break_op (0);
1678 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1709 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1679 return; 1710 return;
1680 } 1711 }
1712
1681 session->last_activity = GNUNET_TIME_absolute_get (); 1713 session->last_activity = GNUNET_TIME_absolute_get ();
1682#if DEBUG_TCP 1714
1683 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1715 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1684 "Passing %u bytes of type %u from `%4s' to transport service.\n", 1716 "Passing %u bytes of type %u from `%4s' to transport service.\n",
1685 (unsigned int) ntohs (message->size), 1717 (unsigned int) ntohs (message->size),
1686 (unsigned int) ntohs (message->type), 1718 (unsigned int) ntohs (message->type),
1687 GNUNET_i2s (&session->target)); 1719 GNUNET_i2s (&session->target));
1688#endif 1720
1689 GNUNET_STATISTICS_update (plugin->env->stats, 1721 GNUNET_STATISTICS_update (plugin->env->stats,
1690 gettext_noop ("# bytes received via TCP"), 1722 gettext_noop ("# bytes received via TCP"),
1691 ntohs (message->size), GNUNET_NO); 1723 ntohs (message->size), GNUNET_NO);
@@ -1697,14 +1729,13 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client,
1697 distance[1].value = session->ats_address_network_type; 1729 distance[1].value = session->ats_address_network_type;
1698 GNUNET_break (ntohl(session->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED); 1730 GNUNET_break (ntohl(session->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED);
1699 1731
1700 delay = 1732 delay = plugin->env->receive (plugin->env->cls,
1701 plugin->env->receive (plugin->env->cls, &session->target, message, 1733 &session->target,
1702 (const struct GNUNET_ATS_Information *) &distance, 1734 message,
1703 1, session, 1735 (const struct GNUNET_ATS_Information *) &distance,
1704 (GNUNET_YES == 1736 1, session,
1705 session->inbound) ? NULL : session->connect_addr, 1737 (GNUNET_YES == session->inbound) ? NULL : session->addr,
1706 (GNUNET_YES == 1738 (GNUNET_YES == session->inbound) ? 0 : session->addrlen);
1707 session->inbound) ? 0 : session->connect_alen);
1708 if (delay.rel_value == 0) 1739 if (delay.rel_value == 0)
1709 { 1740 {
1710 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1741 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -1740,17 +1771,17 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
1740 if (client == NULL) 1771 if (client == NULL)
1741 return; 1772 return;
1742 plugin->max_connections++; 1773 plugin->max_connections++;
1743 session = find_session_by_client (plugin, client); 1774 session = lookup_session_by_client (plugin, client);
1744 if (session == NULL) 1775 if (session == NULL)
1745 return; /* unknown, nothing to do */ 1776 return; /* unknown, nothing to do */
1746#if DEBUG_TCP 1777#if DEBUG_TCP
1747 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", 1778 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp",
1748 "Destroying session of `%4s' with %s due to network-level disconnect.\n", 1779 "Destroying session of `%4s' with %s due to network-level disconnect.\n",
1749 GNUNET_i2s (&session->target), 1780 GNUNET_i2s (&session->target),
1750 (session->connect_addr != 1781 (session->addr !=
1751 NULL) ? tcp_address_to_string (session->plugin, 1782 NULL) ? tcp_address_to_string (session->plugin,
1752 session->connect_addr, 1783 session->addr,
1753 session->connect_alen) : 1784 session->addrlen) :
1754 "*"); 1785 "*");
1755#endif 1786#endif
1756 GNUNET_STATISTICS_update (session->plugin->env->stats, 1787 GNUNET_STATISTICS_update (session->plugin->env->stats,
@@ -2016,11 +2047,14 @@ libgnunet_plugin_transport_tcp_done (void *cls)
2016{ 2047{
2017 struct GNUNET_TRANSPORT_PluginFunctions *api = cls; 2048 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2018 struct Plugin *plugin = api->cls; 2049 struct Plugin *plugin = api->cls;
2019 struct Session *session;
2020 struct TCPProbeContext *tcp_probe; 2050 struct TCPProbeContext *tcp_probe;
2021 2051
2022 while (NULL != (session = plugin->sessions)) 2052 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", "Shutting down TCP plugin\n");
2023 disconnect_session (session); 2053
2054
2055 /* Removing leftover sessions */
2056 GNUNET_CONTAINER_multihashmap_iterate(plugin->sessionmap, &session_disconnect_it, NULL);
2057
2024 if (plugin->service != NULL) 2058 if (plugin->service != NULL)
2025 GNUNET_SERVICE_stop (plugin->service); 2059 GNUNET_SERVICE_stop (plugin->service);
2026 else 2060 else