diff options
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 102 |
1 files changed, 94 insertions, 8 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 53b9ba0c8..9c4672609 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -35,7 +35,6 @@ | |||
35 | * Implement next: | 35 | * Implement next: |
36 | * - DV data structures: | 36 | * - DV data structures: |
37 | * + using DV routes! | 37 | * + using DV routes! |
38 | * - handling of DV-boxed messages that need to be forwarded | ||
39 | * - route_message implementation, including using DV data structures | 38 | * - route_message implementation, including using DV data structures |
40 | * (but not when routing certain message types, like DV learn, | 39 | * (but not when routing certain message types, like DV learn, |
41 | * MUST pay attention to content here -- or pass extra flags?) | 40 | * MUST pay attention to content here -- or pass extra flags?) |
@@ -4763,7 +4762,8 @@ handle_dv_learn (void *cls, | |||
4763 | /* continue communicator here, everything else can happen asynchronous! */ | 4762 | /* continue communicator here, everything else can happen asynchronous! */ |
4764 | finish_cmc_handling (cmc); | 4763 | finish_cmc_handling (cmc); |
4765 | 4764 | ||
4766 | // FIXME: should we bother to verify _every_ DV initiator signature? | 4765 | /* OPTIMIZE-FIXME: Technically, we only need to bother checking |
4766 | the initiator signature if we send the message back to the initiator... */ | ||
4767 | if (GNUNET_OK != | 4767 | if (GNUNET_OK != |
4768 | validate_dv_initiator_signature (&dvl->initiator, | 4768 | validate_dv_initiator_signature (&dvl->initiator, |
4769 | &dvl->challenge, | 4769 | &dvl->challenge, |
@@ -4773,7 +4773,7 @@ handle_dv_learn (void *cls, | |||
4773 | return; | 4773 | return; |
4774 | } | 4774 | } |
4775 | // FIXME: asynchronously (!) verify hop-by-hop signatures! | 4775 | // FIXME: asynchronously (!) verify hop-by-hop signatures! |
4776 | // => if signature verification load too high, implement random drop strategy! | 4776 | // => if signature verification load too high, implement random drop strategy!? |
4777 | 4777 | ||
4778 | do_fwd = GNUNET_YES; | 4778 | do_fwd = GNUNET_YES; |
4779 | if (0 == GNUNET_memcmp (&GST_my_identity, | 4779 | if (0 == GNUNET_memcmp (&GST_my_identity, |
@@ -4953,11 +4953,68 @@ check_dv_box (void *cls, | |||
4953 | GNUNET_break_op (0); | 4953 | GNUNET_break_op (0); |
4954 | return GNUNET_SYSERR; | 4954 | return GNUNET_SYSERR; |
4955 | } | 4955 | } |
4956 | if (0 == | ||
4957 | GNUNET_memcmp (&dvb->origin, | ||
4958 | &GST_my_identity)) | ||
4959 | { | ||
4960 | GNUNET_break_op (0); | ||
4961 | return GNUNET_SYSERR; | ||
4962 | } | ||
4956 | return GNUNET_YES; | 4963 | return GNUNET_YES; |
4957 | } | 4964 | } |
4958 | 4965 | ||
4959 | 4966 | ||
4960 | /** | 4967 | /** |
4968 | * Create a DV Box message and queue it for transmission to | ||
4969 | * @ea next_hop. | ||
4970 | * | ||
4971 | * @param next_hop peer to receive the message next | ||
4972 | * @param total_hops how many hops did the message take so far | ||
4973 | * @param num_hops length of the @a hops array | ||
4974 | * @param origin origin of the message | ||
4975 | * @param hops next peer(s) to the destination, including destination | ||
4976 | * @param payload payload of the box | ||
4977 | * @param payload_size number of bytes in @a payload | ||
4978 | */ | ||
4979 | static void | ||
4980 | forward_dv_box (struct Neighbour *next_hop, | ||
4981 | uint16_t total_hops, | ||
4982 | uint16_t num_hops, | ||
4983 | const struct GNUNET_PeerIdentity *origin, | ||
4984 | const struct GNUNET_PeerIdentity *hops, | ||
4985 | const void *payload, | ||
4986 | uint16_t payload_size) | ||
4987 | { | ||
4988 | struct TransportDVBox *dvb; | ||
4989 | struct GNUNET_PeerIdentity *dhops; | ||
4990 | |||
4991 | GNUNET_assert (UINT16_MAX < | ||
4992 | sizeof (struct TransportDVBox) + | ||
4993 | sizeof (struct GNUNET_PeerIdentity) * num_hops + | ||
4994 | payload_size); | ||
4995 | dvb = GNUNET_malloc (sizeof (struct TransportDVBox) + | ||
4996 | sizeof (struct GNUNET_PeerIdentity) * num_hops + | ||
4997 | payload_size); | ||
4998 | dvb->header.size = htons (sizeof (struct TransportDVBox) + | ||
4999 | sizeof (struct GNUNET_PeerIdentity) * num_hops + | ||
5000 | payload_size); | ||
5001 | dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); | ||
5002 | dvb->total_hops = htons (total_hops); | ||
5003 | dvb->num_hops = htons (num_hops); | ||
5004 | dvb->origin = *origin; | ||
5005 | dhops = (struct GNUNET_PeerIdentity *) &dvb[1]; | ||
5006 | memcpy (dhops, | ||
5007 | hops, | ||
5008 | num_hops * sizeof (struct GNUNET_PeerIdentity)); | ||
5009 | memcpy (&dhops[num_hops], | ||
5010 | payload, | ||
5011 | payload_size); | ||
5012 | route_message (&next_hop->pid, | ||
5013 | &dvb->header); | ||
5014 | } | ||
5015 | |||
5016 | |||
5017 | /** | ||
4961 | * Communicator gave us a DV box. Process the request. | 5018 | * Communicator gave us a DV box. Process the request. |
4962 | * | 5019 | * |
4963 | * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done) | 5020 | * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done) |
@@ -4975,10 +5032,39 @@ handle_dv_box (void *cls, | |||
4975 | 5032 | ||
4976 | if (num_hops > 0) | 5033 | if (num_hops > 0) |
4977 | { | 5034 | { |
4978 | // FIXME: if we are not the target, shorten path and forward along. | 5035 | /* We're trying from the end of the hops array, as we may be |
4979 | // Try from the _end_ of hops array if we know the given | 5036 | able to find a shortcut unknown to the origin that way */ |
4980 | // neighbour (shortening the path!). | 5037 | for (int i=num_hops-1;i>=0;i--) |
4981 | // NOTE: increment total_hops! | 5038 | { |
5039 | struct Neighbour *n; | ||
5040 | |||
5041 | if (0 == | ||
5042 | GNUNET_memcmp (&hops[i], | ||
5043 | &GST_my_identity)) | ||
5044 | { | ||
5045 | GNUNET_break_op (0); | ||
5046 | finish_cmc_handling (cmc); | ||
5047 | return; | ||
5048 | } | ||
5049 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, | ||
5050 | &hops[i]); | ||
5051 | if (NULL == n) | ||
5052 | continue; | ||
5053 | forward_dv_box (n, | ||
5054 | ntohs (dvb->total_hops) + 1, | ||
5055 | num_hops - i - 1, /* number of hops left */ | ||
5056 | &dvb->origin, | ||
5057 | &hops[i+1], /* remaining hops */ | ||
5058 | (const void *) &dvb[1], | ||
5059 | size); | ||
5060 | finish_cmc_handling (cmc); | ||
5061 | return; | ||
5062 | } | ||
5063 | /* Woopsie, next hop not in neighbours, drop! */ | ||
5064 | GNUNET_STATISTICS_update (GST_stats, | ||
5065 | "# DV Boxes dropped: next hop unknown", | ||
5066 | 1, | ||
5067 | GNUNET_NO); | ||
4982 | finish_cmc_handling (cmc); | 5068 | finish_cmc_handling (cmc); |
4983 | return; | 5069 | return; |
4984 | } | 5070 | } |
@@ -5399,7 +5485,7 @@ tracker_update_in_cb (void *cls) | |||
5399 | 5485 | ||
5400 | rsize = (0 == queue->mtu) ? IN_PACKET_SIZE_WITHOUT_MTU : queue->mtu; | 5486 | rsize = (0 == queue->mtu) ? IN_PACKET_SIZE_WITHOUT_MTU : queue->mtu; |
5401 | in_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_in, | 5487 | in_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_in, |
5402 | rsize); | 5488 | rsize); |
5403 | // FIXME: how exactly do we do inbound flow control? | 5489 | // FIXME: how exactly do we do inbound flow control? |
5404 | } | 5490 | } |
5405 | 5491 | ||