diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesh/gnunet-service-mesh-enc.c | 217 |
1 files changed, 99 insertions, 118 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c index aec80124b..3b63f517e 100644 --- a/src/mesh/gnunet-service-mesh-enc.c +++ b/src/mesh/gnunet-service-mesh-enc.c | |||
@@ -4197,7 +4197,6 @@ queue_add (void *cls, uint16_t type, size_t size, | |||
4197 | /******************************************************************************/ | 4197 | /******************************************************************************/ |
4198 | 4198 | ||
4199 | 4199 | ||
4200 | |||
4201 | /** | 4200 | /** |
4202 | * Generic handler for mesh network payload traffic. | 4201 | * Generic handler for mesh network payload traffic. |
4203 | * | 4202 | * |
@@ -4313,6 +4312,7 @@ handle_unicast (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *message) | |||
4313 | return handle_data (t, message, GNUNET_YES); | 4312 | return handle_data (t, message, GNUNET_YES); |
4314 | } | 4313 | } |
4315 | 4314 | ||
4315 | |||
4316 | /** | 4316 | /** |
4317 | * Handler for mesh network traffic towards the owner of a tunnel. | 4317 | * Handler for mesh network traffic towards the owner of a tunnel. |
4318 | * | 4318 | * |
@@ -4328,6 +4328,104 @@ handle_to_orig (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *message) | |||
4328 | return handle_data (t, message, GNUNET_NO); | 4328 | return handle_data (t, message, GNUNET_NO); |
4329 | } | 4329 | } |
4330 | 4330 | ||
4331 | |||
4332 | /** | ||
4333 | * Handler for mesh network traffic end-to-end ACKs. | ||
4334 | * | ||
4335 | * @param t Tunnel on which we got this message. | ||
4336 | * @param message Data message. | ||
4337 | * @param fwd Is this a fwd ACK? (dest->orig) | ||
4338 | * | ||
4339 | * @return GNUNET_OK to keep the connection open, | ||
4340 | * GNUNET_SYSERR to close it (signal serious error) | ||
4341 | */ | ||
4342 | static int | ||
4343 | handle_data_ack (struct MeshTunnel2 *t, | ||
4344 | const struct GNUNET_MESH_DataACK *msg, int fwd) | ||
4345 | { | ||
4346 | struct MeshChannelReliability *rel; | ||
4347 | struct MeshReliableMessage *copy; | ||
4348 | struct MeshReliableMessage *next; | ||
4349 | struct MeshChannel *ch; | ||
4350 | uint32_t ack; | ||
4351 | uint16_t type; | ||
4352 | int work; | ||
4353 | |||
4354 | type = ntohs (msg->header.type); | ||
4355 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message!\n", | ||
4356 | GNUNET_MESH_DEBUG_M2S (type)); | ||
4357 | ch = channel_get (t, ntohl (msg->chid)); | ||
4358 | if (NULL == ch) | ||
4359 | { | ||
4360 | GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO); | ||
4361 | return GNUNET_OK; | ||
4362 | } | ||
4363 | ack = ntohl (msg->mid); | ||
4364 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n", | ||
4365 | (GNUNET_YES == fwd) ? "FWD" : "BCK", ack); | ||
4366 | |||
4367 | if (GNUNET_YES == fwd && GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type) | ||
4368 | { | ||
4369 | rel = ch->fwd_rel; | ||
4370 | } | ||
4371 | else if (GNUNET_NO == fwd && GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK == type) | ||
4372 | { | ||
4373 | rel = ch->bck_rel; | ||
4374 | } | ||
4375 | if (NULL == rel) | ||
4376 | { | ||
4377 | return GNUNET_OK; | ||
4378 | } | ||
4379 | |||
4380 | for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) | ||
4381 | { | ||
4382 | if (GMC_is_pid_bigger (copy->mid, ack)) | ||
4383 | { | ||
4384 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %u, out!\n", copy->mid); | ||
4385 | channel_rel_free_sent (rel, msg); | ||
4386 | break; | ||
4387 | } | ||
4388 | work = GNUNET_YES; | ||
4389 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %u\n", copy->mid); | ||
4390 | next = copy->next; | ||
4391 | rel_message_free (copy); | ||
4392 | } | ||
4393 | /* ACK client if needed */ | ||
4394 | // channel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type); | ||
4395 | |||
4396 | /* If some message was free'd, update the retransmission delay*/ | ||
4397 | if (GNUNET_YES == work) | ||
4398 | { | ||
4399 | if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task) | ||
4400 | { | ||
4401 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
4402 | if (NULL == rel->head_sent) | ||
4403 | { | ||
4404 | rel->retry_task = GNUNET_SCHEDULER_NO_TASK; | ||
4405 | } | ||
4406 | else | ||
4407 | { | ||
4408 | struct GNUNET_TIME_Absolute new_target; | ||
4409 | struct GNUNET_TIME_Relative delay; | ||
4410 | |||
4411 | delay = GNUNET_TIME_relative_multiply (rel->retry_timer, | ||
4412 | MESH_RETRANSMIT_MARGIN); | ||
4413 | new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp, | ||
4414 | delay); | ||
4415 | delay = GNUNET_TIME_absolute_get_remaining (new_target); | ||
4416 | rel->retry_task = | ||
4417 | GNUNET_SCHEDULER_add_delayed (delay, | ||
4418 | &channel_retransmit_message, | ||
4419 | rel); | ||
4420 | } | ||
4421 | } | ||
4422 | else | ||
4423 | GNUNET_break (0); | ||
4424 | } | ||
4425 | return GNUNET_OK; | ||
4426 | } | ||
4427 | |||
4428 | |||
4331 | /** | 4429 | /** |
4332 | * Core handler for connection creation. | 4430 | * Core handler for connection creation. |
4333 | * | 4431 | * |
@@ -4614,123 +4712,6 @@ handle_mesh_connection_destroy (void *cls, | |||
4614 | return GNUNET_OK; | 4712 | return GNUNET_OK; |
4615 | } | 4713 | } |
4616 | 4714 | ||
4617 | |||
4618 | /** | ||
4619 | * Core handler for mesh network traffic end-to-end ACKs. | ||
4620 | * | ||
4621 | * @param cls Closure. | ||
4622 | * @param message Message. | ||
4623 | * @param peer Peer identity this notification is about. | ||
4624 | * | ||
4625 | * @return GNUNET_OK to keep the connection open, | ||
4626 | * GNUNET_SYSERR to close it (signal serious error) | ||
4627 | */ | ||
4628 | static int | ||
4629 | handle_mesh_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
4630 | const struct GNUNET_MessageHeader *message) | ||
4631 | { | ||
4632 | struct GNUNET_MESH_DataACK *msg; | ||
4633 | struct MeshChannelReliability *rel; | ||
4634 | struct MeshReliableMessage *copy; | ||
4635 | struct MeshReliableMessage *next; | ||
4636 | struct MeshTunnel *t; | ||
4637 | GNUNET_PEER_Id id; | ||
4638 | uint32_t ack; | ||
4639 | uint16_t type; | ||
4640 | int work; | ||
4641 | |||
4642 | type = ntohs (message->type); | ||
4643 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a %s message from %s!\n", | ||
4644 | GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer)); | ||
4645 | msg = (struct GNUNET_MESH_DataACK *) message; | ||
4646 | |||
4647 | t = channel_get (&msg->oid, ntohl (msg->tid)); | ||
4648 | if (NULL == t) | ||
4649 | { | ||
4650 | /* TODO notify that we dont know this tunnel (whom)? */ | ||
4651 | GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO); | ||
4652 | return GNUNET_OK; | ||
4653 | } | ||
4654 | ack = ntohl (msg->mid); | ||
4655 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack); | ||
4656 | |||
4657 | /* Is this a forward or backward ACK? */ | ||
4658 | id = GNUNET_PEER_search (peer); | ||
4659 | if (t->next_hop == id && GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type) | ||
4660 | { | ||
4661 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n"); | ||
4662 | if (NULL == t->owner) | ||
4663 | { | ||
4664 | send_prebuilt_message (message, t->prev_hop, t); | ||
4665 | return GNUNET_OK; | ||
4666 | } | ||
4667 | rel = t->fwd_rel; | ||
4668 | } | ||
4669 | else if (t->prev_hop == id && GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK == type) | ||
4670 | { | ||
4671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n"); | ||
4672 | if (NULL == t->client) | ||
4673 | { | ||
4674 | send_prebuilt_message (message, t->next_hop, t); | ||
4675 | return GNUNET_OK; | ||
4676 | } | ||
4677 | rel = t->bck_rel; | ||
4678 | } | ||
4679 | else | ||
4680 | { | ||
4681 | GNUNET_break_op (0); | ||
4682 | return GNUNET_OK; | ||
4683 | } | ||
4684 | |||
4685 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! ACK %u\n", ack); | ||
4686 | for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) | ||
4687 | { | ||
4688 | if (GMC_is_pid_bigger (copy->mid, ack)) | ||
4689 | { | ||
4690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %u, out!\n", copy->mid); | ||
4691 | tunnel_free_sent_reliable (t, msg, rel); | ||
4692 | break; | ||
4693 | } | ||
4694 | work = GNUNET_YES; | ||
4695 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %u\n", copy->mid); | ||
4696 | next = copy->next; | ||
4697 | tunnel_free_reliable_message (copy); | ||
4698 | } | ||
4699 | /* Once buffers have been free'd, send ACK */ | ||
4700 | tunnel_send_ack (t, type, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK == type); | ||
4701 | |||
4702 | /* If some message was free'd, update the retransmission delay*/ | ||
4703 | if (GNUNET_YES == work) | ||
4704 | { | ||
4705 | if (GNUNET_SCHEDULER_NO_TASK != rel->retry_task) | ||
4706 | { | ||
4707 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
4708 | if (NULL == rel->head_sent) | ||
4709 | { | ||
4710 | rel->retry_task = GNUNET_SCHEDULER_NO_TASK; | ||
4711 | } | ||
4712 | else | ||
4713 | { | ||
4714 | struct GNUNET_TIME_Absolute new_target; | ||
4715 | struct GNUNET_TIME_Relative delay; | ||
4716 | |||
4717 | delay = GNUNET_TIME_relative_multiply (rel->retry_timer, | ||
4718 | MESH_RETRANSMIT_MARGIN); | ||
4719 | new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp, | ||
4720 | delay); | ||
4721 | delay = GNUNET_TIME_absolute_get_remaining (new_target); | ||
4722 | rel->retry_task = | ||
4723 | GNUNET_SCHEDULER_add_delayed (delay, | ||
4724 | &tunnel_retransmit_message, | ||
4725 | rel); | ||
4726 | } | ||
4727 | } | ||
4728 | else | ||
4729 | GNUNET_break (0); | ||
4730 | } | ||
4731 | return GNUNET_OK; | ||
4732 | } | ||
4733 | |||
4734 | /** | 4715 | /** |
4735 | * Core handler for mesh network traffic point-to-point acks. | 4716 | * Core handler for mesh network traffic point-to-point acks. |
4736 | * | 4717 | * |