diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-14 16:29:51 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-01-14 16:29:51 +0000 |
commit | 28809e8a3b181a9587aa12096050838848836bfc (patch) | |
tree | e65d2b400accd6a6bee5e2768b49faef3aa8b0ad /src/transport/plugin_transport_udp.c | |
parent | 56e49b44a00454606f055cfdb362d976547bf64d (diff) | |
download | gnunet-28809e8a3b181a9587aa12096050838848836bfc.tar.gz gnunet-28809e8a3b181a9587aa12096050838848836bfc.zip |
issue: as long as we do not have a peer identity we cannot work with HELLO_addresses, so we have to stick to sock_addr
fixed sockaddr-to-session lookup
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 219535bf8..9e3fc4fdf 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -1121,7 +1121,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc, int result) | |||
1121 | call_continuation (&dummy, result); | 1121 | call_continuation (&dummy, result); |
1122 | 1122 | ||
1123 | /* Remove leftover fragments from queue */ | 1123 | /* Remove leftover fragments from queue */ |
1124 | if (s->address->address_length == sizeof(struct sockaddr_in6)) | 1124 | if (s->address->address_length == sizeof(struct IPv6UdpAddress)) |
1125 | { | 1125 | { |
1126 | udpw = plugin->ipv6_queue_head; | 1126 | udpw = plugin->ipv6_queue_head; |
1127 | while (NULL != udpw) | 1127 | while (NULL != udpw) |
@@ -1135,7 +1135,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc, int result) | |||
1135 | udpw = tmp; | 1135 | udpw = tmp; |
1136 | } | 1136 | } |
1137 | } | 1137 | } |
1138 | if (s->address->address_length == sizeof(struct sockaddr_in)) | 1138 | if (s->address->address_length == sizeof(struct IPv4UdpAddress)) |
1139 | { | 1139 | { |
1140 | udpw = plugin->ipv4_queue_head; | 1140 | udpw = plugin->ipv4_queue_head; |
1141 | while (udpw != NULL ) | 1141 | while (udpw != NULL ) |
@@ -1432,7 +1432,7 @@ udp_plugin_lookup_session (void *cls, | |||
1432 | struct SessionCompareContext cctx; | 1432 | struct SessionCompareContext cctx; |
1433 | cctx.address = address; | 1433 | cctx.address = address; |
1434 | cctx.res = NULL; | 1434 | cctx.res = NULL; |
1435 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1435 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
1436 | "Looking for existing session for peer `%s' `%s' \n", | 1436 | "Looking for existing session for peer `%s' `%s' \n", |
1437 | GNUNET_i2s (&address->peer), | 1437 | GNUNET_i2s (&address->peer), |
1438 | udp_address_to_string(NULL, address->address, address->address_length)); | 1438 | udp_address_to_string(NULL, address->address, address->address_length)); |
@@ -1440,7 +1440,7 @@ udp_plugin_lookup_session (void *cls, | |||
1440 | session_cmp_it, &cctx); | 1440 | session_cmp_it, &cctx); |
1441 | if (cctx.res != NULL ) | 1441 | if (cctx.res != NULL ) |
1442 | { | 1442 | { |
1443 | LOG(GNUNET_ERROR_TYPE_ERROR, "Found existing session %p\n", cctx.res); | 1443 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p\n", cctx.res); |
1444 | return cctx.res; | 1444 | return cctx.res; |
1445 | } | 1445 | } |
1446 | return NULL ; | 1446 | return NULL ; |
@@ -1487,7 +1487,7 @@ udp_plugin_create_session (void *cls, | |||
1487 | 1487 | ||
1488 | if (NULL == s) | 1488 | if (NULL == s) |
1489 | return NULL ; /* protocol not supported or address invalid */ | 1489 | return NULL ; /* protocol not supported or address invalid */ |
1490 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1490 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
1491 | "Creating new %s session %p for peer `%s' address `%s'\n", | 1491 | "Creating new %s session %p for peer `%s' address `%s'\n", |
1492 | GNUNET_HELLO_address_check_option (address, GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", | 1492 | GNUNET_HELLO_address_check_option (address, GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", |
1493 | s, GNUNET_i2s (&address->peer), | 1493 | s, GNUNET_i2s (&address->peer), |
@@ -1680,7 +1680,7 @@ udp_plugin_send (void *cls, struct Session *s, const char *msgbuf, | |||
1680 | GNUNET_break(0); | 1680 | GNUNET_break(0); |
1681 | return GNUNET_SYSERR; | 1681 | return GNUNET_SYSERR; |
1682 | } | 1682 | } |
1683 | LOG(GNUNET_ERROR_TYPE_ERROR, | 1683 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
1684 | "UDP transmits %u-byte message to `%s' using address `%s'\n", udpmlen, | 1684 | "UDP transmits %u-byte message to `%s' using address `%s'\n", udpmlen, |
1685 | GNUNET_i2s (&s->target), udp_address_to_string (NULL, s->address->address, s->address->address_length)); | 1685 | GNUNET_i2s (&s->target), udp_address_to_string (NULL, s->address->address, s->address->address_length)); |
1686 | 1686 | ||
@@ -1792,7 +1792,7 @@ udp_nat_port_map_callback (void *cls, int add_remove, | |||
1792 | break; | 1792 | break; |
1793 | case AF_INET6: | 1793 | case AF_INET6: |
1794 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); | 1794 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); |
1795 | memset (&u4, 0, sizeof(u4)); | 1795 | memset (&u6, 0, sizeof(u6)); |
1796 | u6.options = htonl (myoptions); | 1796 | u6.options = htonl (myoptions); |
1797 | if (0 == ((struct sockaddr_in6 *) addr)->sin6_port) | 1797 | if (0 == ((struct sockaddr_in6 *) addr)->sin6_port) |
1798 | return; | 1798 | return; |
@@ -1980,26 +1980,77 @@ fragment_msg_proc (void *cls, const struct GNUNET_MessageHeader *msg) | |||
1980 | rc->src_addr, rc->addr_len); | 1980 | rc->src_addr, rc->addr_len); |
1981 | } | 1981 | } |
1982 | 1982 | ||
1983 | |||
1984 | /** | ||
1985 | * Context to lookup a session based on a IP address | ||
1986 | */ | ||
1983 | struct LookupContext | 1987 | struct LookupContext |
1984 | { | 1988 | { |
1989 | /** | ||
1990 | * The result | ||
1991 | */ | ||
1985 | struct Session *res; | 1992 | struct Session *res; |
1986 | 1993 | ||
1987 | const struct GNUNET_HELLO_Address *address; | 1994 | /** |
1995 | * The socket address | ||
1996 | */ | ||
1997 | const struct sockaddr *address; | ||
1998 | |||
1999 | /** | ||
2000 | * The socket address length | ||
2001 | */ | ||
2002 | size_t addr_len; | ||
1988 | 2003 | ||
2004 | /** | ||
2005 | * Is a fragmentation context required for the session | ||
2006 | */ | ||
1989 | int must_have_frag_ctx; | 2007 | int must_have_frag_ctx; |
1990 | }; | 2008 | }; |
1991 | 2009 | ||
1992 | static int | 2010 | static int |
1993 | lookup_session_by_addr_it (void *cls, const struct GNUNET_PeerIdentity *key, | 2011 | lookup_session_by_sockaddr_it (void *cls, const struct GNUNET_PeerIdentity *key, |
1994 | void *value) | 2012 | void *value) |
1995 | { | 2013 | { |
1996 | struct LookupContext *l_ctx = cls; | 2014 | struct LookupContext *l_ctx = cls; |
1997 | struct Session * s = value; | 2015 | struct Session * s = value; |
2016 | struct IPv4UdpAddress u4; | ||
2017 | struct IPv6UdpAddress u6; | ||
2018 | void *arg; | ||
2019 | size_t args; | ||
2020 | |||
2021 | /* convert address */ | ||
2022 | switch (l_ctx->address->sa_family) | ||
2023 | { | ||
2024 | case AF_INET: | ||
2025 | GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in)); | ||
2026 | memset (&u4, 0, sizeof(u4)); | ||
2027 | u6.options = htonl (0); | ||
2028 | u4.ipv4_addr = ((struct sockaddr_in *) l_ctx->address)->sin_addr.s_addr; | ||
2029 | u4.u4_port = ((struct sockaddr_in *) l_ctx->address)->sin_port; | ||
2030 | arg = &u4; | ||
2031 | args = sizeof(u4); | ||
2032 | break; | ||
2033 | case AF_INET6: | ||
2034 | GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in6)); | ||
2035 | memset (&u6, 0, sizeof(u6)); | ||
2036 | u6.options = htonl (0); | ||
2037 | u6.ipv6_addr = ((struct sockaddr_in6 *) l_ctx->address)->sin6_addr; | ||
2038 | u6.u6_port = ((struct sockaddr_in6 *) l_ctx->address)->sin6_port; | ||
2039 | arg = &u6; | ||
2040 | args = sizeof(u6); | ||
2041 | break; | ||
2042 | default: | ||
2043 | GNUNET_break(0); | ||
2044 | return GNUNET_YES; | ||
2045 | } | ||
2046 | |||
1998 | 2047 | ||
1999 | if ((GNUNET_YES == l_ctx->must_have_frag_ctx) && (NULL == s->frag_ctx)) | 2048 | if ((GNUNET_YES == l_ctx->must_have_frag_ctx) && (NULL == s->frag_ctx)) |
2000 | return GNUNET_YES; | 2049 | return GNUNET_YES; |
2001 | 2050 | ||
2002 | if (0 == GNUNET_HELLO_address_cmp (s->address, l_ctx->address)) | 2051 | /* Does not compare peer identities but addresses */ |
2052 | if ((args == s->address->address_length) && | ||
2053 | (0 == memcmp (arg, s->address->address, args))) | ||
2003 | { | 2054 | { |
2004 | l_ctx->res = s; | 2055 | l_ctx->res = s; |
2005 | return GNUNET_YES; | 2056 | return GNUNET_YES; |
@@ -2025,17 +2076,18 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) | |||
2025 | struct Session *s; | 2076 | struct Session *s; |
2026 | struct LookupContext l_ctx; | 2077 | struct LookupContext l_ctx; |
2027 | 2078 | ||
2028 | l_ctx.address = GNUNET_HELLO_address_allocate (NULL, PLUGIN_NAME, rc->src_addr, | 2079 | l_ctx.address = rc->src_addr; |
2029 | rc->addr_len, GNUNET_HELLO_ADDRESS_INFO_NONE); | 2080 | l_ctx.addr_len = rc->addr_len; |
2030 | l_ctx.res = NULL; | ||
2031 | l_ctx.must_have_frag_ctx = GNUNET_NO; | 2081 | l_ctx.must_have_frag_ctx = GNUNET_NO; |
2082 | l_ctx.res = NULL; | ||
2032 | GNUNET_CONTAINER_multipeermap_iterate (rc->plugin->sessions, | 2083 | GNUNET_CONTAINER_multipeermap_iterate (rc->plugin->sessions, |
2033 | &lookup_session_by_addr_it, &l_ctx); | 2084 | &lookup_session_by_sockaddr_it, &l_ctx); |
2034 | s = l_ctx.res; | 2085 | s = l_ctx.res; |
2035 | |||
2036 | if (NULL == s) | 2086 | if (NULL == s) |
2087 | { | ||
2088 | GNUNET_break (0); | ||
2037 | return; | 2089 | return; |
2038 | 2090 | } | |
2039 | if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) | 2091 | if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) |
2040 | delay = s->flow_delay_for_other_peer.rel_value_us; | 2092 | delay = s->flow_delay_for_other_peer.rel_value_us; |
2041 | 2093 | ||
@@ -2056,6 +2108,7 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg) | |||
2056 | udp_ack->sender = *rc->plugin->env->my_identity; | 2108 | udp_ack->sender = *rc->plugin->env->my_identity; |
2057 | memcpy (&udp_ack[1], msg, ntohs (msg->size)); | 2109 | memcpy (&udp_ack[1], msg, ntohs (msg->size)); |
2058 | enqueue (rc->plugin, udpw); | 2110 | enqueue (rc->plugin, udpw); |
2111 | schedule_select (rc->plugin); | ||
2059 | } | 2112 | } |
2060 | 2113 | ||
2061 | static void | 2114 | static void |
@@ -2088,12 +2141,13 @@ read_process_ack (struct Plugin *plugin, const struct GNUNET_MessageHeader *msg, | |||
2088 | } | 2141 | } |
2089 | udp_ack = (const struct UDP_ACK_Message *) msg; | 2142 | udp_ack = (const struct UDP_ACK_Message *) msg; |
2090 | 2143 | ||
2091 | l_ctx.address = GNUNET_HELLO_address_allocate (NULL, PLUGIN_NAME, | 2144 | /* Lookup session based on sockaddr */ |
2092 | (const struct sockaddr *) addr, fromlen, GNUNET_HELLO_ADDRESS_INFO_NONE); | 2145 | l_ctx.address = addr; |
2146 | l_ctx.addr_len = fromlen; | ||
2093 | l_ctx.res = NULL; | 2147 | l_ctx.res = NULL; |
2094 | l_ctx.must_have_frag_ctx = GNUNET_YES; | 2148 | l_ctx.must_have_frag_ctx = GNUNET_YES; |
2095 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, | 2149 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, |
2096 | &lookup_session_by_addr_it, &l_ctx); | 2150 | &lookup_session_by_sockaddr_it, &l_ctx); |
2097 | s = l_ctx.res; | 2151 | s = l_ctx.res; |
2098 | if ((NULL == s) || (NULL == s->frag_ctx)) | 2152 | if ((NULL == s) || (NULL == s->frag_ctx)) |
2099 | { | 2153 | { |
@@ -2150,8 +2204,8 @@ read_process_fragment (struct Plugin *plugin, | |||
2150 | LOG(GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n", | 2204 | LOG(GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n", |
2151 | (unsigned int ) ntohs (msg->size), GNUNET_a2s (addr, fromlen)); | 2205 | (unsigned int ) ntohs (msg->size), GNUNET_a2s (addr, fromlen)); |
2152 | /* Lookup existing receive context for this address */ | 2206 | /* Lookup existing receive context for this address */ |
2153 | GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs, &find_receive_context, | 2207 | GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs, |
2154 | &frc); | 2208 | &find_receive_context, &frc); |
2155 | now = GNUNET_TIME_absolute_get (); | 2209 | now = GNUNET_TIME_absolute_get (); |
2156 | d_ctx = frc.rc; | 2210 | d_ctx = frc.rc; |
2157 | 2211 | ||
@@ -2248,7 +2302,7 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
2248 | } | 2302 | } |
2249 | msg = (const struct GNUNET_MessageHeader *) buf; | 2303 | msg = (const struct GNUNET_MessageHeader *) buf; |
2250 | 2304 | ||
2251 | LOG(GNUNET_ERROR_TYPE_ERROR, | 2305 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
2252 | "UDP received %u-byte message from `%s' type %u\n", (unsigned int ) size, | 2306 | "UDP received %u-byte message from `%s' type %u\n", (unsigned int ) size, |
2253 | GNUNET_a2s ((const struct sockaddr * ) &addr, fromlen), | 2307 | GNUNET_a2s ((const struct sockaddr * ) &addr, fromlen), |
2254 | ntohs (msg->type)); | 2308 | ntohs (msg->type)); |
@@ -2262,6 +2316,9 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
2262 | GNUNET_STATISTICS_update (plugin->env->stats, "# UDP, total, bytes, received", | 2316 | GNUNET_STATISTICS_update (plugin->env->stats, "# UDP, total, bytes, received", |
2263 | size, GNUNET_NO); | 2317 | size, GNUNET_NO); |
2264 | 2318 | ||
2319 | |||
2320 | |||
2321 | |||
2265 | switch (ntohs (msg->type)) | 2322 | switch (ntohs (msg->type)) |
2266 | { | 2323 | { |
2267 | case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: | 2324 | case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: |
@@ -2508,7 +2565,7 @@ udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) | |||
2508 | else | 2565 | else |
2509 | { | 2566 | { |
2510 | /* Success */ | 2567 | /* Success */ |
2511 | LOG(GNUNET_ERROR_TYPE_ERROR, | 2568 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
2512 | "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n", | 2569 | "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n", |
2513 | (unsigned int ) (udpw->msg_size), GNUNET_i2s (&udpw->session->target), | 2570 | (unsigned int ) (udpw->msg_size), GNUNET_i2s (&udpw->session->target), |
2514 | GNUNET_a2s (a, slen), (int ) sent, | 2571 | GNUNET_a2s (a, slen), (int ) sent, |