aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-08-02 02:51:45 +0000
committerBart Polot <bart@net.in.tum.de>2013-08-02 02:51:45 +0000
commitf05dffb9c72236f4628bf6dfcc718af55cdd5904 (patch)
treebd35d3b848c8f16642cf3e802ae0d095fdaba929 /src
parent6190a95ec24eed69b9657646e242d3eb92e602e3 (diff)
downloadgnunet-f05dffb9c72236f4628bf6dfcc718af55cdd5904.tar.gz
gnunet-f05dffb9c72236f4628bf6dfcc718af55cdd5904.zip
- handle connection_create
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh-enc.c304
1 files changed, 173 insertions, 131 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c
index 57bccb29b..7b6bdf34d 100644
--- a/src/mesh/gnunet-service-mesh-enc.c
+++ b/src/mesh/gnunet-service-mesh-enc.c
@@ -503,17 +503,17 @@ struct MeshConnection
503 struct MeshConnection *prev; 503 struct MeshConnection *prev;
504 504
505 /** 505 /**
506 * Tunnes this belongs to 506 * Tunnel this connection is part of.
507 */ 507 */
508 struct MeshTunnel2 *t; 508 struct MeshTunnel2 *t;
509 509
510 /** 510 /**
511 * Connection number 511 * Connection number.
512 */ 512 */
513 uint32_t id; 513 uint32_t id;
514 514
515 /** 515 /**
516 * State of the connection 516 * State of the connection.
517 */ 517 */
518 enum MeshConnectionState state; 518 enum MeshConnectionState state;
519 519
@@ -1446,13 +1446,13 @@ tunnel_decrypt (struct MeshTunnel2 *t,
1446 1446
1447 1447
1448/** 1448/**
1449 * Sends an already built message on a tunnel, properly registering 1449 * Sends an already built message on a connection, properly registering
1450 * all used resources. 1450 * all used resources.
1451 * 1451 *
1452 * @param message Message to send. Function makes a copy of it. 1452 * @param message Message to send. Function makes a copy of it.
1453 * If message is not hop-by-hop, decrements TTL of copy. 1453 * If message is not hop-by-hop, decrements TTL of copy.
1454 * @param c Connection on which this message is transmitted. 1454 * @param c Connection on which this message is transmitted.
1455 * @param ch Channel on which this message is transmitted. 1455 * @param ch Channel on which this message is transmitted, or NULL.
1456 * @param fwd Is this a fwd message? 1456 * @param fwd Is this a fwd message?
1457 */ 1457 */
1458static void 1458static void
@@ -1883,7 +1883,7 @@ peer_get (const struct GNUNET_PeerIdentity *peer_id)
1883 peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer_id->hashPubKey); 1883 peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer_id->hashPubKey);
1884 if (NULL == peer) 1884 if (NULL == peer)
1885 { 1885 {
1886 peer = (struct MeshPeer *) GNUNET_malloc (sizeof (struct MeshPeer)); 1886 peer = GNUNET_new (struct MeshPeer);
1887 if (GNUNET_CONTAINER_multihashmap_size (peers) > max_peers) 1887 if (GNUNET_CONTAINER_multihashmap_size (peers) > max_peers)
1888 { 1888 {
1889 GNUNET_CONTAINER_multihashmap_iterate (peers, 1889 GNUNET_CONTAINER_multihashmap_iterate (peers,
@@ -3438,6 +3438,109 @@ channel_send_destroy (struct MeshChannel *ch)
3438 3438
3439 3439
3440/** 3440/**
3441 * Create a tunnel.
3442 *
3443 * @param tid Tunnel ID.
3444 */
3445static struct MeshTunnel2 *
3446tunnel_new (struct GNUNET_HashCode *tid)
3447{
3448 struct MeshTunnel2 *t;
3449
3450 t = GNUNET_new (struct MeshTunnel2);
3451 t->id = *tid;
3452 if (GNUNET_OK !=
3453 GNUNET_CONTAINER_multihashmap_put (tunnels, tid, t,
3454 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
3455 {
3456 GNUNET_break (0);
3457 tunnel_destroy (t);
3458 return NULL;
3459 }
3460
3461 return t;
3462}
3463
3464
3465/**
3466 * Find a tunnel.
3467 *
3468 * @param tid Tunnel ID.
3469 */
3470static struct MeshTunnel2 *
3471tunnel_get (struct GNUNET_HashCode *tid)
3472{
3473 return GNUNET_CONTAINER_multihashmap_get (tunnels, tid);
3474}
3475
3476
3477/**
3478 * Add a connection to a tunnel.
3479 *
3480 * @param t Tunnel.
3481 * @param c Connection.
3482 */
3483static void
3484tunnel_add_connection (struct MeshTunnel2 *t, struct MeshConnection *c)
3485{
3486 c->t = t;
3487 GNUNET_CONTAINER_DLL_insert_tail (t->connection_head, t->connection_tail, c);
3488}
3489
3490
3491/**
3492 * Create a connection.
3493 *
3494 * @param tid Tunnel ID.
3495 * @param cid Connection ID.
3496 */
3497static struct MeshConnection *
3498connection_new (struct GNUNET_HashCode *tid, uint32_t cid)
3499{
3500 struct MeshConnection *c;
3501 struct MeshTunnel2 *t;
3502
3503 t = tunnel_get (tid);
3504 if (NULL == t)
3505 {
3506 t = tunnel_new (tid);
3507 if (NULL == t)
3508 {
3509 GNUNET_break (0);
3510 return NULL;
3511 }
3512 }
3513
3514 c = GNUNET_new (struct MeshConnection);
3515 c->id = cid;
3516 tunnel_add_connection (t, c);
3517
3518 return c;
3519}
3520
3521
3522/**
3523 * Find a connection.
3524 *
3525 * @param tid Tunnel ID.
3526 * @param cid Connection ID.
3527 */
3528static struct MeshConnection *
3529connection_get (struct GNUNET_HashCode *tid, uint32_t cid)
3530{
3531 struct MeshConnection *c;
3532 struct MeshTunnel2 *t;
3533
3534 t = tunnel_get (tid);
3535 for (c = t->connection_head; NULL != c; c = c->next)
3536 if (c->id == cid)
3537 return c;
3538
3539 return NULL;
3540}
3541
3542
3543/**
3441 * Connection is no longer needed: destroy it and remove from tunnel. 3544 * Connection is no longer needed: destroy it and remove from tunnel.
3442 * 3545 *
3443 * @param c Connection to destroy. 3546 * @param c Connection to destroy.
@@ -3961,7 +4064,10 @@ queue_send (void *cls, size_t size, void *buf)
3961 break; 4064 break;
3962 case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE: 4065 case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE:
3963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path create\n"); 4066 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path create\n");
3964 data_size = send_core_connection_create (queue->cls, size, buf); 4067 if (NULL != c->t->channel_head)
4068 data_size = send_core_connection_create (queue->cls, size, buf);
4069 else
4070 data_size = send_core_data_raw (queue->cls, size, buf);
3965 break; 4071 break;
3966 case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK: 4072 case GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK:
3967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path ack\n"); 4073 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path ack\n");
@@ -4123,9 +4229,9 @@ queue_add (void *cls, uint16_t type, size_t size,
4123 else 4229 else
4124 GNUNET_CONTAINER_DLL_insert_tail (fc->queue_head, fc->queue_tail, queue); 4230 GNUNET_CONTAINER_DLL_insert_tail (fc->queue_head, fc->queue_tail, queue);
4125 4231
4126 if (NULL == dst->fc->core_transmit) 4232 if (NULL == fc->core_transmit)
4127 { 4233 {
4128 dst->fc->core_transmit = 4234 fc->core_transmit =
4129 GNUNET_CORE_notify_transmit_ready (core_handle, 4235 GNUNET_CORE_notify_transmit_ready (core_handle,
4130 0, 4236 0,
4131 0, 4237 0,
@@ -4146,194 +4252,130 @@ queue_add (void *cls, uint16_t type, size_t size,
4146 4252
4147 4253
4148/** 4254/**
4149 * Core handler for path creation 4255 * Core handler for connection creation.
4150 * 4256 *
4151 * @param cls closure 4257 * @param cls Closure (unused).
4152 * @param message message 4258 * @param peer Sender (neighbor).
4153 * @param peer peer identity this notification is about 4259 * @param message Message.
4154 * 4260 *
4155 * @return GNUNET_OK to keep the connection open, 4261 * @return GNUNET_OK to keep the connection open,
4156 * GNUNET_SYSERR to close it (signal serious error) 4262 * GNUNET_SYSERR to close it (signal serious error)
4157 */ 4263 */
4158static int 4264static int
4159handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, 4265handle_mesh_connection_create (void *cls,
4160 const struct GNUNET_MessageHeader *message) 4266 const struct GNUNET_PeerIdentity *peer,
4267 const struct GNUNET_MessageHeader *message)
4161{ 4268{
4269 struct GNUNET_MESH_ConnectionCreate *msg;
4270 struct GNUNET_PeerIdentity *id;
4271 struct GNUNET_HashCode *tid;
4272 struct MeshPeerPath *path;
4273 struct MeshPeer *dest_peer;
4274 struct MeshPeer *orig_peer;
4275 struct MeshConnection *c;
4162 unsigned int own_pos; 4276 unsigned int own_pos;
4277 uint32_t cid;
4163 uint16_t size; 4278 uint16_t size;
4164 uint16_t i; 4279 uint16_t i;
4165 MESH_ChannelNumber tid;
4166 struct GNUNET_MESH_CreateTunnel *msg;
4167 struct GNUNET_PeerIdentity *pi;
4168 struct MeshPeerPath *path;
4169 struct MeshPeer *dest_peer_info;
4170 struct MeshPeer *orig_peer_info;
4171 struct MeshTunnel *t;
4172 4280
4173 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a connection create msg\n");
4174 "Received a path create msg [%s]\n", 4282
4175 GNUNET_i2s (&my_full_id)); 4283 /* Check size */
4176 size = ntohs (message->size); 4284 size = ntohs (message->size);
4177 if (size < sizeof (struct GNUNET_MESH_CreateTunnel)) 4285 if (size < sizeof (struct GNUNET_MESH_ConnectionCreate))
4178 { 4286 {
4179 GNUNET_break_op (0); 4287 GNUNET_break_op (0);
4180 return GNUNET_OK; 4288 return GNUNET_OK;
4181 } 4289 }
4182 4290
4183 size -= sizeof (struct GNUNET_MESH_CreateTunnel); 4291 /* Calculate hops */
4292 size -= sizeof (struct GNUNET_MESH_ConnectionCreate);
4184 if (size % sizeof (struct GNUNET_PeerIdentity)) 4293 if (size % sizeof (struct GNUNET_PeerIdentity))
4185 { 4294 {
4186 GNUNET_break_op (0); 4295 GNUNET_break_op (0);
4187 return GNUNET_OK; 4296 return GNUNET_OK;
4188 } 4297 }
4189 size /= sizeof (struct GNUNET_PeerIdentity); 4298 size /= sizeof (struct GNUNET_PeerIdentity);
4190 if (size < 1) 4299 if (1 > size)
4191 { 4300 {
4192 GNUNET_break_op (0); 4301 GNUNET_break_op (0);
4193 return GNUNET_OK; 4302 return GNUNET_OK;
4194 } 4303 }
4195 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size); 4304 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
4196 msg = (struct GNUNET_MESH_CreateTunnel *) message;
4197 4305
4198 tid = ntohl (msg->tid); 4306 /* Get parameters */
4199 pi = (struct GNUNET_PeerIdentity *) &msg[1]; 4307 msg = (struct GNUNET_MESH_ConnectionCreate *) message;
4308 cid = ntohl (msg->cid);
4309 tid = &msg->tid;
4310 id = (struct GNUNET_PeerIdentity *) &msg[1];
4200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4201 " path is for tunnel %s[%X]:%u.\n", 4312 " connection %s[%X] (%s).\n",
4202 GNUNET_i2s (pi), tid, ntohl (msg->port)); 4313 GNUNET_h2s (tid), cid, GNUNET_i2s (id));
4203 t = channel_get (pi, tid);
4204 if (NULL == t) /* might be a local tunnel */
4205 {
4206 uint32_t opt;
4207 4314
4208 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating tunnel\n"); 4315 /* Create connection */
4209 t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0); 4316 c = connection_get (tid, cid);
4210 if (NULL == t) 4317 if (NULL == c)
4211 {
4212 GNUNET_break (0);
4213 return GNUNET_OK;
4214 }
4215 t->port = ntohl (msg->port);
4216 opt = ntohl (msg->opt);
4217 if (0 != (opt & GNUNET_MESH_OPTION_NOBUFFER))
4218 {
4219 t->nobuffer = GNUNET_YES;
4220 t->queue_max = 1;
4221 }
4222 if (0 != (opt & GNUNET_MESH_OPTION_RELIABLE))
4223 {
4224 t->reliable = GNUNET_YES;
4225 }
4226 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer);
4227 }
4228 tunnel_reset_timeout (t, GNUNET_YES);
4229 tunnel_change_state (t, MESH_TUNNEL_WAITING);
4230 dest_peer_info =
4231 GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
4232 if (NULL == dest_peer_info)
4233 {
4234 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4235 " Creating PeerInfo for destination.\n");
4236 dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeer));
4237 dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
4238 GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
4239 dest_peer_info,
4240 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
4241 }
4242 orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
4243 if (NULL == orig_peer_info)
4244 { 4318 {
4245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating connection\n");
4246 " Creating PeerInfo for origin.\n"); 4320 c = connection_new (tid, cid);
4247 orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeer)); 4321 if (NULL == c)
4248 orig_peer_info->id = GNUNET_PEER_intern (pi); 4322 return GNUNET_OK;
4249 GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
4250 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
4251 } 4323 }
4324 connection_reset_timeout (c, GNUNET_YES);
4325 tunnel_change_state (c->t, MESH_TUNNEL_WAITING);
4326
4327 /* Remember peers */
4328 dest_peer = peer_get (&id[size - 1]);
4329 orig_peer = peer_get (&id[0]7);
4330
4331 /* Create path */
4252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n"); 4332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n");
4253 path = path_new (size); 4333 path = path_new (size);
4254 own_pos = 0; 4334 own_pos = 0;
4255 for (i = 0; i < size; i++) 4335 for (i = 0; i < size; i++)
4256 { 4336 {
4257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... adding %s\n", 4337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... adding %s\n",
4258 GNUNET_i2s (&pi[i])); 4338 GNUNET_i2s (&id[i]));
4259 path->peers[i] = GNUNET_PEER_intern (&pi[i]); 4339 path->peers[i] = GNUNET_PEER_intern (&id[i]);
4260 if (path->peers[i] == myid) 4340 if (path->peers[i] == myid)
4261 own_pos = i; 4341 own_pos = i;
4262 } 4342 }
4263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
4264 if (own_pos == 0 && path->peers[own_pos] != myid) 4343 if (own_pos == 0 && path->peers[own_pos] != myid)
4265 { 4344 {
4266 /* create path: self not found in path through self */ 4345 /* create path: self not found in path through self */
4267 GNUNET_break_op (0); 4346 GNUNET_break_op (0);
4268 path_destroy (path); 4347 path_destroy (path);
4269 tunnel_destroy (t); 4348 connection_destroy (c);
4270 return GNUNET_OK; 4349 return GNUNET_OK;
4271 } 4350 }
4351 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
4272 path_add_to_peers (path, GNUNET_NO); 4352 path_add_to_peers (path, GNUNET_NO);
4273 tunnel_use_path (t, path); 4353 c->path = path;
4274 4354 c->own_pos = own_pos;
4275 peer_add_tunnel (dest_peer_info, t);
4276 4355
4356 /* Is it a connection to us? */
4277 if (own_pos == size - 1) 4357 if (own_pos == size - 1)
4278 { 4358 {
4279 struct MeshClient *c;
4280
4281 /* Find target client */
4282 c = GNUNET_CONTAINER_multihashmap32_get (ports, t->port);
4283 if (NULL == c)
4284 {
4285 /* TODO send reject */
4286 return GNUNET_OK;
4287 }
4288
4289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n"); 4359 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
4290 peer_add_path_to_origin (orig_peer_info, path, GNUNET_YES); 4360 peer_add_path_to_origin (orig_peer, path, GNUNET_YES);
4291 /* This can be a retransmission due to a lost PATH ACK.
4292 * Check if we already have a destination client for the tunnel. */
4293 if (t->client != c)
4294 {
4295 /* Assign local tid */
4296 while (NULL != channel_get_incoming (next_local_tid))
4297 next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
4298 t->local_tid_dest = next_local_tid++;
4299 next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_CHANNEL_ID_SERV;
4300 4361
4301 if (GNUNET_YES == t->reliable) 4362 send_connection_ack (c);
4302 {
4303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Reliable\n");
4304 t->bck_rel = GNUNET_malloc (sizeof (struct MeshChannelReliability));
4305 t->bck_rel->t = t;
4306 t->bck_rel->expected_delay = MESH_RETRANSMIT_TIME;
4307 }
4308 4363
4309 tunnel_add_client (t, c);
4310 send_local_tunnel_create (t);
4311 }
4312 send_path_ack (t);
4313 /* Eliminate tunnel when origin dies */
4314 tunnel_reset_timeout (t, GNUNET_YES);
4315 /* Keep tunnel alive in direction dest->owner*/ 4364 /* Keep tunnel alive in direction dest->owner*/
4316 tunnel_reset_timeout (t, GNUNET_NO); 4365 connection_reset_timeout (c, GNUNET_NO);
4317 } 4366 }
4318 else 4367 else
4319 { 4368 {
4320 struct MeshPeerPath *path2;
4321
4322 t->next_hop = path->peers[own_pos + 1];
4323 GNUNET_PEER_change_rc(t->next_hop, 1);
4324
4325 /* It's for somebody else! Retransmit. */ 4369 /* It's for somebody else! Retransmit. */
4326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n"); 4370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n");
4327 path2 = path_duplicate (path); 4371 peer_add_path (dest_peer, path_duplicate (path), GNUNET_NO);
4328 peer_add_path (dest_peer_info, path2, GNUNET_NO); 4372 peer_add_path_to_origin (orig_peer, path, GNUNET_NO);
4329 peer_add_path_to_origin (orig_peer_info, path, GNUNET_NO); 4373 send_prebuilt_message_connection (message, c, NULL, GNUNET_YES);
4330 send_path_create (t);
4331 } 4374 }
4332 return GNUNET_OK; 4375 return GNUNET_OK;
4333} 4376}
4334 4377
4335 4378
4336
4337/** 4379/**
4338 * Core handler for path ACKs 4380 * Core handler for path ACKs
4339 * 4381 *
@@ -5023,7 +5065,7 @@ handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
5023 * Functions to handle messages from core 5065 * Functions to handle messages from core
5024 */ 5066 */
5025static struct GNUNET_CORE_MessageHandler core_handlers[] = { 5067static struct GNUNET_CORE_MessageHandler core_handlers[] = {
5026 {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE, 0}, 5068 {&handle_mesh_connection_create, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_CREATE, 0},
5027 {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN, 5069 {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
5028 sizeof (struct GNUNET_MESH_PathBroken)}, 5070 sizeof (struct GNUNET_MESH_PathBroken)},
5029 {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY, 5071 {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,