aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh-new.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/gnunet-service-mesh-new.c')
-rw-r--r--src/mesh/gnunet-service-mesh-new.c869
1 files changed, 116 insertions, 753 deletions
diff --git a/src/mesh/gnunet-service-mesh-new.c b/src/mesh/gnunet-service-mesh-new.c
index 8c98d4a34..0fb4766ea 100644
--- a/src/mesh/gnunet-service-mesh-new.c
+++ b/src/mesh/gnunet-service-mesh-new.c
@@ -370,22 +370,22 @@ struct MeshTunnel
370 GNUNET_PEER_Id dest; 370 GNUNET_PEER_Id dest;
371 371
372 /** 372 /**
373 * Next hop in the tunnel. 373 * Next hop in the tunnel. If 0, @c client must be set.
374 */ 374 */
375 GNUNET_PEER_Id next_hop; 375 GNUNET_PEER_Id next_hop;
376 376
377 /** 377 /**
378 * Previous hop in the tunnel. 378 * Previous hop in the tunnel. If 0, @c owner must be set.
379 */ 379 */
380 GNUNET_PEER_Id prev_hop; 380 GNUNET_PEER_Id prev_hop;
381 381
382 /** 382 /**
383 * Flow control information about @c next_hop. 383 * Flow control information about @c next_hop or @c client.
384 */ 384 */
385 struct MeshFlowControl next_fc; 385 struct MeshFlowControl next_fc;
386 386
387 /** 387 /**
388 * Flow control information about @c prev_hop. 388 * Flow control information about @c prev_hop or @c owner.
389 */ 389 */
390 struct MeshFlowControl prev_fc; 390 struct MeshFlowControl prev_fc;
391 391
@@ -395,35 +395,15 @@ struct MeshTunnel
395 struct MeshClient *owner; 395 struct MeshClient *owner;
396 396
397 /** 397 /**
398 * Task to keep the used paths alive at the owner, 398 * Client destination of the tunnel, if any.
399 * time tunnel out on all the other peers.
400 */
401 GNUNET_SCHEDULER_TaskIdentifier maintenance_task;
402
403 /**
404 * Clients that have been informed about and want to stay in the tunnel.
405 */
406 struct MeshClient **clients;
407
408 /**
409 * Flow control info for each client.
410 */ 399 */
411 struct MeshTunnelClientInfo *clients_fc; 400 struct MeshClient *client;
412 401
413 /** 402 /**
414 * Number of elements in clients/clients_fc 403 * Task to keep the used paths alive at the owner,
415 */ 404 * time tunnel out on all the other peers.
416 unsigned int nclients;
417
418 /**
419 * Clients that have been informed but requested to leave the tunnel.
420 */
421 struct MeshClient **ignore;
422
423 /**
424 * Number of elements in clients
425 */ 405 */
426 unsigned int nignore; 406 GNUNET_SCHEDULER_TaskIdentifier maintenance_task;
427 407
428 /** 408 /**
429 * Path being used for the tunnel. 409 * Path being used for the tunnel.
@@ -441,43 +421,13 @@ struct MeshTunnel
441 * Total messages pending for this tunnels, payload or not. 421 * Total messages pending for this tunnels, payload or not.
442 */ 422 */
443 unsigned int pending_messages; 423 unsigned int pending_messages;
444
445 /**
446 * If the tunnel is empty, destoy it.
447 */
448 GNUNET_SCHEDULER_TaskIdentifier delayed_destroy;
449};
450
451
452/**
453 * Info about a leaf client of a tunnel, needed to perform flow control.
454 */
455struct MeshTunnelClientInfo
456{
457 /**
458 * PID of the last packet sent to the client (FWD).
459 */
460 uint32_t fwd_pid;
461
462 /**
463 * PID of the last packet received from the client (BCK).
464 */
465 uint32_t bck_pid;
466
467 /**
468 * Maximum PID allowed (FWD ACK received).
469 */
470 uint32_t fwd_ack;
471
472 /**
473 * Last ACK sent to that child (BCK ACK).
474 */
475 uint32_t bck_ack;
476}; 424};
477 425
478 426
479/** 427/**
480 * Struct containing information about a client of the service 428 * Struct containing information about a client of the service
429 *
430 * TODO: add a list of 'waiting' types
481 */ 431 */
482struct MeshClient 432struct MeshClient
483{ 433{
@@ -501,10 +451,6 @@ struct MeshClient
501 */ 451 */
502 struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels; 452 struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
503 453
504 /**
505 * Tunnels this client has rejected, indexed by incoming local id
506 */
507 struct GNUNET_CONTAINER_MultiHashMap *ignore_tunnels;
508 /** 454 /**
509 * Handle to communicate with the client 455 * Handle to communicate with the client
510 */ 456 */
@@ -810,15 +756,6 @@ tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
810 756
811 757
812/** 758/**
813 * Delete an active client from the tunnel.
814 *
815 * @param t Tunnel.
816 * @param c Client.
817 */
818static void
819tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
820
821/**
822 * Notify a tunnel that a connection has broken that affects at least 759 * Notify a tunnel that a connection has broken that affects at least
823 * some of its peers. 760 * some of its peers.
824 * 761 *
@@ -835,28 +772,6 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
835 772
836 773
837/** 774/**
838 * Get the current ack value for a tunnel, for data going from root to leaves,
839 * taking in account the tunnel mode and the status of all children and clients.
840 *
841 * @param t Tunnel.
842 *
843 * @return Maximum PID allowed.
844 */
845static uint32_t
846tunnel_get_fwd_ack (struct MeshTunnel *t);
847
848
849/**
850 * Add a client to a tunnel, initializing all needed data structures.
851 *
852 * @param t Tunnel to which add the client.
853 * @param c Client which to add to the tunnel.
854 */
855static void
856tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c);
857
858
859/**
860 * Use the given path for the tunnel. 775 * Use the given path for the tunnel.
861 * 776 *
862 * @param t Tunnel to update. 777 * @param t Tunnel to update.
@@ -999,103 +914,10 @@ client_get (struct GNUNET_SERVER_Client *client)
999 914
1000 915
1001/** 916/**
1002 * Checks if a given client has subscribed to certain message type
1003 *
1004 * @param message_type Type of message to check
1005 * @param c Client to check
1006 *
1007 * @return GNUNET_YES or GNUNET_NO, depending on subscription status
1008 *
1009 * A real hash function alone takes 8-10us out of the ~55us for the whole
1010 * process of retransmitting the message from one local client to another.
1011 * GMC_hash32 aim to imporve this speed.
1012 */
1013static int
1014client_is_subscribed (uint16_t message_type, struct MeshClient *c)
1015{
1016 struct GNUNET_HashCode hc;
1017
1018 if (NULL == c->types)
1019 return GNUNET_NO;
1020
1021 GMC_hash32 ((uint32_t) message_type, &hc);
1022 return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
1023}
1024
1025
1026/**
1027 * Check whether client wants traffic from a tunnel.
1028 *
1029 * @param c Client to check.
1030 * @param t Tunnel to be found.
1031 *
1032 * @return GNUNET_YES if client knows tunnel.
1033 *
1034 * TODO look in client hashmap
1035 */
1036static int
1037client_wants_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1038{
1039 unsigned int i;
1040
1041 for (i = 0; i < t->nclients; i++)
1042 if (t->clients[i] == c)
1043 return GNUNET_YES;
1044 return GNUNET_NO;
1045}
1046
1047
1048/**
1049 * Check whether client has been informed about a tunnel.
1050 *
1051 * @param c Client to check.
1052 * @param t Tunnel to be found.
1053 *
1054 * @return GNUNET_YES if client knows tunnel.
1055 *
1056 * TODO look in client hashmap
1057 */
1058static int
1059client_knows_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1060{
1061 unsigned int i;
1062
1063 for (i = 0; i < t->nignore; i++)
1064 if (t->ignore[i] == c)
1065 return GNUNET_YES;
1066 return client_wants_tunnel(c, t);
1067}
1068
1069
1070/**
1071 * Marks a client as uninterested in traffic from the tunnel, updating both
1072 * client and tunnel to reflect this.
1073 *
1074 * @param c Client that doesn't want traffic anymore.
1075 * @param t Tunnel which should be ignored.
1076 *
1077 * FIXME when to delete an incoming tunnel?
1078 */
1079static void
1080client_ignore_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1081{
1082 struct GNUNET_HashCode hash;
1083
1084 GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1085 GNUNET_break (GNUNET_YES ==
1086 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1087 &hash, t));
1088 GNUNET_break (GNUNET_YES ==
1089 GNUNET_CONTAINER_multihashmap_put (c->ignore_tunnels, &hash, t,
1090 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1091 tunnel_delete_active_client (t, c);
1092 GNUNET_array_append (t->ignore, t->nignore, c);
1093}
1094
1095
1096/**
1097 * Deletes a tunnel from a client (either owner or destination). To be used on 917 * Deletes a tunnel from a client (either owner or destination). To be used on
1098 * tunnel destroy, otherwise, use client_ignore_tunnel. 918 * tunnel destroy.
919 *
920 * FIXME use fast hash
1099 * 921 *
1100 * @param c Client whose tunnel to delete. 922 * @param c Client whose tunnel to delete.
1101 * @param t Tunnel which should be deleted. 923 * @param t Tunnel which should be deleted.
@@ -1113,117 +935,18 @@ client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
1113 &hash, 935 &hash,
1114 t)); 936 t));
1115 } 937 }
1116 else 938 else if (c == t->client)
1117 { 939 {
1118 GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); 940 GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
1119 // FIXME XOR?
1120 GNUNET_assert (GNUNET_YES == 941 GNUNET_assert (GNUNET_YES ==
1121 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, 942 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
1122 &hash, 943 &hash,
1123 t) ||
1124 GNUNET_YES ==
1125 GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels,
1126 &hash,
1127 t)); 944 t));
1128 } 945 }
1129} 946 else
1130
1131
1132/**
1133 * Send the message to all clients that have subscribed to its type
1134 *
1135 * @param msg Pointer to the message itself
1136 * @param payload Pointer to the payload of the message.
1137 * @param t The tunnel to whose clients this message goes.
1138 *
1139 * @return number of clients this message was sent to
1140 */
1141static unsigned int
1142send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
1143 const struct GNUNET_MessageHeader *payload,
1144 struct MeshTunnel *t)
1145{
1146 struct MeshClient *c;
1147 MESH_TunnelNumber *tid;
1148 unsigned int count;
1149 uint16_t type;
1150 char cbuf[htons (msg->size)];
1151
1152 type = ntohs (payload->type);
1153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending to clients...\n");
1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message of type %s\n",
1155 GNUNET_MESH_DEBUG_M2S (type));
1156
1157 memcpy (cbuf, msg, sizeof (cbuf));
1158 switch (htons (msg->type))
1159 {
1160 struct GNUNET_MESH_Unicast *uc;
1161 struct GNUNET_MESH_ToOrigin *to;
1162
1163 case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
1164 uc = (struct GNUNET_MESH_Unicast *) cbuf;
1165 tid = &uc->tid;
1166 break;
1167 case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
1168 to = (struct GNUNET_MESH_ToOrigin *) cbuf;
1169 tid = &to->tid;
1170 break;
1171 default:
1172 GNUNET_break (0);
1173 return 0;
1174 }
1175
1176 for (count = 0, c = clients_head; c != NULL; c = c->next)
1177 { 947 {
1178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client %u\n", c->id); 948 GNUNET_break (0);
1179 if (client_is_subscribed (type, c))
1180 {
1181 if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN)
1182 {
1183 if (c != t->owner)
1184 continue;
1185 *tid = htonl (t->local_tid);
1186 }
1187 else
1188 {
1189 if (GNUNET_NO == client_knows_tunnel (c, t))
1190 {
1191 /* This client doesn't know the tunnel */
1192 struct GNUNET_MESH_TunnelNotification tmsg;
1193 struct GNUNET_HashCode hash;
1194
1195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending tunnel create\n");
1196 tmsg.header.size = htons (sizeof (tmsg));
1197 tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
1198 GNUNET_PEER_resolve (t->id.oid, &tmsg.peer);
1199 tmsg.tunnel_id = htonl (t->local_tid_dest);
1200 tmsg.opt = 0;
1201 if (GNUNET_YES == t->nobuffer)
1202 tmsg.opt |= MESH_TUNNEL_OPT_NOBUFFER;
1203 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1204 &tmsg.header, GNUNET_NO);
1205 tunnel_add_client (t, c);
1206 GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1207 &hash);
1208 GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (
1209 c->incoming_tunnels, &hash, t,
1210 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1211 }
1212 *tid = htonl (t->local_tid_dest);
1213 }
1214
1215 /* Check if the client wants to get traffic from the tunnel */
1216 if (GNUNET_NO == client_wants_tunnel(c, t))
1217 continue;
1218 count++;
1219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending\n");
1220 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1221 (struct GNUNET_MessageHeader
1222 *) cbuf, GNUNET_NO);
1223 }
1224 } 949 }
1225
1226 return count;
1227} 950}
1228 951
1229 952
@@ -1234,45 +957,17 @@ send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
1234 * @param t Tunnel that was destroyed. 957 * @param t Tunnel that was destroyed.
1235 */ 958 */
1236static void 959static void
1237send_clients_tunnel_destroy (struct MeshTunnel *t) 960send_client_tunnel_destroy (struct MeshTunnel *t)
1238{ 961{
1239 struct GNUNET_MESH_TunnelMessage msg; 962 struct GNUNET_MESH_TunnelMessage msg;
1240 963
964 if (NULL == t->client)
965 return;
1241 msg.header.size = htons (sizeof (msg)); 966 msg.header.size = htons (sizeof (msg));
1242 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY); 967 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1243 msg.tunnel_id = htonl (t->local_tid_dest); 968 msg.tunnel_id = htonl (t->local_tid_dest);
1244 GNUNET_SERVER_notification_context_broadcast (nc, &msg.header, GNUNET_NO); 969 GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
1245} 970 &msg.header, GNUNET_NO);
1246
1247
1248/**
1249 * Notify clients of tunnel disconnections, if needed.
1250 * In case the origin disconnects, the destination clients get a tunnel destroy
1251 * notification. If the last destination disconnects (only one remaining client
1252 * in tunnel), the origin gets a (local ID) peer disconnected.
1253 * Note that the function must be called BEFORE removing the client from
1254 * the tunnel.
1255 *
1256 * @param t Tunnel that was destroyed.
1257 * @param c Client that disconnected.
1258 */
1259static void
1260send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c)
1261{
1262 unsigned int i;
1263
1264 if (c == t->owner)
1265 {
1266 struct GNUNET_MESH_TunnelMessage msg;
1267
1268 msg.header.size = htons (sizeof (msg));
1269 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
1270 msg.tunnel_id = htonl (t->local_tid_dest);
1271 for (i = 0; i < t->nclients; i++)
1272 GNUNET_SERVER_notification_context_unicast (nc, t->clients[i]->handle,
1273 &msg.header, GNUNET_NO);
1274 }
1275 // FIXME when to disconnect an incoming tunnel?
1276} 971}
1277 972
1278 973
@@ -2084,81 +1779,34 @@ tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
2084 1779
2085 1780
2086/** 1781/**
2087 * Delete an active client from the tunnel. 1782 * Add a client to a tunnel, initializing all needed data structures.
1783 *
1784 * FIXME: make static after implementing port numbers
2088 * 1785 *
2089 * @param t Tunnel. 1786 * @param t Tunnel to which add the client.
2090 * @param c Client. 1787 * @param c Client which to add to the tunnel.
2091 */ 1788 */
2092static void 1789void
2093tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c) 1790tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
2094{ 1791{
2095 unsigned int i; 1792 if (NULL != t->client)
2096
2097 for (i = 0; i < t->nclients; i++)
2098 { 1793 {
2099 if (t->clients[i] == c) 1794 GNUNET_break(0);
2100 { 1795 return;
2101 t->clients[i] = t->clients[t->nclients - 1];
2102 t->clients_fc[i] = t->clients_fc[t->nclients - 1];
2103 GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1);
2104 t->nclients++;
2105 GNUNET_array_grow (t->clients_fc, t->nclients, t->nclients - 1);
2106 break;
2107 }
2108 } 1796 }
2109} 1797 if (0 != t->next_hop)
2110
2111
2112/**
2113 * Delete an ignored client from the tunnel.
2114 *
2115 * @param t Tunnel.
2116 * @param c Client.
2117 */
2118static void
2119tunnel_delete_ignored_client (struct MeshTunnel *t, const struct MeshClient *c)
2120{
2121 unsigned int i;
2122
2123 for (i = 0; i < t->nignore; i++)
2124 { 1798 {
2125 if (t->ignore[i] == c) 1799 GNUNET_break(0);
2126 { 1800 return;
2127 t->ignore[i] = t->ignore[t->nignore - 1];
2128 GNUNET_array_grow (t->ignore, t->nignore, t->nignore - 1);
2129 break;
2130 }
2131 } 1801 }
2132} 1802 t->client = c;
2133 1803 t->next_fc.last_ack_sent = t->prev_fc.last_pid_recv + 1;
2134 1804 t->next_fc.last_pid_sent = t->prev_fc.last_pid_recv;
2135/** 1805 t->next_fc.last_ack_recv = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
2136 * Delete a client from the tunnel. It should be only done on 1806 t->next_fc.last_pid_recv = (uint32_t) -1; /* Expected next: 0 */
2137 * client disconnection, otherwise use client_ignore_tunnel. 1807 t->next_fc.poll_task = GNUNET_SCHEDULER_NO_TASK;
2138 * 1808 t->next_fc.poll_time = GNUNET_TIME_UNIT_SECONDS;
2139 * @param t Tunnel. 1809 t->next_fc.queue_n = 0;
2140 * @param c Client.
2141 */
2142static void
2143tunnel_delete_client (struct MeshTunnel *t, const struct MeshClient *c)
2144{
2145 tunnel_delete_ignored_client (t, c);
2146 tunnel_delete_active_client (t, c);
2147}
2148
2149/* FIXME check initial values */
2150static void
2151tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
2152{
2153 struct MeshTunnelClientInfo clinfo;
2154
2155 GNUNET_array_append (t->clients, t->nclients, c);
2156 clinfo.fwd_ack = t->prev_fc.last_pid_recv + 1;
2157 clinfo.fwd_pid = t->prev_fc.last_pid_recv;
2158 clinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
2159 clinfo.bck_pid = (uint32_t) -1; /* Expected next: 0 */
2160 t->nclients--; /* Double append */
2161 GNUNET_array_append (t->clients_fc, t->nclients, clinfo);
2162} 1810}
2163 1811
2164 1812
@@ -2238,134 +1886,6 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
2238 1886
2239 1887
2240/** 1888/**
2241 * Get the Flow Control info of a client.
2242 *
2243 * @param t Tunnel on which to look.
2244 * @param c Client whose ACK to get.
2245 *
2246 * @return ACK value.
2247 */
2248static struct MeshTunnelClientInfo *
2249tunnel_get_client_fc (struct MeshTunnel *t,
2250 struct MeshClient *c)
2251{
2252 unsigned int i;
2253
2254 for (i = 0; i < t->nclients; i++)
2255 {
2256 if (t->clients[i] != c)
2257 continue;
2258 return &t->clients_fc[i];
2259 }
2260 GNUNET_assert (0);
2261 return NULL; // avoid compiler / coverity complaints
2262}
2263
2264
2265/**
2266 * Set the FWD ACK value of a client in a particular tunnel.
2267 *
2268 * @param t Tunnel affected.
2269 * @param c Client whose ACK to set.
2270 * @param ack ACK value.
2271 */
2272static void
2273tunnel_set_client_fwd_ack (struct MeshTunnel *t,
2274 struct MeshClient *c,
2275 uint32_t ack)
2276{
2277 unsigned int i;
2278
2279 for (i = 0; i < t->nclients; i++)
2280 {
2281 if (t->clients[i] != c)
2282 continue;
2283 t->clients_fc[i].fwd_ack = ack;
2284 return;
2285 }
2286 GNUNET_break (0);
2287}
2288
2289
2290/**
2291 * Get the highest ACK value of all clients in a particular tunnel,
2292 * according to the buffering/speed settings.
2293 *
2294 * @param t Tunnel on which to look.
2295 *
2296 * @return Corresponding ACK value (max uint32_t).
2297 * If no clients are suscribed, -1LL.
2298 */
2299static int64_t
2300tunnel_get_clients_fwd_ack (struct MeshTunnel *t)
2301{
2302 unsigned int i;
2303 int64_t ack;
2304
2305 if (0 == t->nclients)
2306 {
2307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2308 " tunnel has no clients, no FWD ACK\n");
2309 return -1LL;
2310 }
2311
2312 for (ack = -1LL, i = 0; i < t->nclients; i++)
2313 {
2314 if (-1LL == ack ||
2315 GNUNET_YES == GMC_is_pid_bigger (ack, t->clients_fc[i].fwd_ack))
2316 {
2317 ack = t->clients_fc[i].fwd_ack;
2318 }
2319 }
2320
2321 if (GNUNET_YES == t->nobuffer &&
2322 GMC_is_pid_bigger(ack, t->prev_fc.last_pid_recv))
2323 ack = (uint32_t) t->prev_fc.last_pid_recv + 1; // Might overflow, it's ok.
2324
2325 return (uint32_t) ack;
2326}
2327
2328
2329/** FIXME
2330 * Get the current fwd ack value for a tunnel, taking in account the tunnel
2331 * mode and the status of all children nodes.
2332 *
2333 * @param t Tunnel.
2334 *
2335 * @return Maximum PID allowed.
2336 */
2337static uint32_t
2338tunnel_get_fwd_ack (struct MeshTunnel *t)
2339{
2340 uint32_t ack;
2341 uint32_t buffer_free;
2342 int64_t client_ack;
2343
2344 buffer_free = t->queue_max - t->next_fc.queue_n;
2345 client_ack = tunnel_get_clients_fwd_ack (t);
2346 if (GNUNET_YES == t->nobuffer)
2347 {
2348 ack = t->prev_fc.last_ack_sent;
2349 }
2350 else
2351 {
2352 ack = t->prev_fc.last_ack_sent + buffer_free; // Overflow? OK!
2353 }
2354 if (-1LL == client_ack)
2355 {
2356 client_ack = ack;
2357 }
2358 /* FIXME check */
2359 ack = GMC_max_pid ((uint32_t) client_ack, ack);
2360
2361 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2362 "c %u, bf %u, cl %lld, ACK: %u\n",
2363 t->prev_fc.last_ack_sent, buffer_free, client_ack, ack);
2364 return ack;
2365}
2366
2367
2368/**
2369 * Build a local ACK message and send it to a local client. 1889 * Build a local ACK message and send it to a local client.
2370 * 1890 *
2371 * @param t Tunnel on which to send the ACK. 1891 * @param t Tunnel on which to send the ACK.
@@ -2410,36 +1930,6 @@ send_ack (struct MeshTunnel *t, GNUNET_PEER_Id peer, uint32_t ack)
2410 1930
2411 1931
2412/** 1932/**
2413 * Notify a the owner of a tunnel about how many more
2414 * payload packages will we accept on a given tunnel.
2415 *
2416 * @param t Tunnel on which to send the ACK.
2417 */
2418static void
2419tunnel_send_client_fwd_ack (struct MeshTunnel *t)
2420{
2421 uint32_t ack;
2422
2423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2424 "Sending client FWD ACK on tunnel %X\n",
2425 t->local_tid);
2426
2427 ack = tunnel_get_fwd_ack (t);
2428
2429 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
2430 if (t->prev_fc.last_ack_sent == ack)
2431 {
2432 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " same as last, not sending!\n");
2433 return;
2434 }
2435
2436 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n");
2437 t->prev_fc.last_ack_sent = ack;
2438 send_local_ack (t, t->owner, ack);
2439}
2440
2441
2442/**
2443 * Send an ACK informing the predecessor about the available buffer space. 1933 * Send an ACK informing the predecessor about the available buffer space.
2444 * In case there is no predecessor, inform the owning client. 1934 * In case there is no predecessor, inform the owning client.
2445 * If buffering is off, send only on behalf of children or self if endpoint. 1935 * If buffering is off, send only on behalf of children or self if endpoint.
@@ -2455,11 +1945,6 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
2455{ 1945{
2456 uint32_t ack; 1946 uint32_t ack;
2457 1947
2458 if (NULL != t->owner)
2459 {
2460 tunnel_send_client_fwd_ack (t);
2461 return;
2462 }
2463 /* Is it after unicast retransmission? */ 1948 /* Is it after unicast retransmission? */
2464 switch (type) 1949 switch (type)
2465 { 1950 {
@@ -2498,112 +1983,28 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
2498 } 1983 }
2499 1984
2500 /* Ok, ACK might be necessary, what PID to ACK? */ 1985 /* Ok, ACK might be necessary, what PID to ACK? */
2501 ack = tunnel_get_fwd_ack (t); 1986 ack = t->prev_fc.last_pid_recv + t->queue_max - t->next_fc.queue_n;
2502 if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack) 1987 if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack)
2503 { 1988 {
2504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not ready\n"); 1989 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
2505 return; 1990 return;
2506 } 1991 }
2507 1992
2508 t->prev_fc.last_ack_sent = ack; 1993 t->prev_fc.last_ack_sent = ack;
2509 send_ack (t, t->prev_hop, ack); 1994 if (0 != t->prev_hop)
1995 send_ack (t, t->prev_hop, ack);
1996 else if (NULL != t->owner)
1997 send_local_ack (t, t->owner, ack);
1998 else
1999 GNUNET_break (0);
2510 debug_fwd_ack++; 2000 debug_fwd_ack++;
2511 t->force_ack = GNUNET_NO; 2001 t->force_ack = GNUNET_NO;
2512} 2002}
2513 2003
2514 2004
2515/** 2005/**
2516 * Send a child node a BCK ACK to allow him to send more to_origin data. 2006 * Send an ACK informing the children node/client about the available
2517 * 2007 * buffer space.
2518 * @param t Tunnel.
2519 * @param id Id of the child node.
2520 */
2521static void
2522tunnel_send_mesh_bck_ack (struct MeshTunnel *t,
2523 GNUNET_PEER_Id peer)
2524{
2525 uint32_t ack = 0; // FIXME
2526
2527 ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
2528
2529 if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
2530 {
2531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2532 " Not sending ACK, not needed\n");
2533 return;
2534 }
2535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2536 " Sending BCK ACK %u (last sent: %u)\n",
2537 ack, t->next_fc.last_ack_sent);
2538 t->next_fc.last_ack_sent = ack;
2539
2540 send_ack (t, peer, ack);
2541}
2542
2543
2544/**
2545 * @brief Send BCK ACKs to clients to allow them more to_origin traffic
2546 *
2547 * Iterates over all clients and sends BCK ACKs to the ones that need it.
2548 *
2549 * FIXME fc: what happens if we have 2 clients but q_size is 1?
2550 * - implement a size 1 buffer in each client_fc AND children_fc
2551 * to hold at least 1 message per "child".
2552 * problem: violates no buffer policy
2553 * - ack 0 and make "children" poll for transmission slots
2554 * problem: big overhead, extra latency even in low traffic
2555 * settings
2556 *
2557 * @param t Tunnel on which to send the BCK ACKs.
2558 */
2559static void
2560tunnel_send_clients_bck_ack (struct MeshTunnel *t)
2561{
2562 unsigned int i;
2563 unsigned int tunnel_delta;
2564
2565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Sending BCK ACK to clients\n");
2566
2567 tunnel_delta = t->queue_max - t->next_fc.queue_n;
2568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " tunnel delta: %u\n", tunnel_delta);
2569
2570 /* Find client whom to allow to send to origin (with lowest buffer space) */
2571 for (i = 0; i < t->nclients; i++)
2572 {
2573 struct MeshTunnelClientInfo *clinfo;
2574 unsigned int delta;
2575
2576 clinfo = &t->clients_fc[i];
2577 delta = clinfo->bck_ack - clinfo->bck_pid;
2578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client %u delta: %u\n",
2579 t->clients[i]->id, delta);
2580
2581 if ((GNUNET_NO == t->nobuffer && tunnel_delta > delta) ||
2582 (GNUNET_YES == t->nobuffer && 0 == delta))
2583 {
2584 uint32_t ack;
2585
2586 ack = clinfo->bck_pid;
2587 ack += t->nobuffer ? 1 : tunnel_delta;
2588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2589 " sending ack to client %u: %u\n",
2590 t->clients[i]->id, ack);
2591 send_local_ack (t, t->clients[i], ack);
2592 clinfo->bck_ack = ack;
2593 }
2594 else
2595 {
2596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2597 " not sending ack to client %u (td %u, d %u)\n",
2598 t->clients[i]->id, tunnel_delta, delta);
2599 }
2600 }
2601}
2602
2603
2604/**
2605 * Send an ACK informing the children nodes and destination clients about
2606 * the available buffer space.
2607 * If buffering is off, send only on behalf of root (can be self). 2008 * If buffering is off, send only on behalf of root (can be self).
2608 * If buffering is on, send when sent to predecessor and buffer space is free. 2009 * If buffering is on, send when sent to predecessor and buffer space is free.
2609 * Note that although the name is bck_ack, the BCK mean backwards *traffic*, 2010 * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
@@ -2615,6 +2016,7 @@ tunnel_send_clients_bck_ack (struct MeshTunnel *t)
2615static void 2016static void
2616tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type) 2017tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
2617{ 2018{
2019 uint32_t ack;
2618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2619 "Sending BCK ACK on tunnel %u [%u] due to %s\n", 2021 "Sending BCK ACK on tunnel %u [%u] due to %s\n",
2620 t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type)); 2022 t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
@@ -2625,7 +2027,7 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
2625 if (GNUNET_YES == t->nobuffer) 2027 if (GNUNET_YES == t->nobuffer)
2626 { 2028 {
2627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2029 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2628 " Not sending ACK, nobuffer\n"); 2030 " Not sending ACK, nobuffer + traffic\n");
2629 return; 2031 return;
2630 } 2032 }
2631 break; 2033 break;
@@ -2639,8 +2041,25 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
2639 GNUNET_break (0); 2041 GNUNET_break (0);
2640 } 2042 }
2641 2043
2642 tunnel_send_clients_bck_ack (t); 2044 ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
2643 tunnel_send_mesh_bck_ack (t, t->next_hop); 2045
2046 if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
2047 {
2048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2049 " Not sending ACK, not needed\n");
2050 return;
2051 }
2052 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2053 " Sending BCK ACK %u (last sent: %u)\n",
2054 ack, t->next_fc.last_ack_sent);
2055 t->next_fc.last_ack_sent = ack;
2056
2057 if (0 != t->next_hop)
2058 send_ack (t, t->next_hop, ack);
2059 else if (NULL != t->client)
2060 send_local_ack (t, t->client, ack);
2061 else
2062 GNUNET_break (0);
2644 t->force_ack = GNUNET_NO; 2063 t->force_ack = GNUNET_NO;
2645} 2064}
2646 2065
@@ -2780,7 +2199,6 @@ tunnel_destroy (struct MeshTunnel *t)
2780{ 2199{
2781 struct MeshClient *c; 2200 struct MeshClient *c;
2782 struct GNUNET_HashCode hash; 2201 struct GNUNET_HashCode hash;
2783 unsigned int i;
2784 int r; 2202 int r;
2785 2203
2786 if (NULL == t) 2204 if (NULL == t)
@@ -2807,6 +2225,7 @@ tunnel_destroy (struct MeshTunnel *t)
2807 r = GNUNET_SYSERR; 2225 r = GNUNET_SYSERR;
2808 } 2226 }
2809 2227
2228 // FIXME use fast hash
2810 if (NULL != c) 2229 if (NULL != c)
2811 { 2230 {
2812 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); 2231 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
@@ -2818,10 +2237,10 @@ tunnel_destroy (struct MeshTunnel *t)
2818 } 2237 }
2819 } 2238 }
2820 2239
2821 GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash); 2240 // FIXME use fast hash
2822 for (i = 0; i < t->nclients; i++) 2241 if (NULL != t->client)
2823 { 2242 {
2824 c = t->clients[i]; 2243 GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
2825 if (GNUNET_YES != 2244 if (GNUNET_YES !=
2826 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t)) 2245 GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
2827 { 2246 {
@@ -2829,22 +2248,13 @@ tunnel_destroy (struct MeshTunnel *t)
2829 r = GNUNET_SYSERR; 2248 r = GNUNET_SYSERR;
2830 } 2249 }
2831 } 2250 }
2832 for (i = 0; i < t->nignore; i++) 2251
2252 if (GNUNET_YES !=
2253 GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t))
2833 { 2254 {
2834 c = t->ignore[i]; 2255 GNUNET_break (0);
2835 if (GNUNET_YES != 2256 r = GNUNET_SYSERR;
2836 GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels, &hash, t))
2837 {
2838 GNUNET_break (0);
2839 r = GNUNET_SYSERR;
2840 }
2841 } 2257 }
2842
2843 (void) GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t);
2844 GNUNET_free_non_null (t->clients);
2845 GNUNET_free_non_null (t->ignore);
2846 GNUNET_free_non_null (t->clients_fc);
2847
2848 peer_cancel_queues (t->next_hop, t); 2258 peer_cancel_queues (t->next_hop, t);
2849 peer_cancel_queues (t->prev_hop, t); 2259 peer_cancel_queues (t->prev_hop, t);
2850 2260
@@ -2862,22 +2272,11 @@ tunnel_destroy (struct MeshTunnel *t)
2862/** 2272/**
2863 * Tunnel is empty: destroy it. 2273 * Tunnel is empty: destroy it.
2864 * 2274 *
2865 * @param cls Closure (Tunnel). 2275 * @param t Tunnel to destroy.
2866 * @param tc TaskContext.
2867 */ 2276 */
2868static void 2277static void
2869tunnel_destroy_empty_delayed (void *cls, 2278tunnel_destroy_empty (struct MeshTunnel *t)
2870 const struct GNUNET_SCHEDULER_TaskContext *tc)
2871{ 2279{
2872 struct MeshTunnel *t = cls;
2873
2874 t->delayed_destroy = GNUNET_SCHEDULER_NO_TASK;
2875 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
2876 return;
2877
2878 if (0 != t->nclients)
2879 return;
2880
2881 #if MESH_DEBUG 2280 #if MESH_DEBUG
2882 { 2281 {
2883 struct GNUNET_PeerIdentity id; 2282 struct GNUNET_PeerIdentity id;
@@ -2898,40 +2297,6 @@ tunnel_destroy_empty_delayed (void *cls,
2898 2297
2899 2298
2900/** 2299/**
2901 * Schedule tunnel destruction if is empty and no new traffic comes in a time.
2902 *
2903 * @param t Tunnel to destroy if empty.
2904 */
2905static void
2906tunnel_destroy_empty (struct MeshTunnel *t)
2907{
2908 if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy ||
2909 0 != t->nclients)
2910 {
2911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%u %u\n",
2912 t->delayed_destroy, t->nclients);
2913 return;
2914 }
2915
2916 #if MESH_DEBUG
2917 {
2918 struct GNUNET_PeerIdentity id;
2919
2920 GNUNET_PEER_resolve (t->id.oid, &id);
2921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2922 "scheduling destruction of empty tunnel %s [%X]\n",
2923 GNUNET_i2s (&id), t->id.tid);
2924 }
2925 #endif
2926
2927 t->delayed_destroy =
2928 GNUNET_SCHEDULER_add_delayed (TUNNEL_DESTROY_EMPTY_TIME,
2929 &tunnel_destroy_empty_delayed,
2930 t);
2931}
2932
2933
2934/**
2935 * Create a new tunnel 2300 * Create a new tunnel
2936 * 2301 *
2937 * @param owner Who is the owner of the tunnel (short ID). 2302 * @param owner Who is the owner of the tunnel (short ID).
@@ -3024,11 +2389,10 @@ tunnel_destroy_iterator (void *cls,
3024 struct MeshTunnel *t = value; 2389 struct MeshTunnel *t = value;
3025 struct MeshClient *c = cls; 2390 struct MeshClient *c = cls;
3026 2391
3027 send_client_tunnel_disconnect (t, c); 2392 send_client_tunnel_destroy (t);
3028 if (c != t->owner) 2393 if (c != t->owner)
3029 { 2394 {
3030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %u is destination.\n", c->id); 2395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %u is destination.\n", c->id);
3031 tunnel_delete_client (t, c);
3032 client_delete_tunnel (c, t); 2396 client_delete_tunnel (c, t);
3033 tunnel_destroy_empty (t); 2397 tunnel_destroy_empty (t);
3034 return GNUNET_OK; 2398 return GNUNET_OK;
@@ -3060,10 +2424,11 @@ tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3060 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2424 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3061 "Tunnel %s [%X] timed out. Destroying.\n", 2425 "Tunnel %s [%X] timed out. Destroying.\n",
3062 GNUNET_i2s(&id), t->id.tid); 2426 GNUNET_i2s(&id), t->id.tid);
3063 send_clients_tunnel_destroy (t); 2427 send_client_tunnel_destroy (t);
3064 tunnel_destroy (t); 2428 tunnel_destroy (t);
3065} 2429}
3066 2430
2431
3067/** 2432/**
3068 * Resets the tunnel timeout. Starts it if no timeout was running. 2433 * Resets the tunnel timeout. Starts it if no timeout was running.
3069 * 2434 *
@@ -3833,7 +3198,7 @@ handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3833 if (own_pos < path->length - 1) 3198 if (own_pos < path->length - 1)
3834 send_prebuilt_message (message, path->peers[own_pos + 1], t); 3199 send_prebuilt_message (message, path->peers[own_pos + 1], t);
3835 else 3200 else
3836 send_client_tunnel_disconnect(t, NULL); 3201 send_client_tunnel_destroy (t);
3837 3202
3838// tunnel_delete_peer (t, path->peers[path->length - 1]); FIXME 3203// tunnel_delete_peer (t, path->peers[path->length - 1]); FIXME
3839 path_destroy (path); 3204 path_destroy (path);
@@ -3894,7 +3259,6 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3894{ 3259{
3895 struct GNUNET_MESH_TunnelDestroy *msg; 3260 struct GNUNET_MESH_TunnelDestroy *msg;
3896 struct MeshTunnel *t; 3261 struct MeshTunnel *t;
3897 GNUNET_PEER_Id pid;
3898 3262
3899 msg = (struct GNUNET_MESH_TunnelDestroy *) message; 3263 msg = (struct GNUNET_MESH_TunnelDestroy *) message;
3900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3915,20 +3279,13 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
3915 1, GNUNET_NO); 3279 1, GNUNET_NO);
3916 return GNUNET_OK; 3280 return GNUNET_OK;
3917 } 3281 }
3918 pid = GNUNET_PEER_search (peer); 3282 // TODO check owner's signature
3919 if (pid != t->prev_hop && 0 < t->nclients)
3920 {
3921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3922 "still in use by %u clients\n",
3923 t->nclients);
3924 return GNUNET_OK;
3925 }
3926 if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) 3283 if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
3927 { 3284 {
3928 /* Tunnel was incoming, notify clients */ 3285 /* Tunnel was incoming, notify clients */
3929 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n", 3286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
3930 t->local_tid, t->local_tid_dest); 3287 t->local_tid, t->local_tid_dest);
3931 send_clients_tunnel_destroy (t); 3288 send_client_tunnel_destroy (t);
3932 } 3289 }
3933 tunnel_send_destroy (t); 3290 tunnel_send_destroy (t);
3934 t->destroy = GNUNET_YES; 3291 t->destroy = GNUNET_YES;
@@ -4008,13 +3365,24 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
4008 tunnel_reset_timeout (t); 3365 tunnel_reset_timeout (t);
4009 if (t->dest == myid) 3366 if (t->dest == myid)
4010 { 3367 {
3368 if (NULL == t->client)
3369 {
3370 GNUNET_break (0);
3371 return GNUNET_OK;
3372 }
4011 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4012 " it's for us! sending to clients...\n"); 3374 " it's for us! sending to clients...\n");
4013 GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO); 3375 GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
4014 send_subscribed_clients (message, &msg[1].header, t); 3376 GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
3377 message, GNUNET_NO);
4015 tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST); 3378 tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
4016 return GNUNET_OK; 3379 return GNUNET_OK;
4017 } 3380 }
3381 if (0 == t->next_hop)
3382 {
3383 GNUNET_break (0);
3384 return GNUNET_OK;
3385 }
4018 ttl = ntohl (msg->ttl); 3386 ttl = ntohl (msg->ttl);
4019 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl); 3387 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
4020 if (ttl == 0) 3388 if (ttl == 0)
@@ -4585,11 +3953,8 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
4585 &tunnel_destroy_iterator, c); 3953 &tunnel_destroy_iterator, c);
4586 GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels, 3954 GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
4587 &tunnel_destroy_iterator, c); 3955 &tunnel_destroy_iterator, c);
4588 GNUNET_CONTAINER_multihashmap_iterate (c->ignore_tunnels,
4589 &tunnel_destroy_iterator, c);
4590 GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels); 3956 GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
4591 GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels); 3957 GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
4592 GNUNET_CONTAINER_multihashmap_destroy (c->ignore_tunnels);
4593 3958
4594 if (NULL != c->types) 3959 if (NULL != c->types)
4595 GNUNET_CONTAINER_multihashmap_destroy (c->types); 3960 GNUNET_CONTAINER_multihashmap_destroy (c->types);
@@ -4668,7 +4033,6 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
4668 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c); 4033 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
4669 c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 4034 c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4670 c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 4035 c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4671 c->ignore_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
4672 GNUNET_SERVER_notification_context_add (nc, client); 4036 GNUNET_SERVER_notification_context_add (nc, client);
4673 GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO); 4037 GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
4674 4038
@@ -4801,14 +4165,13 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
4801 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 4165 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
4802 return; 4166 return;
4803 } 4167 }
4804 if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) 4168 if (c == t->client)
4805 { 4169 {
4806 client_ignore_tunnel (c, t);
4807 tunnel_destroy_empty (t); 4170 tunnel_destroy_empty (t);
4808 GNUNET_SERVER_receive_done (client, GNUNET_OK); 4171 GNUNET_SERVER_receive_done (client, GNUNET_OK);
4809 return; 4172 return;
4810 } 4173 }
4811 send_client_tunnel_disconnect (t, c); 4174 send_client_tunnel_destroy (t);
4812 client_delete_tunnel (c, t); 4175 client_delete_tunnel (c, t);
4813 4176
4814 /* Don't try to ACK the client about the tunnel_destroy multicast packet */ 4177 /* Don't try to ACK the client about the tunnel_destroy multicast packet */
@@ -4985,7 +4348,7 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
4985 const struct GNUNET_MessageHeader *message) 4348 const struct GNUNET_MessageHeader *message)
4986{ 4349{
4987 struct GNUNET_MESH_ToOrigin *data_msg; 4350 struct GNUNET_MESH_ToOrigin *data_msg;
4988 struct MeshTunnelClientInfo *clinfo; 4351 struct MeshFlowControl *fc;
4989 struct MeshClient *c; 4352 struct MeshClient *c;
4990 struct MeshTunnel *t; 4353 struct MeshTunnel *t;
4991 MESH_TunnelNumber tid; 4354 MESH_TunnelNumber tid;
@@ -5034,7 +4397,7 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
5034 } 4397 }
5035 4398
5036 /* It should be sent by someone who has this as incoming tunnel. */ 4399 /* It should be sent by someone who has this as incoming tunnel. */
5037 if (GNUNET_NO == client_knows_tunnel (c, t)) 4400 if (t->client != c)
5038 { 4401 {
5039 GNUNET_break (0); 4402 GNUNET_break (0);
5040 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 4403 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -5042,18 +4405,18 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
5042 } 4405 }
5043 4406
5044 /* PID should be as expected */ 4407 /* PID should be as expected */
5045 clinfo = tunnel_get_client_fc (t, c); 4408 fc = &t->next_fc;
5046 if (ntohl (data_msg->pid) != clinfo->bck_pid + 1) 4409 if (ntohl (data_msg->pid) != fc->last_pid_recv + 1)
5047 { 4410 {
5048 GNUNET_break (0); 4411 GNUNET_break (0);
5049 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 4412 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5050 "To Origin PID, expected %u, got %u\n", 4413 "To Origin PID, expected %u, got %u\n",
5051 clinfo->bck_pid + 1, 4414 fc->last_pid_recv + 1,
5052 ntohl (data_msg->pid)); 4415 ntohl (data_msg->pid));
5053 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 4416 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
5054 return; 4417 return;
5055 } 4418 }
5056 clinfo->bck_pid++; 4419 fc->last_pid_recv++;
5057 4420
5058 /* Ok, everything is correct, send the message 4421 /* Ok, everything is correct, send the message
5059 * (pretend we got it from a mesh peer) 4422 * (pretend we got it from a mesh peer)
@@ -5063,8 +4426,8 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
5063 struct GNUNET_MESH_ToOrigin *copy; 4426 struct GNUNET_MESH_ToOrigin *copy;
5064 4427
5065 /* Work around 'const' limitation */ 4428 /* Work around 'const' limitation */
5066 copy = (struct GNUNET_MESH_ToOrigin *) buf;
5067 memcpy (buf, data_msg, size); 4429 memcpy (buf, data_msg, size);
4430 copy = (struct GNUNET_MESH_ToOrigin *) buf;
5068 GNUNET_PEER_resolve (t->id.oid, &copy->oid); 4431 GNUNET_PEER_resolve (t->id.oid, &copy->oid);
5069 copy->tid = htonl (t->id.tid); 4432 copy->tid = htonl (t->id.tid);
5070 copy->ttl = htonl (default_ttl); 4433 copy->ttl = htonl (default_ttl);
@@ -5126,16 +4489,16 @@ handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
5126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack); 4489 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
5127 4490
5128 /* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */ 4491 /* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
5129 if (NULL != t->owner && t->owner->handle == client) 4492 if (t->owner == c)
5130 { 4493 {
5131 /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */ 4494 /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
5132 t->next_fc.last_ack_sent = ack; 4495 t->prev_fc.last_ack_recv = ack;
5133 tunnel_send_bck_ack(t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK); 4496 tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5134 } 4497 }
5135 else 4498 else
5136 { 4499 {
5137 /* The client doesn't own the tunnel, this ACK is for FWD traffic. */ 4500 /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
5138 tunnel_set_client_fwd_ack (t, c, ack); 4501 t->next_fc.last_ack_recv = ack;
5139 tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK); 4502 tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
5140 } 4503 }
5141 4504