aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fs/gnunet-service-fs_mesh.c10
-rw-r--r--src/include/gnunet_mesh_service.h44
-rw-r--r--src/include/gnunet_protocols.h53
-rw-r--r--src/mesh/gnunet-service-mesh.c393
-rw-r--r--src/mesh/mesh.h11
-rw-r--r--src/mesh/mesh_api.c92
-rw-r--r--src/mesh/mesh_protocol.h41
-rw-r--r--src/pt/gnunet-daemon-pt.c6
-rw-r--r--src/set/gnunet-service-set.c4
-rw-r--r--src/stream/stream_api.c2
-rw-r--r--src/util/peer.c2
-rw-r--r--src/vpn/gnunet-service-vpn.c12
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 */
200struct GNUNET_MESH_Tunnel * 203struct GNUNET_MESH_Tunnel *
201GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, 204GNUNET_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 */
227void 228struct MeshTunnelInfo {
228GNUNET_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 */
241void 253struct MeshTunnelInfo *
242GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable); 254GNUNET_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 */
287struct 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 */
2237static void
2238tunnel_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 *) &copy[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 */
2610static void
2611tunnel_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 */
3777static int
3778handle_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 */
4279static void
4280handle_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 */
4336static void
4337handle_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 *) &copy[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, &copy->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, &copy->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 *) &copy[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, &copy->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 */
1449struct GNUNET_MESH_Tunnel * 1470struct GNUNET_MESH_Tunnel *
1450GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, 1471GNUNET_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
1511void
1512GNUNET_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 */
1541void 1545struct MeshTunnelInfo *
1542GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable) 1546GNUNET_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
1561struct GNUNET_MESH_TransmitHandle * 1561struct GNUNET_MESH_TransmitHandle *
1562GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork, 1562GNUNET_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 */
142struct 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 */
145struct GNUNET_MESH_ACK 176struct 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,