aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-10-18 18:57:48 +0000
committerChristian Grothoff <christian@grothoff.org>2015-10-18 18:57:48 +0000
commit2e85825b85b733c2ada5bdf9a70ca70b130536e6 (patch)
tree11a4eb296cb3c049539794c94c0e6d126149a7d1 /src/transport/plugin_transport_udp.c
parent8f001cabeafeedd0ff95e3398ee684a5001d29d2 (diff)
downloadgnunet-2e85825b85b733c2ada5bdf9a70ca70b130536e6.tar.gz
gnunet-2e85825b85b733c2ada5bdf9a70ca70b130536e6.zip
-use UINT32_MAX to mean disconnect, for real
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c301
1 files changed, 155 insertions, 146 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 2c95918f1..29ade08f0 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -480,6 +480,8 @@ struct UDP_ACK_Message
480 480
481 /** 481 /**
482 * Desired delay for flow control, in us (in NBO). 482 * Desired delay for flow control, in us (in NBO).
483 * A value of UINT32_MAX indicates that the other
484 * peer wants us to disconnect.
483 */ 485 */
484 uint32_t delay GNUNET_PACKED; 486 uint32_t delay GNUNET_PACKED;
485 487
@@ -2143,118 +2145,6 @@ udp_plugin_send (void *cls,
2143} 2145}
2144 2146
2145 2147
2146/**
2147 * Handle an ACK message.
2148 *
2149 * @param plugin the UDP plugin
2150 * @param msg the (presumed) UDP ACK message
2151 * @param udp_addr sender address
2152 * @param udp_addr_len number of bytes in @a udp_addr
2153 */
2154static void
2155read_process_ack (struct Plugin *plugin,
2156 const struct GNUNET_MessageHeader *msg,
2157 const union UdpAddress *udp_addr,
2158 socklen_t udp_addr_len)
2159{
2160 const struct GNUNET_MessageHeader *ack;
2161 const struct UDP_ACK_Message *udp_ack;
2162 struct GNUNET_HELLO_Address *address;
2163 struct GNUNET_ATS_Session *s;
2164 struct GNUNET_TIME_Relative flow_delay;
2165
2166 if (ntohs (msg->size)
2167 < sizeof(struct UDP_ACK_Message) + sizeof(struct GNUNET_MessageHeader))
2168 {
2169 GNUNET_break_op (0);
2170 return;
2171 }
2172 udp_ack = (const struct UDP_ACK_Message *) msg;
2173 ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
2174 if (ntohs (ack->size) != ntohs (msg->size) - sizeof(struct UDP_ACK_Message))
2175 {
2176 GNUNET_break_op(0);
2177 return;
2178 }
2179 address = GNUNET_HELLO_address_allocate (&udp_ack->sender,
2180 PLUGIN_NAME,
2181 udp_addr,
2182 udp_addr_len,
2183 GNUNET_HELLO_ADDRESS_INFO_NONE);
2184 s = udp_plugin_lookup_session (plugin,
2185 address);
2186 if (NULL == s)
2187 {
2188 LOG (GNUNET_ERROR_TYPE_WARNING,
2189 "UDP session of address %s for ACK not found\n",
2190 udp_address_to_string (plugin,
2191 address->address,
2192 address->address_length));
2193 GNUNET_HELLO_address_free (address);
2194 return;
2195 }
2196 if (NULL == s->frag_ctx)
2197 {
2198 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2199 "Fragmentation context of address %s for ACK (%s) not found\n",
2200 udp_address_to_string (plugin,
2201 address->address,
2202 address->address_length),
2203 GNUNET_FRAGMENT_print_ack (ack));
2204 GNUNET_HELLO_address_free (address);
2205 return;
2206 }
2207 GNUNET_HELLO_address_free (address);
2208
2209 flow_delay.rel_value_us = (uint64_t) ntohl (udp_ack->delay);
2210 if (flow_delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
2211 LOG (GNUNET_ERROR_TYPE_WARNING,
2212 "We received a sending delay of %s for %s\n",
2213 GNUNET_STRINGS_relative_time_to_string (flow_delay,
2214 GNUNET_YES),
2215 GNUNET_i2s (&udp_ack->sender));
2216 else
2217 LOG (GNUNET_ERROR_TYPE_DEBUG,
2218 "We received a sending delay of %s for %s\n",
2219 GNUNET_STRINGS_relative_time_to_string (flow_delay,
2220 GNUNET_YES),
2221 GNUNET_i2s (&udp_ack->sender));
2222 /* Flow delay is for the reassembled packet, however, our delay
2223 is per packet, so we need to adjust: */
2224 flow_delay = GNUNET_TIME_relative_divide (flow_delay,
2225 1 + (s->frag_ctx->payload_size /
2226 UDP_MTU));
2227 s->flow_delay_from_other_peer = flow_delay;
2228
2229
2230 if (GNUNET_OK !=
2231 GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag,
2232 ack))
2233 {
2234 LOG (GNUNET_ERROR_TYPE_DEBUG,
2235 "UDP processes %u-byte acknowledgement from `%s' at `%s'\n",
2236 (unsigned int) ntohs (msg->size),
2237 GNUNET_i2s (&udp_ack->sender),
2238 udp_address_to_string (plugin,
2239 udp_addr,
2240 udp_addr_len));
2241 /* Expect more ACKs to arrive */
2242 return;
2243 }
2244
2245 LOG (GNUNET_ERROR_TYPE_DEBUG,
2246 "Message from %s at %s full ACK'ed\n",
2247 GNUNET_i2s (&udp_ack->sender),
2248 udp_address_to_string (plugin,
2249 udp_addr,
2250 udp_addr_len));
2251
2252 /* Remove fragmented message after successful sending */
2253 fragmented_message_done (s->frag_ctx,
2254 GNUNET_OK);
2255}
2256
2257
2258/* ********************** Receiving ********************** */ 2148/* ********************** Receiving ********************** */
2259 2149
2260 2150
@@ -2318,35 +2208,6 @@ find_receive_context (void *cls,
2318 2208
2319 2209
2320/** 2210/**
2321 * Message tokenizer has broken up an incomming message. Pass it on
2322 * to the service.
2323 *
2324 * @param cls the `struct Plugin *`
2325 * @param client the `struct GNUNET_ATS_Session *`
2326 * @param hdr the actual message
2327 * @return #GNUNET_OK (always)
2328 */
2329static int
2330process_inbound_tokenized_messages (void *cls,
2331 void *client,
2332 const struct GNUNET_MessageHeader *hdr)
2333{
2334 struct Plugin *plugin = cls;
2335 struct GNUNET_ATS_Session *session = client;
2336
2337 if (GNUNET_YES == session->in_destroy)
2338 return GNUNET_OK;
2339 reschedule_session_timeout (session);
2340 session->flow_delay_for_other_peer
2341 = plugin->env->receive (plugin->env->cls,
2342 session->address,
2343 session,
2344 hdr);
2345 return GNUNET_OK;
2346}
2347
2348
2349/**
2350 * Functions with this signature are called whenever we need to close 2211 * Functions with this signature are called whenever we need to close
2351 * a session due to a disconnect or failure to establish a connection. 2212 * a session due to a disconnect or failure to establish a connection.
2352 * 2213 *
@@ -2464,6 +2325,154 @@ udp_disconnect_session (void *cls,
2464 2325
2465 2326
2466/** 2327/**
2328 * Handle an ACK message.
2329 *
2330 * @param plugin the UDP plugin
2331 * @param msg the (presumed) UDP ACK message
2332 * @param udp_addr sender address
2333 * @param udp_addr_len number of bytes in @a udp_addr
2334 */
2335static void
2336read_process_ack (struct Plugin *plugin,
2337 const struct GNUNET_MessageHeader *msg,
2338 const union UdpAddress *udp_addr,
2339 socklen_t udp_addr_len)
2340{
2341 const struct GNUNET_MessageHeader *ack;
2342 const struct UDP_ACK_Message *udp_ack;
2343 struct GNUNET_HELLO_Address *address;
2344 struct GNUNET_ATS_Session *s;
2345 struct GNUNET_TIME_Relative flow_delay;
2346
2347 if (ntohs (msg->size)
2348 < sizeof(struct UDP_ACK_Message) + sizeof(struct GNUNET_MessageHeader))
2349 {
2350 GNUNET_break_op (0);
2351 return;
2352 }
2353 udp_ack = (const struct UDP_ACK_Message *) msg;
2354 ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
2355 if (ntohs (ack->size) != ntohs (msg->size) - sizeof(struct UDP_ACK_Message))
2356 {
2357 GNUNET_break_op(0);
2358 return;
2359 }
2360 address = GNUNET_HELLO_address_allocate (&udp_ack->sender,
2361 PLUGIN_NAME,
2362 udp_addr,
2363 udp_addr_len,
2364 GNUNET_HELLO_ADDRESS_INFO_NONE);
2365 s = udp_plugin_lookup_session (plugin,
2366 address);
2367 if (NULL == s)
2368 {
2369 LOG (GNUNET_ERROR_TYPE_WARNING,
2370 "UDP session of address %s for ACK not found\n",
2371 udp_address_to_string (plugin,
2372 address->address,
2373 address->address_length));
2374 GNUNET_HELLO_address_free (address);
2375 return;
2376 }
2377 if (NULL == s->frag_ctx)
2378 {
2379 LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
2380 "Fragmentation context of address %s for ACK (%s) not found\n",
2381 udp_address_to_string (plugin,
2382 address->address,
2383 address->address_length),
2384 GNUNET_FRAGMENT_print_ack (ack));
2385 GNUNET_HELLO_address_free (address);
2386 return;
2387 }
2388 GNUNET_HELLO_address_free (address);
2389
2390 if (UINT32_MAX == ntohl (udp_ack->delay))
2391 {
2392 /* Other peer asked for us to terminate the session */
2393 udp_disconnect_session (plugin,
2394 s);
2395 return;
2396 }
2397 flow_delay.rel_value_us = (uint64_t) ntohl (udp_ack->delay);
2398 if (flow_delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
2399 LOG (GNUNET_ERROR_TYPE_WARNING,
2400 "We received a sending delay of %s for %s\n",
2401 GNUNET_STRINGS_relative_time_to_string (flow_delay,
2402 GNUNET_YES),
2403 GNUNET_i2s (&udp_ack->sender));
2404 else
2405 LOG (GNUNET_ERROR_TYPE_DEBUG,
2406 "We received a sending delay of %s for %s\n",
2407 GNUNET_STRINGS_relative_time_to_string (flow_delay,
2408 GNUNET_YES),
2409 GNUNET_i2s (&udp_ack->sender));
2410 /* Flow delay is for the reassembled packet, however, our delay
2411 is per packet, so we need to adjust: */
2412 flow_delay = GNUNET_TIME_relative_divide (flow_delay,
2413 1 + (s->frag_ctx->payload_size /
2414 UDP_MTU));
2415 s->flow_delay_from_other_peer = flow_delay;
2416
2417
2418 if (GNUNET_OK !=
2419 GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag,
2420 ack))
2421 {
2422 LOG (GNUNET_ERROR_TYPE_DEBUG,
2423 "UDP processes %u-byte acknowledgement from `%s' at `%s'\n",
2424 (unsigned int) ntohs (msg->size),
2425 GNUNET_i2s (&udp_ack->sender),
2426 udp_address_to_string (plugin,
2427 udp_addr,
2428 udp_addr_len));
2429 /* Expect more ACKs to arrive */
2430 return;
2431 }
2432
2433 LOG (GNUNET_ERROR_TYPE_DEBUG,
2434 "Message from %s at %s full ACK'ed\n",
2435 GNUNET_i2s (&udp_ack->sender),
2436 udp_address_to_string (plugin,
2437 udp_addr,
2438 udp_addr_len));
2439
2440 /* Remove fragmented message after successful sending */
2441 fragmented_message_done (s->frag_ctx,
2442 GNUNET_OK);
2443}
2444
2445
2446/**
2447 * Message tokenizer has broken up an incomming message. Pass it on
2448 * to the service.
2449 *
2450 * @param cls the `struct Plugin *`
2451 * @param client the `struct GNUNET_ATS_Session *`
2452 * @param hdr the actual message
2453 * @return #GNUNET_OK (always)
2454 */
2455static int
2456process_inbound_tokenized_messages (void *cls,
2457 void *client,
2458 const struct GNUNET_MessageHeader *hdr)
2459{
2460 struct Plugin *plugin = cls;
2461 struct GNUNET_ATS_Session *session = client;
2462
2463 if (GNUNET_YES == session->in_destroy)
2464 return GNUNET_OK;
2465 reschedule_session_timeout (session);
2466 session->flow_delay_for_other_peer
2467 = plugin->env->receive (plugin->env->cls,
2468 session->address,
2469 session,
2470 hdr);
2471 return GNUNET_OK;
2472}
2473
2474
2475/**
2467 * Destroy a session, plugin is being unloaded. 2476 * Destroy a session, plugin is being unloaded.
2468 * 2477 *
2469 * @param cls the `struct Plugin` 2478 * @param cls the `struct Plugin`
@@ -2868,10 +2877,13 @@ ack_proc (void *cls,
2868 GNUNET_NO); 2877 GNUNET_NO);
2869 return; 2878 return;
2870 } 2879 }
2871 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) 2880 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
2881 s->flow_delay_for_other_peer.rel_value_us)
2882 delay = UINT32_MAX;
2883 else if (s->flow_delay_for_other_peer.rel_value_us < UINT32_MAX)
2872 delay = s->flow_delay_for_other_peer.rel_value_us; 2884 delay = s->flow_delay_for_other_peer.rel_value_us;
2873 else 2885 else
2874 delay = UINT32_MAX; 2886 delay = UINT32_MAX - 1; /* largest value we can communicate */
2875 LOG (GNUNET_ERROR_TYPE_DEBUG, 2887 LOG (GNUNET_ERROR_TYPE_DEBUG,
2876 "Sending ACK to `%s' including delay of %s\n", 2888 "Sending ACK to `%s' including delay of %s\n",
2877 udp_address_to_string (plugin, 2889 udp_address_to_string (plugin,
@@ -3078,9 +3090,6 @@ udp_select_read (struct Plugin *plugin,
3078 return; 3090 return;
3079 } 3091 }
3080 3092
3081
3082
3083
3084 msg = (const struct GNUNET_MessageHeader *) buf; 3093 msg = (const struct GNUNET_MessageHeader *) buf;
3085 LOG (GNUNET_ERROR_TYPE_DEBUG, 3094 LOG (GNUNET_ERROR_TYPE_DEBUG,
3086 "UDP received %u-byte message from `%s' type %u\n", 3095 "UDP received %u-byte message from `%s' type %u\n",