diff options
-rw-r--r-- | src/fs/gnunet-service-fs_mesh.c | 10 | ||||
-rw-r--r-- | src/include/gnunet_mesh_service.h | 44 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 53 | ||||
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 393 | ||||
-rw-r--r-- | src/mesh/mesh.h | 11 | ||||
-rw-r--r-- | src/mesh/mesh_api.c | 92 | ||||
-rw-r--r-- | src/mesh/mesh_protocol.h | 41 | ||||
-rw-r--r-- | src/pt/gnunet-daemon-pt.c | 6 | ||||
-rw-r--r-- | src/set/gnunet-service-set.c | 4 | ||||
-rw-r--r-- | src/stream/stream_api.c | 2 | ||||
-rw-r--r-- | src/util/peer.c | 2 | ||||
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 12 |
12 files changed, 394 insertions, 276 deletions
diff --git a/src/fs/gnunet-service-fs_mesh.c b/src/fs/gnunet-service-fs_mesh.c index a2cf3dad4..4c311279d 100644 --- a/src/fs/gnunet-service-fs_mesh.c +++ b/src/fs/gnunet-service-fs_mesh.c | |||
@@ -452,9 +452,11 @@ reset_mesh (struct StreamHandle *sh) | |||
452 | &move_to_pending, | 452 | &move_to_pending, |
453 | sh); | 453 | sh); |
454 | sh->mesh = GNUNET_MESH_tunnel_create (listen_socket, | 454 | sh->mesh = GNUNET_MESH_tunnel_create (listen_socket, |
455 | sh, | 455 | sh, |
456 | &sh->target, | 456 | &sh->target, |
457 | GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER); | 457 | GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, |
458 | GNUNET_YES, | ||
459 | GNUNET_YES); | ||
458 | } | 460 | } |
459 | 461 | ||
460 | 462 | ||
@@ -743,7 +745,9 @@ get_mesh (const struct GNUNET_PeerIdentity *target) | |||
743 | sh->mesh = GNUNET_MESH_tunnel_create (listen_socket, | 745 | sh->mesh = GNUNET_MESH_tunnel_create (listen_socket, |
744 | sh, | 746 | sh, |
745 | &sh->target, | 747 | &sh->target, |
746 | GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER); | 748 | GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, |
749 | GNUNET_YES, | ||
750 | GNUNET_YES); | ||
747 | GNUNET_assert (GNUNET_OK == | 751 | GNUNET_assert (GNUNET_OK == |
748 | GNUNET_CONTAINER_multihashmap_put (mesh_map, | 752 | GNUNET_CONTAINER_multihashmap_put (mesh_map, |
749 | &sh->target.hashPubKey, | 753 | &sh->target.hashPubKey, |
diff --git a/src/include/gnunet_mesh_service.h b/src/include/gnunet_mesh_service.h index 82fc3febd..48c71ed63 100644 --- a/src/include/gnunet_mesh_service.h +++ b/src/include/gnunet_mesh_service.h | |||
@@ -195,13 +195,18 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle); | |||
195 | * @param tunnel_ctx client's tunnel context to associate with the tunnel | 195 | * @param tunnel_ctx client's tunnel context to associate with the tunnel |
196 | * @param peer peer identity the tunnel should go to | 196 | * @param peer peer identity the tunnel should go to |
197 | * @param port Port number. | 197 | * @param port Port number. |
198 | * @param buffer Flag for buffering on relay nodes. | ||
199 | * @param reliable Flag for end-to-end reliability. | ||
200 | * | ||
198 | * @return handle to the tunnel | 201 | * @return handle to the tunnel |
199 | */ | 202 | */ |
200 | struct GNUNET_MESH_Tunnel * | 203 | struct GNUNET_MESH_Tunnel * |
201 | GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, | 204 | GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, |
202 | void *tunnel_ctx, | 205 | void *tunnel_ctx, |
203 | const struct GNUNET_PeerIdentity *peer, | 206 | const struct GNUNET_PeerIdentity *peer, |
204 | uint32_t port); | 207 | uint32_t port, |
208 | int buffer, | ||
209 | int reliable); | ||
205 | 210 | ||
206 | 211 | ||
207 | /** | 212 | /** |
@@ -218,28 +223,35 @@ GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel); | |||
218 | 223 | ||
219 | 224 | ||
220 | /** | 225 | /** |
221 | * Turn on/off the buffering status of the tunnel. | 226 | * Struct to retrieve info about a tunnel. |
222 | * | ||
223 | * @param tunnel Tunnel affected. | ||
224 | * @param buffer GNUNET_YES to turn buffering on (default), | ||
225 | * GNUNET_NO otherwise. | ||
226 | */ | 227 | */ |
227 | void | 228 | struct MeshTunnelInfo { |
228 | GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer); | 229 | |
230 | /** | ||
231 | * Property, as listed in src/mesh/mesh.h (GNUNET_MESH_OPTION_*) | ||
232 | */ | ||
233 | unsigned int prop; | ||
234 | |||
235 | /** | ||
236 | * Value, of type dependant on @c prop. | ||
237 | */ | ||
238 | void *value; | ||
239 | }; | ||
229 | 240 | ||
230 | 241 | ||
231 | /** | 242 | /** |
232 | * Turn on/off the reliability of the tunnel. | 243 | * Get information about a tunnel. |
233 | * | 244 | * |
234 | * If reliability is on, mesh will resend lost messages, similar to TCP. | 245 | * The existing end callback for the tunnel will be called immediately. |
235 | * If reliability is off, mesh just do best effort, similar to UDP. | 246 | * Any pending outgoing messages will be sent but no incoming messages will be |
247 | * accepted and no data callbacks will be called. | ||
248 | * | ||
249 | * @param tunnel Tunnel handle. | ||
236 | * | 250 | * |
237 | * @param tunnel Tunnel affected. | 251 | * @return Allocated, {0, NULL} terminated set of tunnel properties. |
238 | * @param reliable GNUNET_YES to turn reliability on, | ||
239 | * GNUNET_NO to have a best effort tunnel (default). | ||
240 | */ | 252 | */ |
241 | void | 253 | struct MeshTunnelInfo * |
242 | GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable); | 254 | GNUNET_MESH_tunnel_get_info (struct GNUNET_MESH_Tunnel *tunnel); |
243 | 255 | ||
244 | 256 | ||
245 | /** | 257 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 0a0a2967b..1bd1714c9 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -792,9 +792,9 @@ extern "C" | |||
792 | #define GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE 256 | 792 | #define GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE 256 |
793 | 793 | ||
794 | /** | 794 | /** |
795 | * Request the modification of an existing path | 795 | * Send origin an ACK that the path is complete |
796 | */ | 796 | */ |
797 | #define GNUNET_MESSAGE_TYPE_MESH_PATH_CHANGE 257 | 797 | #define GNUNET_MESSAGE_TYPE_MESH_PATH_ACK 257 |
798 | 798 | ||
799 | /** | 799 | /** |
800 | * Notify that a connection of a path is no longer valid | 800 | * Notify that a connection of a path is no longer valid |
@@ -817,9 +817,9 @@ extern "C" | |||
817 | #define GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN 262 | 817 | #define GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN 262 |
818 | 818 | ||
819 | /** | 819 | /** |
820 | * Send origin an ACK that the path is complete | 820 | * Confirm data end-to-end. |
821 | */ | 821 | */ |
822 | #define GNUNET_MESSAGE_TYPE_MESH_PATH_ACK 263 | 822 | #define GNUNET_MESSAGE_TYPE_MESH_DATA_ACK 263 |
823 | 823 | ||
824 | /** | 824 | /** |
825 | * Avoid path timeouts | 825 | * Avoid path timeouts |
@@ -862,51 +862,6 @@ extern "C" | |||
862 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY 274 | 862 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY 274 |
863 | 863 | ||
864 | /** | 864 | /** |
865 | * Ask the mesh service to add a peer to an existing tunnel | ||
866 | */ | ||
867 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD 275 | ||
868 | |||
869 | /** | ||
870 | * Ask the mesh service to remove a peer from a tunnel | ||
871 | */ | ||
872 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL 276 | ||
873 | |||
874 | /** | ||
875 | * Ask the mesh service to add a peer offering a service to an existing tunnel | ||
876 | */ | ||
877 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE 277 | ||
878 | |||
879 | /** | ||
880 | * Ask the mesh service to add a peer described by a service string | ||
881 | */ | ||
882 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX 278 | ||
883 | |||
884 | /** | ||
885 | * Ask the mesh service to add a peer described by a service string | ||
886 | */ | ||
887 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING 279 | ||
888 | |||
889 | /** | ||
890 | * Set tunnel to reliable. | ||
891 | */ | ||
892 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE 282 | ||
893 | |||
894 | /** | ||
895 | * Set tunnel to best effort. | ||
896 | */ | ||
897 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE 283 | ||
898 | |||
899 | /** | ||
900 | * Set tunnel buffering on. | ||
901 | */ | ||
902 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER 284 | ||
903 | |||
904 | /** | ||
905 | * Set tunnel buffering off. | ||
906 | */ | ||
907 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER 285 | ||
908 | |||
909 | /** | ||
910 | * Local ACK for data. | 865 | * Local ACK for data. |
911 | */ | 866 | */ |
912 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK 286 | 867 | #define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK 286 |
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index d97ae74b1..465c8912d 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -23,12 +23,14 @@ | |||
23 | * @brief GNUnet MESH service | 23 | * @brief GNUnet MESH service |
24 | * @author Bartlomiej Polot | 24 | * @author Bartlomiej Polot |
25 | * | 25 | * |
26 | * FIXME in progress: | ||
27 | * - keep queues until receiving ACK | ||
28 | * | ||
26 | * TODO: | 29 | * TODO: |
27 | * - relay corking down to core | 30 | * - relay corking down to core |
28 | * - set ttl relative to path length | 31 | * - set ttl relative to path length |
29 | * - add signatures | 32 | * - add signatures |
30 | * - add encryption | 33 | * - add encryption |
31 | * - keep queues until receiving ACK | ||
32 | * TODO END | 34 | * TODO END |
33 | */ | 35 | */ |
34 | 36 | ||
@@ -280,6 +282,39 @@ struct MESH_TunnelID | |||
280 | 282 | ||
281 | 283 | ||
282 | /** | 284 | /** |
285 | * Info needed to retry a message in case it gets lost. | ||
286 | */ | ||
287 | struct MeshSentMessage { | ||
288 | |||
289 | /** | ||
290 | * Tunnel this message is in. | ||
291 | */ | ||
292 | struct MeshTunnel *t; | ||
293 | |||
294 | /** | ||
295 | * ID of the message (ACK needed to free) | ||
296 | */ | ||
297 | uint32_t id; | ||
298 | |||
299 | /** | ||
300 | * Task to resend/poll in case no ACK is received. | ||
301 | */ | ||
302 | GNUNET_SCHEDULER_TaskIdentifier retry_task; // FIXME move to per tunnel timer? | ||
303 | |||
304 | /** | ||
305 | * Counter for exponential backoff. | ||
306 | */ | ||
307 | struct GNUNET_TIME_Relative retry_timer; | ||
308 | |||
309 | /** | ||
310 | * Is this a forward or backward going message? | ||
311 | */ | ||
312 | int is_forward; | ||
313 | |||
314 | /* struct GNUNET_MESH_Data with payload */ | ||
315 | }; | ||
316 | |||
317 | /** | ||
283 | * Struct containing all information regarding a tunnel | 318 | * Struct containing all information regarding a tunnel |
284 | * For an intermediate node the improtant info used will be: | 319 | * For an intermediate node the improtant info used will be: |
285 | * - id Tunnel unique identification | 320 | * - id Tunnel unique identification |
@@ -397,6 +432,18 @@ struct MeshTunnel | |||
397 | * Total messages pending for this tunnels, payload or not. | 432 | * Total messages pending for this tunnels, payload or not. |
398 | */ | 433 | */ |
399 | unsigned int pending_messages; | 434 | unsigned int pending_messages; |
435 | |||
436 | /** | ||
437 | * Messages sent and not yet ACK'd. | ||
438 | * Only present (non-NULL) at the owner of a tunnel. | ||
439 | */ | ||
440 | struct GNUNET_CONTAINER_MultiHashMap32 *sent_messages_fwd; | ||
441 | |||
442 | /** | ||
443 | * Messages sent and not yet ACK'd. | ||
444 | * Only present (non-NULL) at the destination of a tunnel. | ||
445 | */ | ||
446 | struct GNUNET_CONTAINER_MultiHashMap32 *sent_messages_bck; | ||
400 | }; | 447 | }; |
401 | 448 | ||
402 | 449 | ||
@@ -1998,10 +2045,13 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type) | |||
1998 | } | 2045 | } |
1999 | break; | 2046 | break; |
2000 | case GNUNET_MESSAGE_TYPE_MESH_ACK: | 2047 | case GNUNET_MESSAGE_TYPE_MESH_ACK: |
2048 | if (NULL != t->owner && GNUNET_YES == t->reliable) | ||
2049 | return; | ||
2001 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: | 2050 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: |
2002 | break; | 2051 | break; |
2003 | case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK: | 2052 | case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK: |
2004 | case GNUNET_MESSAGE_TYPE_MESH_POLL: | 2053 | case GNUNET_MESSAGE_TYPE_MESH_POLL: |
2054 | case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK: | ||
2005 | t->force_ack = GNUNET_YES; | 2055 | t->force_ack = GNUNET_YES; |
2006 | break; | 2056 | break; |
2007 | default: | 2057 | default: |
@@ -2073,10 +2123,13 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type) | |||
2073 | } | 2123 | } |
2074 | break; | 2124 | break; |
2075 | case GNUNET_MESSAGE_TYPE_MESH_ACK: | 2125 | case GNUNET_MESSAGE_TYPE_MESH_ACK: |
2126 | if (NULL != t->client && GNUNET_YES == t->reliable) | ||
2127 | return; | ||
2076 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: | 2128 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: |
2077 | break; | 2129 | break; |
2078 | case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK: | 2130 | case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK: |
2079 | case GNUNET_MESSAGE_TYPE_MESH_POLL: | 2131 | case GNUNET_MESSAGE_TYPE_MESH_POLL: |
2132 | case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK: | ||
2080 | t->force_ack = GNUNET_YES; | 2133 | t->force_ack = GNUNET_YES; |
2081 | break; | 2134 | break; |
2082 | default: | 2135 | default: |
@@ -2176,6 +2229,35 @@ tunnel_send_client_to_orig (struct MeshTunnel *t, | |||
2176 | 2229 | ||
2177 | 2230 | ||
2178 | /** | 2231 | /** |
2232 | * We haven't received an ACK after a certain time: restransmit the message. | ||
2233 | * | ||
2234 | * @param cls Closure (MeshSentMessage with the message to restransmit) | ||
2235 | * @param tc TaskContext. | ||
2236 | */ | ||
2237 | static void | ||
2238 | tunnel_retransmit_message (void *cls, | ||
2239 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2240 | { | ||
2241 | struct MeshSentMessage *copy = cls; | ||
2242 | struct GNUNET_MESH_Data *payload; | ||
2243 | GNUNET_PEER_Id hop; | ||
2244 | |||
2245 | copy->retry_task = GNUNET_SCHEDULER_NO_TASK; | ||
2246 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
2247 | return; | ||
2248 | |||
2249 | payload = (struct GNUNET_MESH_Data *) ©[1]; | ||
2250 | hop = copy->is_forward ? copy->t->next_hop : copy->t->prev_hop; | ||
2251 | send_prebuilt_message (&payload->header, hop, copy->t); | ||
2252 | GNUNET_STATISTICS_update (stats, "# unicast retransmitted", 1, GNUNET_NO); | ||
2253 | copy->retry_timer = GNUNET_TIME_STD_BACKOFF (copy->retry_timer); | ||
2254 | copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer, | ||
2255 | &tunnel_retransmit_message, | ||
2256 | cls); | ||
2257 | } | ||
2258 | |||
2259 | |||
2260 | /** | ||
2179 | * @brief Re-initiate traffic to this peer if necessary. | 2261 | * @brief Re-initiate traffic to this peer if necessary. |
2180 | * | 2262 | * |
2181 | * Check if there is traffic queued towards this peer | 2263 | * Check if there is traffic queued towards this peer |
@@ -2519,6 +2601,19 @@ tunnel_new (GNUNET_PEER_Id owner, | |||
2519 | } | 2601 | } |
2520 | 2602 | ||
2521 | 2603 | ||
2604 | /** | ||
2605 | * Set options in a tunnel, extracted from a bit flag field | ||
2606 | * | ||
2607 | * @param t Tunnel to set options to. | ||
2608 | * @param options Bit array in host byte order. | ||
2609 | */ | ||
2610 | static void | ||
2611 | tunnel_set_options (struct MeshTunnel *t, uint32_t options) | ||
2612 | { | ||
2613 | t->nobuffer = options & GNUNET_MESH_OPTION_NOBUFFER; | ||
2614 | t->reliable = options & GNUNET_MESH_OPTION_RELIABLE; | ||
2615 | } | ||
2616 | |||
2522 | 2617 | ||
2523 | /** | 2618 | /** |
2524 | * Iterator for deleting each tunnel whose client endpoint disconnected. | 2619 | * Iterator for deleting each tunnel whose client endpoint disconnected. |
@@ -2654,7 +2749,9 @@ send_core_path_create (void *cls, size_t size, void *buf) | |||
2654 | 2749 | ||
2655 | opt = 0; | 2750 | opt = 0; |
2656 | if (GNUNET_YES == t->nobuffer) | 2751 | if (GNUNET_YES == t->nobuffer) |
2657 | opt |= MESH_TUNNEL_OPT_NOBUFFER; | 2752 | opt |= GNUNET_MESH_OPTION_NOBUFFER; |
2753 | if (GNUNET_YES == t->reliable) | ||
2754 | opt |= GNUNET_MESH_OPTION_RELIABLE; | ||
2658 | msg->opt = htonl (opt); | 2755 | msg->opt = htonl (opt); |
2659 | msg->port = htonl (t->port); | 2756 | msg->port = htonl (t->port); |
2660 | 2757 | ||
@@ -3148,11 +3245,15 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3148 | } | 3245 | } |
3149 | t->port = ntohl (msg->port); | 3246 | t->port = ntohl (msg->port); |
3150 | opt = ntohl (msg->opt); | 3247 | opt = ntohl (msg->opt); |
3151 | if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER)) | 3248 | if (0 != (opt & GNUNET_MESH_OPTION_NOBUFFER)) |
3152 | { | 3249 | { |
3153 | t->nobuffer = GNUNET_YES; | 3250 | t->nobuffer = GNUNET_YES; |
3154 | t->queue_max = 1; | 3251 | t->queue_max = 1; |
3155 | } | 3252 | } |
3253 | if (0 != (opt & GNUNET_MESH_OPTION_RELIABLE)) | ||
3254 | { | ||
3255 | t->reliable = GNUNET_YES; | ||
3256 | } | ||
3156 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer); | 3257 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer); |
3157 | 3258 | ||
3158 | tunnel_reset_timeout (t); | 3259 | tunnel_reset_timeout (t); |
@@ -3228,6 +3329,10 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3228 | t->local_tid_dest = next_local_tid++; | 3329 | t->local_tid_dest = next_local_tid++; |
3229 | next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; | 3330 | next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; |
3230 | 3331 | ||
3332 | if (GNUNET_YES == t->reliable) | ||
3333 | t->sent_messages_bck = | ||
3334 | GNUNET_CONTAINER_multihashmap32_create (t->queue_max); | ||
3335 | |||
3231 | tunnel_add_client (t, c); | 3336 | tunnel_add_client (t, c); |
3232 | send_client_tunnel_create (t); | 3337 | send_client_tunnel_create (t); |
3233 | send_path_ack (t); | 3338 | send_path_ack (t); |
@@ -3660,6 +3765,86 @@ handle_mesh_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
3660 | 3765 | ||
3661 | 3766 | ||
3662 | /** | 3767 | /** |
3768 | * Core handler for mesh network traffic end-to-end ACKs. | ||
3769 | * | ||
3770 | * @param cls Closure. | ||
3771 | * @param message Message. | ||
3772 | * @param peer Peer identity this notification is about. | ||
3773 | * | ||
3774 | * @return GNUNET_OK to keep the connection open, | ||
3775 | * GNUNET_SYSERR to close it (signal serious error) | ||
3776 | */ | ||
3777 | static int | ||
3778 | handle_mesh_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
3779 | const struct GNUNET_MessageHeader *message) | ||
3780 | { | ||
3781 | struct GNUNET_MESH_DataACK *msg; | ||
3782 | struct GNUNET_CONTAINER_MultiHashMap32 *hm; | ||
3783 | struct MeshSentMessage *copy; | ||
3784 | struct MeshTunnel *t; | ||
3785 | GNUNET_PEER_Id id; | ||
3786 | uint32_t ack; | ||
3787 | |||
3788 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a DATA ACK message from %s!\n", | ||
3789 | GNUNET_i2s (peer)); | ||
3790 | msg = (struct GNUNET_MESH_DataACK *) message; | ||
3791 | |||
3792 | t = tunnel_get (&msg->oid, ntohl (msg->tid)); | ||
3793 | if (NULL == t) | ||
3794 | { | ||
3795 | /* TODO notify that we dont know this tunnel (whom)? */ | ||
3796 | GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO); | ||
3797 | return GNUNET_OK; | ||
3798 | } | ||
3799 | ack = ntohl (msg->pid); | ||
3800 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack); | ||
3801 | |||
3802 | /* Is this a forward or backward ACK? */ | ||
3803 | id = GNUNET_PEER_search (peer); | ||
3804 | if (t->next_hop == id) | ||
3805 | { | ||
3806 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n"); | ||
3807 | if (NULL == t->owner) | ||
3808 | { | ||
3809 | send_prebuilt_message (message, t->prev_hop, t); | ||
3810 | return GNUNET_OK; | ||
3811 | } | ||
3812 | hm = t->sent_messages_fwd; | ||
3813 | tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK); | ||
3814 | } | ||
3815 | else if (t->prev_hop == id) | ||
3816 | { | ||
3817 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n"); | ||
3818 | if (NULL == t->client) | ||
3819 | { | ||
3820 | send_prebuilt_message (message, t->next_hop, t); | ||
3821 | return GNUNET_OK; | ||
3822 | } | ||
3823 | hm = t->sent_messages_bck; | ||
3824 | tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK); | ||
3825 | } | ||
3826 | else | ||
3827 | GNUNET_break_op (0); | ||
3828 | |||
3829 | copy = GNUNET_CONTAINER_multihashmap32_get (hm, ack); | ||
3830 | if (NULL == copy) | ||
3831 | { | ||
3832 | GNUNET_break (0); // FIXME needed? | ||
3833 | return GNUNET_OK; | ||
3834 | } | ||
3835 | GNUNET_break (GNUNET_YES == | ||
3836 | GNUNET_CONTAINER_multihashmap32_remove (hm, ack, copy)); | ||
3837 | if (GNUNET_SCHEDULER_NO_TASK != copy->retry_task) | ||
3838 | { | ||
3839 | GNUNET_SCHEDULER_cancel (copy->retry_task); | ||
3840 | } | ||
3841 | else | ||
3842 | GNUNET_break (0); | ||
3843 | GNUNET_free (copy); | ||
3844 | return GNUNET_OK; | ||
3845 | } | ||
3846 | |||
3847 | /** | ||
3663 | * Core handler for mesh network traffic point-to-point acks. | 3848 | * Core handler for mesh network traffic point-to-point acks. |
3664 | * | 3849 | * |
3665 | * @param cls closure | 3850 | * @param cls closure |
@@ -3834,9 +4019,11 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = { | |||
3834 | {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY, | 4019 | {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY, |
3835 | sizeof (struct GNUNET_MESH_TunnelDestroy)}, | 4020 | sizeof (struct GNUNET_MESH_TunnelDestroy)}, |
3836 | {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, | 4021 | {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, |
4022 | {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, | ||
4023 | {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK, | ||
4024 | sizeof (struct GNUNET_MESH_DataACK)}, | ||
3837 | {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE, | 4025 | {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE, |
3838 | sizeof (struct GNUNET_MESH_TunnelKeepAlive)}, | 4026 | sizeof (struct GNUNET_MESH_TunnelKeepAlive)}, |
3839 | {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, | ||
3840 | {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK, | 4027 | {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK, |
3841 | sizeof (struct GNUNET_MESH_ACK)}, | 4028 | sizeof (struct GNUNET_MESH_ACK)}, |
3842 | {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL, | 4029 | {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL, |
@@ -4189,6 +4376,10 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
4189 | return; | 4376 | return; |
4190 | } | 4377 | } |
4191 | t->port = ntohl (t_msg->port); | 4378 | t->port = ntohl (t_msg->port); |
4379 | tunnel_set_options (t, ntohl (t_msg->options)); | ||
4380 | if (GNUNET_YES == t->reliable) | ||
4381 | t->sent_messages_fwd = | ||
4382 | GNUNET_CONTAINER_multihashmap32_create (t->queue_max); | ||
4192 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s[%x]:%u (%x)\n", | 4383 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s[%x]:%u (%x)\n", |
4193 | GNUNET_i2s (&my_full_id), t->id.tid, t->port, t->local_tid); | 4384 | GNUNET_i2s (&my_full_id), t->id.tid, t->port, t->local_tid); |
4194 | 4385 | ||
@@ -4270,120 +4461,6 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
4270 | 4461 | ||
4271 | 4462 | ||
4272 | /** | 4463 | /** |
4273 | * Handler for requests of seeting tunnel's buffering policy. | ||
4274 | * | ||
4275 | * @param cls Closure (unused). | ||
4276 | * @param client Identification of the client. | ||
4277 | * @param message The actual message. | ||
4278 | */ | ||
4279 | static void | ||
4280 | handle_local_tunnel_buffer (void *cls, struct GNUNET_SERVER_Client *client, | ||
4281 | const struct GNUNET_MessageHeader *message) | ||
4282 | { | ||
4283 | struct GNUNET_MESH_TunnelMessage *tunnel_msg; | ||
4284 | struct MeshClient *c; | ||
4285 | struct MeshTunnel *t; | ||
4286 | MESH_TunnelNumber tid; | ||
4287 | |||
4288 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4289 | "Got a BUFFER request from client!\n"); | ||
4290 | |||
4291 | /* Sanity check for client registration */ | ||
4292 | if (NULL == (c = client_get (client))) | ||
4293 | { | ||
4294 | GNUNET_break (0); | ||
4295 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4296 | return; | ||
4297 | } | ||
4298 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); | ||
4299 | |||
4300 | tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message; | ||
4301 | |||
4302 | /* Retrieve tunnel */ | ||
4303 | tid = ntohl (tunnel_msg->tunnel_id); | ||
4304 | t = tunnel_get_by_local_id(c, tid); | ||
4305 | if (NULL == t) | ||
4306 | { | ||
4307 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " tunnel %X not found\n", tid); | ||
4308 | GNUNET_break (0); | ||
4309 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4310 | return; | ||
4311 | } | ||
4312 | |||
4313 | switch (ntohs(message->type)) | ||
4314 | { | ||
4315 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER: | ||
4316 | t->nobuffer = GNUNET_NO; | ||
4317 | break; | ||
4318 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER: | ||
4319 | t->nobuffer = GNUNET_YES; | ||
4320 | break; | ||
4321 | default: | ||
4322 | GNUNET_break (0); | ||
4323 | } | ||
4324 | |||
4325 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
4326 | } | ||
4327 | |||
4328 | |||
4329 | /** | ||
4330 | * Handler for requests of seeting tunnel's reliability policy. | ||
4331 | * | ||
4332 | * @param cls Closure (unused). | ||
4333 | * @param client Identification of the client. | ||
4334 | * @param message The actual message. | ||
4335 | */ | ||
4336 | static void | ||
4337 | handle_local_tunnel_reliability (void *cls, struct GNUNET_SERVER_Client *client, | ||
4338 | const struct GNUNET_MessageHeader *message) | ||
4339 | { | ||
4340 | struct GNUNET_MESH_TunnelMessage *tunnel_msg; | ||
4341 | struct MeshClient *c; | ||
4342 | struct MeshTunnel *t; | ||
4343 | MESH_TunnelNumber tid; | ||
4344 | |||
4345 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4346 | "Got a BUFFER request from client!\n"); | ||
4347 | |||
4348 | /* Sanity check for client registration */ | ||
4349 | if (NULL == (c = client_get (client))) | ||
4350 | { | ||
4351 | GNUNET_break (0); | ||
4352 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4353 | return; | ||
4354 | } | ||
4355 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id); | ||
4356 | |||
4357 | tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message; | ||
4358 | |||
4359 | /* Retrieve tunnel */ | ||
4360 | tid = ntohl (tunnel_msg->tunnel_id); | ||
4361 | t = tunnel_get_by_local_id(c, tid); | ||
4362 | if (NULL == t) | ||
4363 | { | ||
4364 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " tunnel %X not found\n", tid); | ||
4365 | GNUNET_break (0); | ||
4366 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4367 | return; | ||
4368 | } | ||
4369 | |||
4370 | switch (ntohs(message->type)) | ||
4371 | { | ||
4372 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE: | ||
4373 | t->reliable = GNUNET_YES; | ||
4374 | break; | ||
4375 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE: | ||
4376 | t->reliable = GNUNET_NO; | ||
4377 | break; | ||
4378 | default: | ||
4379 | GNUNET_break (0); | ||
4380 | } | ||
4381 | |||
4382 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
4383 | } | ||
4384 | |||
4385 | |||
4386 | /** | ||
4387 | * Handler for client traffic directed to one peer | 4464 | * Handler for client traffic directed to one peer |
4388 | * | 4465 | * |
4389 | * @param cls closure | 4466 | * @param cls closure |
@@ -4457,18 +4534,34 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client, | |||
4457 | * (pretend we got it from a mesh peer) | 4534 | * (pretend we got it from a mesh peer) |
4458 | */ | 4535 | */ |
4459 | { | 4536 | { |
4460 | /* Work around const limitation */ | 4537 | struct MeshSentMessage *copy; |
4461 | char buf[ntohs (message->size)] GNUNET_ALIGN; | 4538 | struct GNUNET_MESH_Data *payload; |
4462 | struct GNUNET_MESH_Data *copy; | ||
4463 | 4539 | ||
4464 | copy = (struct GNUNET_MESH_Data *) buf; | 4540 | copy = GNUNET_malloc (sizeof (struct MeshSentMessage) + size); |
4465 | memcpy (buf, data_msg, size); | 4541 | copy->id = ntohl (data_msg->pid); |
4466 | copy->oid = my_full_id; | 4542 | copy->is_forward = GNUNET_YES; |
4467 | copy->tid = htonl (t->id.tid); | 4543 | copy->retry_timer = GNUNET_TIME_UNIT_MINUTES; |
4468 | copy->ttl = htonl (default_ttl); | 4544 | copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer, |
4545 | &tunnel_retransmit_message, | ||
4546 | copy); | ||
4547 | if (GNUNET_OK != | ||
4548 | GNUNET_CONTAINER_multihashmap32_put (t->sent_messages_fwd, | ||
4549 | copy->id, | ||
4550 | copy, | ||
4551 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
4552 | { | ||
4553 | GNUNET_break (0); | ||
4554 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4555 | return; | ||
4556 | } | ||
4557 | payload = (struct GNUNET_MESH_Data *) ©[1]; | ||
4558 | memcpy (payload, data_msg, size); | ||
4559 | payload->oid = my_full_id; | ||
4560 | payload->tid = htonl (t->id.tid); | ||
4561 | payload->ttl = htonl (default_ttl); | ||
4469 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4562 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4470 | " calling generic handler...\n"); | 4563 | " calling generic handler...\n"); |
4471 | handle_mesh_unicast (NULL, &my_full_id, ©->header); | 4564 | handle_mesh_unicast (NULL, &my_full_id, &payload->header); |
4472 | } | 4565 | } |
4473 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n"); | 4566 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n"); |
4474 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 4567 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -4562,19 +4655,35 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client, | |||
4562 | * (pretend we got it from a mesh peer) | 4655 | * (pretend we got it from a mesh peer) |
4563 | */ | 4656 | */ |
4564 | { | 4657 | { |
4565 | char buf[ntohs (message->size)] GNUNET_ALIGN; | 4658 | struct MeshSentMessage *copy; |
4566 | struct GNUNET_MESH_Data *copy; | 4659 | struct GNUNET_MESH_Data *payload; |
4567 | 4660 | ||
4568 | /* Work around 'const' limitation */ | 4661 | copy = GNUNET_malloc (sizeof (struct MeshSentMessage) + size); |
4569 | memcpy (buf, data_msg, size); | 4662 | copy->id = ntohl (data_msg->pid); |
4570 | copy = (struct GNUNET_MESH_Data *) buf; | 4663 | copy->is_forward = GNUNET_NO; |
4571 | GNUNET_PEER_resolve (t->id.oid, ©->oid); | 4664 | copy->retry_timer = GNUNET_TIME_UNIT_MINUTES; |
4572 | copy->tid = htonl (t->id.tid); | 4665 | copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer, |
4573 | copy->ttl = htonl (default_ttl); | 4666 | &tunnel_retransmit_message, |
4667 | copy); | ||
4668 | if (GNUNET_OK != | ||
4669 | GNUNET_CONTAINER_multihashmap32_put (t->sent_messages_bck, | ||
4670 | copy->id, | ||
4671 | copy, | ||
4672 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
4673 | { | ||
4674 | GNUNET_break (0); | ||
4675 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
4676 | return; | ||
4677 | } | ||
4678 | payload = (struct GNUNET_MESH_Data *) ©[1]; | ||
4679 | memcpy (payload, data_msg, size); | ||
4680 | GNUNET_PEER_resolve (t->id.oid, &payload->oid); | ||
4681 | payload->tid = htonl (t->id.tid); | ||
4682 | payload->ttl = htonl (default_ttl); | ||
4574 | 4683 | ||
4575 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4576 | " calling generic handler...\n"); | 4685 | " calling generic handler...\n"); |
4577 | handle_mesh_to_orig (NULL, &my_full_id, ©->header); | 4686 | handle_mesh_to_orig (NULL, &my_full_id, &payload->header); |
4578 | } | 4687 | } |
4579 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 4688 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
4580 | 4689 | ||
@@ -4789,18 +4898,6 @@ static struct GNUNET_SERVER_MessageHandler client_handlers[] = { | |||
4789 | {&handle_local_tunnel_destroy, NULL, | 4898 | {&handle_local_tunnel_destroy, NULL, |
4790 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, | 4899 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY, |
4791 | sizeof (struct GNUNET_MESH_TunnelMessage)}, | 4900 | sizeof (struct GNUNET_MESH_TunnelMessage)}, |
4792 | {&handle_local_tunnel_buffer, NULL, | ||
4793 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER, | ||
4794 | sizeof (struct GNUNET_MESH_TunnelMessage)}, | ||
4795 | {&handle_local_tunnel_buffer, NULL, | ||
4796 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER, | ||
4797 | sizeof (struct GNUNET_MESH_TunnelMessage)}, | ||
4798 | {&handle_local_tunnel_reliability, NULL, | ||
4799 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER, | ||
4800 | sizeof (struct GNUNET_MESH_TunnelMessage)}, | ||
4801 | {&handle_local_tunnel_reliability, NULL, | ||
4802 | GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER, | ||
4803 | sizeof (struct GNUNET_MESH_TunnelMessage)}, | ||
4804 | {&handle_local_unicast, NULL, | 4901 | {&handle_local_unicast, NULL, |
4805 | GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, | 4902 | GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, |
4806 | {&handle_local_to_origin, NULL, | 4903 | {&handle_local_to_origin, NULL, |
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index 360bfabb4..4cad774ba 100644 --- a/src/mesh/mesh.h +++ b/src/mesh/mesh.h | |||
@@ -88,6 +88,12 @@ extern "C" | |||
88 | #define HIGH_PID 0xFFFF0000 | 88 | #define HIGH_PID 0xFFFF0000 |
89 | #define LOW_PID 0x0000FFFF | 89 | #define LOW_PID 0x0000FFFF |
90 | 90 | ||
91 | /** | ||
92 | * Value in tunnel info: *int (GNUNET_YES/GNUNET_NO) | ||
93 | */ | ||
94 | #define GNUNET_MESH_OPTION_NOBUFFER 0x1 | ||
95 | #define GNUNET_MESH_OPTION_RELIABLE 0x2 | ||
96 | |||
91 | #define PID_OVERFLOW(pid, max) (pid > HIGH_PID && max < LOW_PID) | 97 | #define PID_OVERFLOW(pid, max) (pid > HIGH_PID && max < LOW_PID) |
92 | 98 | ||
93 | /******************************************************************************/ | 99 | /******************************************************************************/ |
@@ -148,6 +154,11 @@ struct GNUNET_MESH_TunnelMessage | |||
148 | * Port of the tunnel. | 154 | * Port of the tunnel. |
149 | */ | 155 | */ |
150 | uint32_t port GNUNET_PACKED; | 156 | uint32_t port GNUNET_PACKED; |
157 | |||
158 | /** | ||
159 | * Options. | ||
160 | */ | ||
161 | int32_t options GNUNET_PACKED; | ||
151 | }; | 162 | }; |
152 | 163 | ||
153 | 164 | ||
diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c index 064eb2885..6c579f1a0 100644 --- a/src/mesh/mesh_api.c +++ b/src/mesh/mesh_api.c | |||
@@ -734,6 +734,7 @@ do_reconnect (struct GNUNET_MESH_Handle *h) | |||
734 | for (t = h->tunnels_head; NULL != t; t = t->next) | 734 | for (t = h->tunnels_head; NULL != t; t = t->next) |
735 | { | 735 | { |
736 | struct GNUNET_MESH_TunnelMessage tmsg; | 736 | struct GNUNET_MESH_TunnelMessage tmsg; |
737 | uint32_t options; | ||
737 | 738 | ||
738 | if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) | 739 | if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) |
739 | { | 740 | { |
@@ -751,13 +752,16 @@ do_reconnect (struct GNUNET_MESH_Handle *h) | |||
751 | tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage)); | 752 | tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage)); |
752 | tmsg.tunnel_id = htonl (t->tid); | 753 | tmsg.tunnel_id = htonl (t->tid); |
753 | GNUNET_PEER_resolve (t->peer, &tmsg.peer); | 754 | GNUNET_PEER_resolve (t->peer, &tmsg.peer); |
754 | send_packet (h, &tmsg.header, t); | ||
755 | 755 | ||
756 | options = 0; | ||
756 | if (GNUNET_NO == t->buffering) | 757 | if (GNUNET_NO == t->buffering) |
757 | GNUNET_MESH_tunnel_buffer (t, GNUNET_NO); | 758 | options |= GNUNET_MESH_OPTION_NOBUFFER; |
758 | 759 | ||
759 | if (GNUNET_YES == t->reliable) | 760 | if (GNUNET_YES == t->reliable) |
760 | GNUNET_MESH_tunnel_reliable (t, GNUNET_YES); | 761 | options |= GNUNET_MESH_OPTION_RELIABLE; |
762 | |||
763 | tmsg.options = htonl (options); | ||
764 | send_packet (h, &tmsg.header, t); | ||
761 | } | 765 | } |
762 | return GNUNET_YES; | 766 | return GNUNET_YES; |
763 | } | 767 | } |
@@ -831,10 +835,14 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h, | |||
831 | t->mesh = h; | 835 | t->mesh = h; |
832 | t->tid = tid; | 836 | t->tid = tid; |
833 | t->port = ntohl (msg->port); | 837 | t->port = ntohl (msg->port); |
834 | if (0 != (msg->opt & MESH_TUNNEL_OPT_NOBUFFER)) | 838 | if (0 != (msg->opt & GNUNET_MESH_OPTION_NOBUFFER)) |
835 | t->buffering = GNUNET_NO; | 839 | t->buffering = GNUNET_NO; |
836 | else | 840 | else |
837 | t->buffering = GNUNET_YES; | 841 | t->buffering = GNUNET_YES; |
842 | if (0 != (msg->opt & GNUNET_MESH_OPTION_RELIABLE)) | ||
843 | t->reliable = GNUNET_YES; | ||
844 | else | ||
845 | t->reliable = GNUNET_NO; | ||
838 | LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t); | 846 | LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t); |
839 | t->ctx = h->new_tunnel (h->cls, t, &msg->peer, t->port); | 847 | t->ctx = h->new_tunnel (h->cls, t, &msg->peer, t->port); |
840 | LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n"); | 848 | LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n"); |
@@ -1446,11 +1454,26 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle) | |||
1446 | } | 1454 | } |
1447 | 1455 | ||
1448 | 1456 | ||
1457 | /** | ||
1458 | * Create a new tunnel (we're initiator and will be allowed to add/remove peers | ||
1459 | * and to broadcast). | ||
1460 | * | ||
1461 | * @param h mesh handle | ||
1462 | * @param tunnel_ctx client's tunnel context to associate with the tunnel | ||
1463 | * @param peer peer identity the tunnel should go to | ||
1464 | * @param port Port number. | ||
1465 | * @param buffer Flag for buffering on relay nodes. | ||
1466 | * @param reliable Flag for end-to-end reliability. | ||
1467 | * | ||
1468 | * @return handle to the tunnel | ||
1469 | */ | ||
1449 | struct GNUNET_MESH_Tunnel * | 1470 | struct GNUNET_MESH_Tunnel * |
1450 | GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, | 1471 | GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, |
1451 | void *tunnel_ctx, | 1472 | void *tunnel_ctx, |
1452 | const struct GNUNET_PeerIdentity *peer, | 1473 | const struct GNUNET_PeerIdentity *peer, |
1453 | uint32_t port) | 1474 | uint32_t port, |
1475 | int buffer, | ||
1476 | int reliable) | ||
1454 | { | 1477 | { |
1455 | struct GNUNET_MESH_Tunnel *t; | 1478 | struct GNUNET_MESH_Tunnel *t; |
1456 | struct GNUNET_MESH_TunnelMessage msg; | 1479 | struct GNUNET_MESH_TunnelMessage msg; |
@@ -1508,56 +1531,33 @@ GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel) | |||
1508 | } | 1531 | } |
1509 | 1532 | ||
1510 | 1533 | ||
1511 | void | ||
1512 | GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer) | ||
1513 | { | ||
1514 | struct GNUNET_MESH_TunnelMessage msg; | ||
1515 | struct GNUNET_MESH_Handle *h; | ||
1516 | |||
1517 | h = tunnel->mesh; | ||
1518 | tunnel->buffering = buffer; | ||
1519 | |||
1520 | if (GNUNET_YES == buffer) | ||
1521 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER); | ||
1522 | else | ||
1523 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER); | ||
1524 | msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage)); | ||
1525 | msg.tunnel_id = htonl (tunnel->tid); | ||
1526 | |||
1527 | send_packet (h, &msg.header, NULL); | ||
1528 | } | ||
1529 | |||
1530 | |||
1531 | /** | 1534 | /** |
1532 | * Turn on/off the reliability of the tunnel. | 1535 | * Get information about a tunnel. |
1533 | * | 1536 | * |
1534 | * If reliability is on, mesh will resend lost messages, similar to TCP. | 1537 | * The existing end callback for the tunnel will be called immediately. |
1535 | * If reliability is off, mesh just do best effort, similar to UDP. | 1538 | * Any pending outgoing messages will be sent but no incoming messages will be |
1539 | * accepted and no data callbacks will be called. | ||
1540 | * | ||
1541 | * @param tunnel Tunnel handle. | ||
1536 | * | 1542 | * |
1537 | * @param tunnel Tunnel affected. | 1543 | * @return Allocated, {0, NULL} terminated set of tunnel properties. |
1538 | * @param reliable GNUNET_YES to turn reliability on, | ||
1539 | * GNUNET_NO to have a best effort tunnel (default). | ||
1540 | */ | 1544 | */ |
1541 | void | 1545 | struct MeshTunnelInfo * |
1542 | GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable) | 1546 | GNUNET_MESH_tunnel_get_info (struct GNUNET_MESH_Tunnel *tunnel) |
1543 | { | 1547 | { |
1544 | struct GNUNET_MESH_TunnelMessage msg; | 1548 | struct MeshTunnelInfo *ret; |
1545 | struct GNUNET_MESH_Handle *h; | ||
1546 | |||
1547 | h = tunnel->mesh; | ||
1548 | tunnel->reliable = reliable; | ||
1549 | 1549 | ||
1550 | if (GNUNET_YES == reliable) | 1550 | ret = GNUNET_malloc (sizeof (struct MeshTunnelInfo) * 3); |
1551 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE); | 1551 | ret[0].prop = GNUNET_MESH_OPTION_NOBUFFER; |
1552 | else | 1552 | ret[0].value = &tunnel->buffering; // FIXME return ¬buffering ("nobuffer") |
1553 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE); | 1553 | ret[1].prop = GNUNET_MESH_OPTION_RELIABLE; |
1554 | msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage)); | 1554 | ret[1].value = &tunnel->reliable; |
1555 | msg.tunnel_id = htonl (tunnel->tid); | 1555 | ret[2].prop = 0; |
1556 | ret[2].value = NULL; | ||
1556 | 1557 | ||
1557 | send_packet (h, &msg.header, NULL); | 1558 | return ret; |
1558 | } | 1559 | } |
1559 | 1560 | ||
1560 | |||
1561 | struct GNUNET_MESH_TransmitHandle * | 1561 | struct GNUNET_MESH_TransmitHandle * |
1562 | GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork, | 1562 | GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork, |
1563 | struct GNUNET_TIME_Relative maxdelay, | 1563 | struct GNUNET_TIME_Relative maxdelay, |
diff --git a/src/mesh/mesh_protocol.h b/src/mesh/mesh_protocol.h index d35d7141e..ce9df073c 100644 --- a/src/mesh/mesh_protocol.h +++ b/src/mesh/mesh_protocol.h | |||
@@ -35,9 +35,6 @@ extern "C" | |||
35 | #endif | 35 | #endif |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #define MESH_TUNNEL_OPT_NOBUFFER 0x2 | ||
39 | |||
40 | |||
41 | /******************************************************************************/ | 38 | /******************************************************************************/ |
42 | /******************** MESH NETWORK MESSAGES **************************/ | 39 | /******************** MESH NETWORK MESSAGES **************************/ |
43 | /******************************************************************************/ | 40 | /******************************************************************************/ |
@@ -64,7 +61,7 @@ struct GNUNET_MESH_CreateTunnel | |||
64 | uint32_t tid GNUNET_PACKED; | 61 | uint32_t tid GNUNET_PACKED; |
65 | 62 | ||
66 | /** | 63 | /** |
67 | * Tunnel options (MESH_TUNNEL_OPT_*). | 64 | * Tunnel options (GNUNET_MESH_OPTION_*). |
68 | */ | 65 | */ |
69 | uint32_t opt GNUNET_PACKED; | 66 | uint32_t opt GNUNET_PACKED; |
70 | 67 | ||
@@ -140,6 +137,40 @@ struct GNUNET_MESH_Data | |||
140 | 137 | ||
141 | 138 | ||
142 | /** | 139 | /** |
140 | * Message to acknowledge end-to-end data. | ||
141 | */ | ||
142 | struct GNUNET_MESH_DataACK | ||
143 | { | ||
144 | /** | ||
145 | * Type: GNUNET_MESSAGE_TYPE_MESH_DATA_ACK | ||
146 | */ | ||
147 | struct GNUNET_MessageHeader header; | ||
148 | |||
149 | /** | ||
150 | * TID of the tunnel | ||
151 | */ | ||
152 | uint32_t tid GNUNET_PACKED; | ||
153 | |||
154 | /** | ||
155 | * OID of the tunnel | ||
156 | */ | ||
157 | struct GNUNET_PeerIdentity oid; | ||
158 | |||
159 | /** | ||
160 | * Maximum packet ID acknowledged. | ||
161 | */ | ||
162 | uint32_t pid; | ||
163 | |||
164 | /** | ||
165 | * Bitfield of already-received newer messages // TODO implement and use | ||
166 | * pid + 1 @ LSB | ||
167 | * pid + 32 @ MSB | ||
168 | */ | ||
169 | uint32_t futures; | ||
170 | }; | ||
171 | |||
172 | |||
173 | /** | ||
143 | * Message to acknowledge mesh data traffic. | 174 | * Message to acknowledge mesh data traffic. |
144 | */ | 175 | */ |
145 | struct GNUNET_MESH_ACK | 176 | struct GNUNET_MESH_ACK |
@@ -163,9 +194,9 @@ struct GNUNET_MESH_ACK | |||
163 | * Maximum packet ID authorized. | 194 | * Maximum packet ID authorized. |
164 | */ | 195 | */ |
165 | uint32_t pid; | 196 | uint32_t pid; |
166 | |||
167 | }; | 197 | }; |
168 | 198 | ||
199 | |||
169 | /** | 200 | /** |
170 | * Message to query a peer about its Flow Control status regarding a tunnel. | 201 | * Message to query a peer about its Flow Control status regarding a tunnel. |
171 | */ | 202 | */ |
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c index 466584f0f..dc7eef061 100644 --- a/src/pt/gnunet-daemon-pt.c +++ b/src/pt/gnunet-daemon-pt.c | |||
@@ -943,9 +943,11 @@ run (void *cls, char *const *args GNUNET_UNUSED, | |||
943 | return; | 943 | return; |
944 | } | 944 | } |
945 | mesh_tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | 945 | mesh_tunnel = GNUNET_MESH_tunnel_create (mesh_handle, |
946 | NULL, | 946 | NULL, |
947 | NULL, /* FIXME peer ID*/ | 947 | NULL, /* FIXME peer ID*/ |
948 | PORT_PT); | 948 | PORT_PT, |
949 | GNUNET_YES, | ||
950 | GNUNET_NO); | ||
949 | // GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel, FIXME use regex | 951 | // GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel, FIXME use regex |
950 | // GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER); | 952 | // GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER); |
951 | } | 953 | } |
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c index 5a4a18f15..62d1ce21b 100644 --- a/src/set/gnunet-service-set.c +++ b/src/set/gnunet-service-set.c | |||
@@ -655,7 +655,9 @@ handle_client_evaluate (void *cls, | |||
655 | spec->peer = msg->target_peer; | 655 | spec->peer = msg->target_peer; |
656 | 656 | ||
657 | tunnel = GNUNET_MESH_tunnel_create (mesh, tc, &msg->target_peer, | 657 | tunnel = GNUNET_MESH_tunnel_create (mesh, tc, &msg->target_peer, |
658 | GNUNET_APPLICATION_TYPE_SET); | 658 | GNUNET_APPLICATION_TYPE_SET, |
659 | GNUNET_YES, | ||
660 | GNUNET_YES); | ||
659 | 661 | ||
660 | switch (set->operation) | 662 | switch (set->operation) |
661 | { | 663 | { |
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c index f8c0af1cf..3647ba21d 100644 --- a/src/stream/stream_api.c +++ b/src/stream/stream_api.c | |||
@@ -3024,7 +3024,7 @@ GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
3024 | socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh, | 3024 | socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh, |
3025 | socket, /* Tunnel context */ | 3025 | socket, /* Tunnel context */ |
3026 | &socket->other_peer, | 3026 | &socket->other_peer, |
3027 | STREAM_PORT); | 3027 | STREAM_PORT, 1, 0); |
3028 | GNUNET_assert (NULL != socket->tunnel); | 3028 | GNUNET_assert (NULL != socket->tunnel); |
3029 | socket->stat_handle = GNUNET_STATISTICS_create ("stream", cfg); | 3029 | socket->stat_handle = GNUNET_STATISTICS_create ("stream", cfg); |
3030 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); | 3030 | LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__); |
diff --git a/src/util/peer.c b/src/util/peer.c index 1ad3ee264..81803e097 100644 --- a/src/util/peer.c +++ b/src/util/peer.c | |||
@@ -227,7 +227,7 @@ GNUNET_PEER_resolve (GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid) | |||
227 | if (0 == id) | 227 | if (0 == id) |
228 | { | 228 | { |
229 | memset (pid, 0, sizeof (struct GNUNET_PeerIdentity)); | 229 | memset (pid, 0, sizeof (struct GNUNET_PeerIdentity)); |
230 | GNUNET_break (0); | 230 | GNUNET_assert (0); |
231 | return; | 231 | return; |
232 | } | 232 | } |
233 | GNUNET_assert (id < size); | 233 | GNUNET_assert (id < size); |
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 7844df15b..5230dc631 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -785,9 +785,11 @@ handle_regex_result (void *cls, | |||
785 | GNUNET_REGEX_search_cancel (ts->search); | 785 | GNUNET_REGEX_search_cancel (ts->search); |
786 | ts->search = NULL; | 786 | ts->search = NULL; |
787 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | 787 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, |
788 | ts, | 788 | ts, |
789 | id, | 789 | id, |
790 | PORT_VPN); | 790 | PORT_VPN, |
791 | GNUNET_YES, | ||
792 | GNUNET_NO); | ||
791 | } | 793 | } |
792 | 794 | ||
793 | 795 | ||
@@ -827,8 +829,10 @@ create_tunnel_to_destination (struct DestinationEntry *de, | |||
827 | { | 829 | { |
828 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, | 830 | ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle, |
829 | ts, | 831 | ts, |
830 | &de->details.service_destination.target, | 832 | &de->details.service_destination.target, |
831 | PORT_VPN); | 833 | PORT_VPN, |
834 | GNUNET_YES, | ||
835 | GNUNET_NO); | ||
832 | if (NULL == ts->tunnel) | 836 | if (NULL == ts->tunnel) |
833 | { | 837 | { |
834 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 838 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |