aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/gnunet-service-mesh.c')
-rw-r--r--src/mesh/gnunet-service-mesh.c123
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 */
2878static void
2879tunnel_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 */
3495static struct MeshTunnelChildInfo * 3543static struct MeshTunnelChildInfo *
3496tunnel_get_neighbor_fc (const struct MeshTunnel *t, 3544tunnel_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 */
5847static int
5848handle_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}