diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-18 18:57:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-18 18:57:48 +0000 |
commit | 2e85825b85b733c2ada5bdf9a70ca70b130536e6 (patch) | |
tree | 11a4eb296cb3c049539794c94c0e6d126149a7d1 /src/transport/plugin_transport_udp.c | |
parent | 8f001cabeafeedd0ff95e3398ee684a5001d29d2 (diff) | |
download | gnunet-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.c | 301 |
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 | */ | ||
2154 | static void | ||
2155 | read_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 | */ | ||
2329 | static int | ||
2330 | process_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 | */ | ||
2335 | static void | ||
2336 | read_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 | */ | ||
2455 | static int | ||
2456 | process_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", |