aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-05-08 22:11:38 +0200
committerChristian Grothoff <christian@grothoff.org>2019-05-08 22:11:38 +0200
commit95096540e381d784ab0d28b6cde2935b9b269558 (patch)
tree6fb5205cd69a0e78624fc46d7f908468fa2fb504 /src
parente4895ec7c1a1808a13195c346a828c271ca86c78 (diff)
downloadgnunet-95096540e381d784ab0d28b6cde2935b9b269558.tar.gz
gnunet-95096540e381d784ab0d28b6cde2935b9b269558.zip
more logging, more FIXMEs
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-tng.c151
1 files changed, 140 insertions, 11 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 2784ca99e..b8c5ea9f8 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -24,7 +24,10 @@
24 * 24 *
25 * TODO: 25 * TODO:
26 * Implement next: 26 * Implement next:
27 * - add (more) logging 27 * - remove duplicate HELLO vs. URI API code
28 * - add (more) logging (beyond line ~7500)
29 * - properly encrypt *all* DV traffic, not only backchannel;
30 * rename BackchannelEncapsulation logic to DVEncapsulation!
28 * - realize transport-to-transport flow control (needed in case 31 * - realize transport-to-transport flow control (needed in case
29 * communicators do not offer flow control). Note that we may not 32 * communicators do not offer flow control). Note that we may not
30 * want to simply delay the ACKs as that may cause unnecessary 33 * want to simply delay the ACKs as that may cause unnecessary
@@ -3586,7 +3589,7 @@ client_send_response (struct PendingMessage *pm)
3586 * @param num_hops length of the @a hops array 3589 * @param num_hops length of the @a hops array
3587 * @param origin origin of the message 3590 * @param origin origin of the message
3588 * @param hops next peer(s) to the destination, including destination 3591 * @param hops next peer(s) to the destination, including destination
3589 * @param payload payload of the box 3592 * @param payload encrypted (!) payload of the box
3590 * @param payload_size number of bytes in @a payload 3593 * @param payload_size number of bytes in @a payload
3591 * @return boxed message (caller must #GNUNET_free() it). 3594 * @return boxed message (caller must #GNUNET_free() it).
3592 */ 3595 */
@@ -3784,6 +3787,7 @@ handle_client_send (void *cls, const struct OutboundMessage *obm)
3784 res = pick_random_dv_hops (dv, RMO_NONE, &dvh, 1); 3787 res = pick_random_dv_hops (dv, RMO_NONE, &dvh, 1);
3785 GNUNET_assert (1 == res); 3788 GNUNET_assert (1 == res);
3786 target = dvh->next_hop; 3789 target = dvh->next_hop;
3790 /* FIXME: encrypt bytes_msg at &obm[1] to &obm->peer first! */
3787 dvb = create_dv_box (0, 3791 dvb = create_dv_box (0,
3788 &GST_my_identity, 3792 &GST_my_identity,
3789 &obm->peer, 3793 &obm->peer,
@@ -4252,12 +4256,14 @@ route_via_neighbour (const struct Neighbour *n,
4252 * Sets up the boxed message and queues it at the next hop. 4256 * Sets up the boxed message and queues it at the next hop.
4253 * 4257 *
4254 * @param dvh choice of the path for the message 4258 * @param dvh choice of the path for the message
4255 * @param payload body to transmit 4259 * @param payload encrypted body to transmit
4260 * @param payload_len number of bytes in @a payload
4256 * @param options options to use for control 4261 * @param options options to use for control
4257 */ 4262 */
4258static void 4263static void
4259forward_via_dvh (const struct DistanceVectorHop *dvh, 4264forward_via_dvh (const struct DistanceVectorHop *dvh,
4260 const struct GNUNET_MessageHeader *payload, 4265 const void *payload,
4266 size_t payload_len,
4261 enum RouteMessageOptions options) 4267 enum RouteMessageOptions options)
4262{ 4268{
4263 struct TransportDVBoxMessage *dvb; 4269 struct TransportDVBoxMessage *dvb;
@@ -4268,7 +4274,7 @@ forward_via_dvh (const struct DistanceVectorHop *dvh,
4268 dvh->distance, 4274 dvh->distance,
4269 dvh->path, 4275 dvh->path,
4270 payload, 4276 payload,
4271 ntohs (payload->size)); 4277 payload_len);
4272 route_via_neighbour (dvh->next_hop, &dvb->header, options); 4278 route_via_neighbour (dvh->next_hop, &dvb->header, options);
4273 GNUNET_free (dvb); 4279 GNUNET_free (dvb);
4274} 4280}
@@ -4295,6 +4301,13 @@ route_via_dv (const struct DistanceVector *dv,
4295 options, 4301 options,
4296 hops, 4302 hops,
4297 (0 == (options & RMO_REDUNDANT)) ? 1 : 2); 4303 (0 == (options & RMO_REDUNDANT)) ? 1 : 2);
4304 if (0 == res)
4305 {
4306 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4307 "Failed to route message, could not determine DV path\n");
4308 return;
4309 }
4310 // FIXME: we should encrypt `hdr` here first!
4298 for (unsigned int i = 0; i < res; i++) 4311 for (unsigned int i = 0; i < res; i++)
4299 { 4312 {
4300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4313 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4303,7 +4316,11 @@ route_via_dv (const struct DistanceVector *dv,
4303 GNUNET_i2s (&dv->target), 4316 GNUNET_i2s (&dv->target),
4304 i + 1, 4317 i + 1,
4305 res + 1); 4318 res + 1);
4306 forward_via_dvh (hops[i], hdr, options & (~RMO_REDUNDANT)); 4319 forward_via_dvh (hops[i],
4320 hdr,
4321 ntohs (
4322 hdr->size), /* FIXME: can't do this once encrypted... */
4323 options & (~RMO_REDUNDANT));
4307 } 4324 }
4308} 4325}
4309 4326
@@ -4610,6 +4627,9 @@ handle_communicator_backchannel (
4610 ntohs (inbox->size)); 4627 ntohs (inbox->size));
4611 } 4628 }
4612 /* encapsulate and encrypt message */ 4629 /* encapsulate and encrypt message */
4630
4631 /* FIXME: this should be done with the DV logic for all
4632 DV messages, NOT here only for backchannel! */
4613 msize = ntohs (cb->header.size) - sizeof (*cb) + 4633 msize = ntohs (cb->header.size) - sizeof (*cb) +
4614 sizeof (struct TransportBackchannelRequestPayloadP); 4634 sizeof (struct TransportBackchannelRequestPayloadP);
4615 enc = GNUNET_malloc (sizeof (*enc) + msize); 4635 enc = GNUNET_malloc (sizeof (*enc) + msize);
@@ -5245,7 +5265,8 @@ handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
5245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5246 "Fragment reassembly complete for message %u\n", 5266 "Fragment reassembly complete for message %u\n",
5247 (unsigned int) fb->msg_uuid.uuid); 5267 (unsigned int) fb->msg_uuid.uuid);
5248 5268 /* FIXME: check that the resulting msg is NOT a
5269 DV Box or Reliability Box, as that is NOT allowed! */
5249 demultiplex_with_cmc (cmc, msg); 5270 demultiplex_with_cmc (cmc, msg);
5250 /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still 5271 /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still
5251 en-route and we forget that we finished this reassembly immediately! 5272 en-route and we forget that we finished this reassembly immediately!
@@ -5305,6 +5326,8 @@ handle_reliability_box (void *cls,
5305 : GNUNET_TIME_relative_to_absolute ( 5326 : GNUNET_TIME_relative_to_absolute (
5306 GNUNET_TIME_relative_divide (rtt, 8 /* FIXME: magic constant */))); 5327 GNUNET_TIME_relative_divide (rtt, 8 /* FIXME: magic constant */)));
5307 /* continue with inner message */ 5328 /* continue with inner message */
5329 /* FIXME: check that inbox is NOT a DV Box, fragment or another
5330 reliability box (not allowed!) */
5308 demultiplex_with_cmc (cmc, inbox); 5331 demultiplex_with_cmc (cmc, inbox);
5309} 5332}
5310 5333
@@ -5840,6 +5863,8 @@ handle_backchannel_encapsulation (
5840 finish_cmc_handling (cmc); 5863 finish_cmc_handling (cmc);
5841 return; 5864 return;
5842 } 5865 }
5866 /* FIXME: this should be done when decrypting _any_ DV
5867 message, not only for backchannels! */
5843 dh_key_derive_eph_pub (&be->ephemeral_key, &be->iv, &key); 5868 dh_key_derive_eph_pub (&be->ephemeral_key, &be->iv, &key);
5844 hdr = (const char *) &be[1]; 5869 hdr = (const char *) &be[1];
5845 hdr_len = ntohs (be->header.size) - sizeof (*be); 5870 hdr_len = ntohs (be->header.size) - sizeof (*be);
@@ -6553,9 +6578,6 @@ neighbour_store_dvmono_cb (void *cls, int success)
6553} 6578}
6554 6579
6555 6580
6556// FIXME: add logging logic from here!
6557
6558
6559/** 6581/**
6560 * Communicator gave us a DV learn message. Process the request. 6582 * Communicator gave us a DV learn message. Process the request.
6561 * 6583 *
@@ -6672,6 +6694,31 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6672 } 6694 }
6673 } 6695 }
6674 6696
6697 if (GNUNET_EXTRA_LOGGING > 0)
6698 {
6699 char *path;
6700
6701 path = GNUNET_strdup (GNUNET_i2s (&dvl->initiator));
6702 for (unsigned int i = 0; i < nhops; i++)
6703 {
6704 char *tmp;
6705
6706 GNUNET_asprintf (&tmp,
6707 "%s%s%s",
6708 path,
6709 (bi_history & (1 << (nhops - i))) ? "<->" : "-->",
6710 GNUNET_i2s (&hops[i].hop));
6711 GNUNET_free (path);
6712 path = tmp;
6713 }
6714 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6715 "Received DVInit via %s%s%s\n",
6716 path,
6717 bi_hop ? "<->" : "-->",
6718 GNUNET_i2s (&GST_my_identity));
6719 GNUNET_free (path);
6720 }
6721
6675 do_fwd = GNUNET_YES; 6722 do_fwd = GNUNET_YES;
6676 if (0 == GNUNET_memcmp (&GST_my_identity, &dvl->initiator)) 6723 if (0 == GNUNET_memcmp (&GST_my_identity, &dvl->initiator))
6677 { 6724 {
@@ -6701,6 +6748,11 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6701 /* assumption: linear latency increase per hop */ 6748 /* assumption: linear latency increase per hop */
6702 ilat = GNUNET_TIME_relative_multiply (network_latency, i); 6749 ilat = GNUNET_TIME_relative_multiply (network_latency, i);
6703 path[i] = hops[i - 1].hop; 6750 path[i] = hops[i - 1].hop;
6751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6752 "Learned path with %u hops to %s with latency %s\n",
6753 i,
6754 GNUNET_i2s (&path[i]),
6755 GNUNET_STRINGS_relative_time_to_string (ilat, GNUNET_YES));
6704 learn_dv_path (path, 6756 learn_dv_path (path,
6705 i, 6757 i,
6706 ilat, 6758 ilat,
@@ -6711,7 +6763,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6711 do_fwd = GNUNET_NO; 6763 do_fwd = GNUNET_NO;
6712 return; 6764 return;
6713 } 6765 }
6714 else if (bi_hop) 6766 if (bi_hop)
6715 { 6767 {
6716 /* last hop was bi-directional, we could learn something here! */ 6768 /* last hop was bi-directional, we could learn something here! */
6717 struct GNUNET_PeerIdentity path[nhops + 2]; 6769 struct GNUNET_PeerIdentity path[nhops + 2];
@@ -6733,6 +6785,10 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6733 path[i + 2] = hops[nhops - i - 2].hop; 6785 path[i + 2] = hops[nhops - i - 2].hop;
6734 } 6786 }
6735 6787
6788 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6789 "Learned inverse path with %u hops to %s\n",
6790 i + 1,
6791 GNUNET_i2s (&path[i + 2]));
6736 iret = learn_dv_path (path, 6792 iret = learn_dv_path (path,
6737 i + 2, 6793 i + 2,
6738 GNUNET_TIME_UNIT_FOREVER_REL, 6794 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -6779,6 +6835,9 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6779 GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator))) 6835 GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator)))
6780 { 6836 {
6781 /* send back to origin! */ 6837 /* send back to origin! */
6838 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6839 "Sending DVL back to initiator %s\n",
6840 GNUNET_i2s (&dvl->initiator));
6782 forward_dv_learn (&dvl->initiator, dvl, bi_history, nhops, hops, in_time); 6841 forward_dv_learn (&dvl->initiator, dvl, bi_history, nhops, hops, in_time);
6783 did_initiator = GNUNET_YES; 6842 did_initiator = GNUNET_YES;
6784 } 6843 }
@@ -6808,6 +6867,9 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6808 nsc.num_selections = calculate_fork_degree (nhops, n_cnt, nsc.num_eligible); 6867 nsc.num_selections = calculate_fork_degree (nhops, n_cnt, nsc.num_eligible);
6809 nsc.num_selections = 6868 nsc.num_selections =
6810 GNUNET_MIN (MAX_DV_DISCOVERY_SELECTION, nsc.num_selections); 6869 GNUNET_MIN (MAX_DV_DISCOVERY_SELECTION, nsc.num_selections);
6870 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6871 "Forwarding DVL to %u other peers\n",
6872 nsc.num_selections);
6811 for (unsigned int i = 0; i < nsc.num_selections; i++) 6873 for (unsigned int i = 0; i < nsc.num_selections; i++)
6812 nsc.selections[i] = 6874 nsc.selections[i] =
6813 (nsc.num_selections == n_cnt) 6875 (nsc.num_selections == n_cnt)
@@ -6900,6 +6962,13 @@ forward_dv_box (struct Neighbour *next_hop,
6900 hops, 6962 hops,
6901 payload, 6963 payload,
6902 payload_size); 6964 payload_size);
6965 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6966 "Routing DV Box of %u bytes from %s at %u/%u hops via %s\n",
6967 payload_size,
6968 GNUNET_i2s (origin),
6969 (unsigned int) num_hops,
6970 (unsigned int) total_hops,
6971 GNUNET_i2s2 (&next_hop->pid));
6903 route_message (&next_hop->pid, &dvb->header, RMO_NONE); 6972 route_message (&next_hop->pid, &dvb->header, RMO_NONE);
6904 GNUNET_free (dvb); 6973 GNUNET_free (dvb);
6905} 6974}
@@ -6923,6 +6992,25 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6923 const struct GNUNET_MessageHeader *inbox = 6992 const struct GNUNET_MessageHeader *inbox =
6924 (const struct GNUNET_MessageHeader *) &hops[num_hops]; 6993 (const struct GNUNET_MessageHeader *) &hops[num_hops];
6925 6994
6995 if (GNUNET_EXTRA_LOGGING > 0)
6996 {
6997 char *path;
6998
6999 path = GNUNET_strdup (GNUNET_i2s (&GST_my_identity));
7000 for (unsigned int i = 0; i < num_hops; i++)
7001 {
7002 char *tmp;
7003
7004 GNUNET_asprintf (&tmp, "%s->%s", path, GNUNET_i2s (&hops[i]));
7005 GNUNET_free (path);
7006 path = tmp;
7007 }
7008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7009 "Received DVBox with remainig path %s\n",
7010 path);
7011 GNUNET_free (path);
7012 }
7013
6926 if (num_hops > 0) 7014 if (num_hops > 0)
6927 { 7015 {
6928 /* We're trying from the end of the hops array, as we may be 7016 /* We're trying from the end of the hops array, as we may be
@@ -6940,6 +7028,10 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6940 n = lookup_neighbour (&hops[i]); 7028 n = lookup_neighbour (&hops[i]);
6941 if (NULL == n) 7029 if (NULL == n)
6942 continue; 7030 continue;
7031 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7032 "Skipping %u/%u hops ahead while routing DV Box\n",
7033 i,
7034 num_hops);
6943 forward_dv_box (n, 7035 forward_dv_box (n,
6944 ntohs (dvb->total_hops) + 1, 7036 ntohs (dvb->total_hops) + 1,
6945 num_hops - i - 1, /* number of hops left */ 7037 num_hops - i - 1, /* number of hops left */
@@ -6947,6 +7039,14 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6947 &hops[i + 1], /* remaining hops */ 7039 &hops[i + 1], /* remaining hops */
6948 (const void *) &dvb[1], 7040 (const void *) &dvb[1],
6949 size); 7041 size);
7042 GNUNET_STATISTICS_update (GST_stats,
7043 "# DV hops skipped routing boxes",
7044 i,
7045 GNUNET_NO);
7046 GNUNET_STATISTICS_update (GST_stats,
7047 "# DV boxes routed (total)",
7048 1,
7049 GNUNET_NO);
6950 finish_cmc_handling (cmc); 7050 finish_cmc_handling (cmc);
6951 return; 7051 return;
6952 } 7052 }
@@ -6959,8 +7059,17 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6959 return; 7059 return;
6960 } 7060 }
6961 /* We are the target. Unbox and handle message. */ 7061 /* We are the target. Unbox and handle message. */
7062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7063 "DVBox received for me from %s\n",
7064 GNUNET_i2s (&dvb->origin));
7065 GNUNET_STATISTICS_update (GST_stats,
7066 "# DV boxes opened (ultimate target)",
7067 1,
7068 GNUNET_NO);
6962 cmc->im.sender = dvb->origin; 7069 cmc->im.sender = dvb->origin;
6963 cmc->total_hops = ntohs (dvb->total_hops); 7070 cmc->total_hops = ntohs (dvb->total_hops);
7071 // FIXME: should *decrypt* inbox here; needs BackchannelEncapsulation!
7072 // FIXME: need to prevent box-in-a-box, so check inbox type!
6964 demultiplex_with_cmc (cmc, inbox); 7073 demultiplex_with_cmc (cmc, inbox);
6965} 7074}
6966 7075
@@ -7011,6 +7120,9 @@ handle_validation_challenge (
7011 finish_cmc_handling (cmc); 7120 finish_cmc_handling (cmc);
7012 return; 7121 return;
7013 } 7122 }
7123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7124 "Received address validation challenge %s\n",
7125 GNUNET_sh2s (&tvc->challenge.value));
7014 tvr = GNUNET_new (struct TransportValidationResponseMessage); 7126 tvr = GNUNET_new (struct TransportValidationResponseMessage);
7015 tvr->header.type = 7127 tvr->header.type =
7016 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE); 7128 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE);
@@ -7206,6 +7318,9 @@ handle_validation_response (
7206 "# Validations dropped, challenge unknown", 7318 "# Validations dropped, challenge unknown",
7207 1, 7319 1,
7208 GNUNET_NO); 7320 GNUNET_NO);
7321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7322 "Validation response %s dropped, challenge unknown\n",
7323 GNUNET_sh2s (&tvr->challenge.value));
7209 finish_cmc_handling (cmc); 7324 finish_cmc_handling (cmc);
7210 return; 7325 return;
7211 } 7326 }
@@ -7263,6 +7378,10 @@ handle_validation_response (
7263 vs->last_challenge_use = 7378 vs->last_challenge_use =
7264 GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet used */ 7379 GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet used */
7265 update_next_challenge_time (vs, vs->first_challenge_use); 7380 update_next_challenge_time (vs, vs->first_challenge_use);
7381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7382 "Validation response %s accepted, address valid until %s\n",
7383 GNUNET_sh2s (&tvr->challenge.value),
7384 GNUNET_STRINGS_absolute_time_to_string (vs->valid_until));
7266 vs->sc = GNUNET_PEERSTORE_store (peerstore, 7385 vs->sc = GNUNET_PEERSTORE_store (peerstore,
7267 "transport", 7386 "transport",
7268 &cmc->im.sender, 7387 &cmc->im.sender,
@@ -7335,6 +7454,9 @@ handle_incoming_msg (void *cls,
7335 7454
7336 cmc->tc = tc; 7455 cmc->tc = tc;
7337 cmc->im = *im; 7456 cmc->im = *im;
7457 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7458 "Received message via communicator from peer %s\n",
7459 GNUNET_i2s (&im->sender));
7338 demultiplex_with_cmc (cmc, (const struct GNUNET_MessageHeader *) &im[1]); 7460 demultiplex_with_cmc (cmc, (const struct GNUNET_MessageHeader *) &im[1]);
7339} 7461}
7340 7462
@@ -7388,6 +7510,10 @@ demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
7388 GNUNET_MQ_handler_end ()}; 7510 GNUNET_MQ_handler_end ()};
7389 int ret; 7511 int ret;
7390 7512
7513 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7514 "Handling message of type %u with %u bytes\n",
7515 (unsigned int) ntohs (msg->type),
7516 (unsigned int) ntohs (msg->size));
7391 ret = GNUNET_MQ_handle_message (handlers, msg); 7517 ret = GNUNET_MQ_handle_message (handlers, msg);
7392 if (GNUNET_SYSERR == ret) 7518 if (GNUNET_SYSERR == ret)
7393 { 7519 {
@@ -7441,6 +7567,9 @@ set_pending_message_uuid (struct PendingMessage *pm)
7441} 7567}
7442 7568
7443 7569
7570// FIXME: add logging logic from here!
7571
7572
7444/** 7573/**
7445 * Setup data structure waiting for acknowledgements. 7574 * Setup data structure waiting for acknowledgements.
7446 * 7575 *