diff options
Diffstat (limited to 'src/mesh/gnunet-service-mesh.c')
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 123 |
1 files changed, 119 insertions, 4 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index e8ce53af2..f6645f2fd 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -374,6 +374,11 @@ struct MeshTunnel | |||
374 | unsigned int bck_queue_max; | 374 | unsigned int bck_queue_max; |
375 | 375 | ||
376 | /** | 376 | /** |
377 | * Task to poll peer in case of a stall. | ||
378 | */ | ||
379 | GNUNET_SCHEDULER_TaskIdentifier fc_poll_bck; | ||
380 | |||
381 | /** | ||
377 | * Last time the tunnel was used | 382 | * Last time the tunnel was used |
378 | */ | 383 | */ |
379 | struct GNUNET_TIME_Absolute timestamp; | 384 | struct GNUNET_TIME_Absolute timestamp; |
@@ -527,6 +532,16 @@ struct MeshTunnelChildInfo | |||
527 | * How many elements are already in the buffer. | 532 | * How many elements are already in the buffer. |
528 | */ | 533 | */ |
529 | unsigned int send_buffer_n; | 534 | unsigned int send_buffer_n; |
535 | |||
536 | /** | ||
537 | * Tunnel this info is about | ||
538 | */ | ||
539 | struct MeshTunnel *t; | ||
540 | |||
541 | /** | ||
542 | * Task to poll peer in case of a stall. | ||
543 | */ | ||
544 | GNUNET_SCHEDULER_TaskIdentifier fc_poll; | ||
530 | }; | 545 | }; |
531 | 546 | ||
532 | 547 | ||
@@ -954,8 +969,6 @@ unsigned int next_client_id; | |||
954 | /*********************** DECLARATIONS **************************/ | 969 | /*********************** DECLARATIONS **************************/ |
955 | /******************************************************************************/ | 970 | /******************************************************************************/ |
956 | 971 | ||
957 | /* FIXME move declarations here */ | ||
958 | |||
959 | /** | 972 | /** |
960 | * Function to process paths received for a new peer addition. The recorded | 973 | * Function to process paths received for a new peer addition. The recorded |
961 | * paths form the initial tunnel, which can be optimized later. | 974 | * paths form the initial tunnel, which can be optimized later. |
@@ -2856,6 +2869,41 @@ peer_info_add_path_to_origin (struct MeshPeerInfo *peer_info, | |||
2856 | 2869 | ||
2857 | 2870 | ||
2858 | /** | 2871 | /** |
2872 | * Function called if the connection to the peer has been stalled for a while, | ||
2873 | * possibly due to a missed ACK. Poll the peer about its ACK status. | ||
2874 | * | ||
2875 | * @param cls Closure (info about regex search). | ||
2876 | * @param tc TaskContext. | ||
2877 | */ | ||
2878 | static void | ||
2879 | tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2880 | { | ||
2881 | struct MeshTunnelChildInfo *cinfo = cls; | ||
2882 | struct GNUNET_MESH_Poll msg; | ||
2883 | struct GNUNET_PeerIdentity id; | ||
2884 | struct MeshTunnel *t; | ||
2885 | |||
2886 | cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK; | ||
2887 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
2888 | { | ||
2889 | return; | ||
2890 | } | ||
2891 | |||
2892 | t = cinfo->t; | ||
2893 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL); | ||
2894 | msg.header.size = htons (sizeof (msg)); | ||
2895 | msg.tid = htonl (t->id.tid); | ||
2896 | GNUNET_PEER_resolve (t->id.oid, &msg.oid); | ||
2897 | msg.last_ack = htonl (cinfo->fwd_ack); | ||
2898 | |||
2899 | GNUNET_PEER_resolve (tree_get_predecessor(cinfo->t->tree), &id); | ||
2900 | send_prebuilt_message (&msg.header, &id, cinfo->t); | ||
2901 | cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS, | ||
2902 | &tunnel_poll, cinfo); | ||
2903 | } | ||
2904 | |||
2905 | |||
2906 | /** | ||
2859 | * Build a PeerPath from the paths returned from the DHT, reversing the paths | 2907 | * Build a PeerPath from the paths returned from the DHT, reversing the paths |
2860 | * to obtain a local peer -> destination path and interning the peer ids. | 2908 | * to obtain a local peer -> destination path and interning the peer ids. |
2861 | * | 2909 | * |
@@ -3493,7 +3541,7 @@ tunnel_add_skip (void *cls, | |||
3493 | * @return Neighbor's Flow Control info. | 3541 | * @return Neighbor's Flow Control info. |
3494 | */ | 3542 | */ |
3495 | static struct MeshTunnelChildInfo * | 3543 | static struct MeshTunnelChildInfo * |
3496 | tunnel_get_neighbor_fc (const struct MeshTunnel *t, | 3544 | tunnel_get_neighbor_fc (struct MeshTunnel *t, |
3497 | const struct GNUNET_PeerIdentity *peer) | 3545 | const struct GNUNET_PeerIdentity *peer) |
3498 | { | 3546 | { |
3499 | struct MeshTunnelChildInfo *cinfo; | 3547 | struct MeshTunnelChildInfo *cinfo; |
@@ -3510,6 +3558,7 @@ tunnel_get_neighbor_fc (const struct MeshTunnel *t, | |||
3510 | cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo)); | 3558 | cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo)); |
3511 | cinfo->id = GNUNET_PEER_intern (peer); | 3559 | cinfo->id = GNUNET_PEER_intern (peer); |
3512 | cinfo->skip = t->fwd_pid; | 3560 | cinfo->skip = t->fwd_pid; |
3561 | cinfo->t = t; | ||
3513 | 3562 | ||
3514 | delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE; | 3563 | delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE; |
3515 | cinfo->fwd_ack = t->fwd_pid + delta; | 3564 | cinfo->fwd_ack = t->fwd_pid + delta; |
@@ -3923,7 +3972,7 @@ tunnel_send_child_bck_ack (void *cls, | |||
3923 | GNUNET_NO == GMC_is_pid_bigger (cinfo->bck_ack, cinfo->pid)) | 3972 | GNUNET_NO == GMC_is_pid_bigger (cinfo->bck_ack, cinfo->pid)) |
3924 | return; | 3973 | return; |
3925 | 3974 | ||
3926 | cinfo->bck_ack++; | 3975 | cinfo->bck_ack++; // FIXME window size? |
3927 | send_ack (t, &peer, cinfo->bck_ack); | 3976 | send_ack (t, &peer, cinfo->bck_ack); |
3928 | } | 3977 | } |
3929 | 3978 | ||
@@ -4004,6 +4053,7 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type) | |||
4004 | break; | 4053 | break; |
4005 | case GNUNET_MESSAGE_TYPE_MESH_ACK: | 4054 | case GNUNET_MESSAGE_TYPE_MESH_ACK: |
4006 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: | 4055 | case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK: |
4056 | case GNUNET_MESSAGE_TYPE_MESH_POLL: | ||
4007 | break; | 4057 | break; |
4008 | default: | 4058 | default: |
4009 | GNUNET_break (0); | 4059 | GNUNET_break (0); |
@@ -4776,6 +4826,7 @@ queue_send (void *cls, size_t size, void *buf) | |||
4776 | size_t data_size; | 4826 | size_t data_size; |
4777 | 4827 | ||
4778 | peer->core_transmit = NULL; | 4828 | peer->core_transmit = NULL; |
4829 | cinfo = NULL; | ||
4779 | 4830 | ||
4780 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n"); | 4831 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n"); |
4781 | queue = queue_get_next (peer); | 4832 | queue = queue_get_next (peer); |
@@ -4951,9 +5002,15 @@ queue_send (void *cls, size_t size, void *buf) | |||
4951 | else | 5002 | else |
4952 | { | 5003 | { |
4953 | if (NULL != peer->queue_head) | 5004 | if (NULL != peer->queue_head) |
5005 | { | ||
4954 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 5006 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
4955 | "********* %s stalled\n", | 5007 | "********* %s stalled\n", |
4956 | GNUNET_i2s(&my_full_id)); | 5008 | GNUNET_i2s(&my_full_id)); |
5009 | if (NULL == cinfo) | ||
5010 | cinfo = tunnel_get_neighbor_fc (t, &dst_id); | ||
5011 | cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS, | ||
5012 | &tunnel_poll, cinfo); | ||
5013 | } | ||
4957 | } | 5014 | } |
4958 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* return %d\n", data_size); | 5015 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* return %d\n", data_size); |
4959 | return data_size; | 5016 | return data_size; |
@@ -5776,6 +5833,62 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
5776 | 5833 | ||
5777 | 5834 | ||
5778 | /** | 5835 | /** |
5836 | * Core handler for mesh network traffic point-to-point ack polls. | ||
5837 | * | ||
5838 | * @param cls closure | ||
5839 | * @param message message | ||
5840 | * @param peer peer identity this notification is about | ||
5841 | * @param atsi performance data | ||
5842 | * @param atsi_count number of records in 'atsi' | ||
5843 | * | ||
5844 | * @return GNUNET_OK to keep the connection open, | ||
5845 | * GNUNET_SYSERR to close it (signal serious error) | ||
5846 | */ | ||
5847 | static int | ||
5848 | handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
5849 | const struct GNUNET_MessageHeader *message, | ||
5850 | const struct GNUNET_ATS_Information *atsi, | ||
5851 | unsigned int atsi_count) | ||
5852 | { | ||
5853 | struct GNUNET_MESH_Poll *msg; | ||
5854 | struct MeshTunnel *t; | ||
5855 | |||
5856 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n", | ||
5857 | GNUNET_i2s (peer)); | ||
5858 | |||
5859 | msg = (struct GNUNET_MESH_Poll *) message; | ||
5860 | |||
5861 | t = tunnel_get (&msg->oid, ntohl (msg->tid)); | ||
5862 | |||
5863 | if (NULL == t) | ||
5864 | { | ||
5865 | /* TODO notify that we dont know this tunnel (whom)? */ | ||
5866 | GNUNET_STATISTICS_update (stats, "# poll on unknown tunnel", 1, GNUNET_NO); | ||
5867 | GNUNET_break_op (0); | ||
5868 | return GNUNET_OK; | ||
5869 | } | ||
5870 | |||
5871 | /* Is this a forward or backward ACK? */ | ||
5872 | if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer)) | ||
5873 | { | ||
5874 | struct MeshTunnelChildInfo *cinfo; | ||
5875 | |||
5876 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from FWD\n"); | ||
5877 | cinfo = tunnel_get_neighbor_fc (t, peer); | ||
5878 | cinfo->bck_ack = cinfo->pid; // mark as ready to send | ||
5879 | tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL); | ||
5880 | } | ||
5881 | else | ||
5882 | { | ||
5883 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from BCK\n"); | ||
5884 | tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL); | ||
5885 | } | ||
5886 | |||
5887 | return GNUNET_OK; | ||
5888 | } | ||
5889 | |||
5890 | |||
5891 | /** | ||
5779 | * Core handler for path ACKs | 5892 | * Core handler for path ACKs |
5780 | * | 5893 | * |
5781 | * @param cls closure | 5894 | * @param cls closure |
@@ -5939,6 +6052,8 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = { | |||
5939 | {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, | 6052 | {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, |
5940 | {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK, | 6053 | {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK, |
5941 | sizeof (struct GNUNET_MESH_ACK)}, | 6054 | sizeof (struct GNUNET_MESH_ACK)}, |
6055 | {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL, | ||
6056 | sizeof (struct GNUNET_MESH_Poll)}, | ||
5942 | {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK, | 6057 | {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK, |
5943 | sizeof (struct GNUNET_MESH_PathACK)}, | 6058 | sizeof (struct GNUNET_MESH_PathACK)}, |
5944 | {NULL, 0, 0} | 6059 | {NULL, 0, 0} |