aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-10-28 13:02:55 +0000
committerChristian Grothoff <christian@grothoff.org>2015-10-28 13:02:55 +0000
commit47cdfc6435d41f410ac7b9d25701905fbdeed6ea (patch)
treec0d827ea09bc5e3156897156fd5ecda371d32417 /src/transport
parent78b3c3c0c977d4686cabfc8291d082e517f66998 (diff)
downloadgnunet-47cdfc6435d41f410ac7b9d25701905fbdeed6ea.tar.gz
gnunet-47cdfc6435d41f410ac7b9d25701905fbdeed6ea.zip
-fix #4025
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport_clients.c129
-rw-r--r--src/transport/gnunet-service-transport_clients.h10
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c9
3 files changed, 112 insertions, 36 deletions
diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c
index 3a7f10337..86c833c5b 100644
--- a/src/transport/gnunet-service-transport_clients.c
+++ b/src/transport/gnunet-service-transport_clients.c
@@ -172,6 +172,40 @@ struct MonitoringClient
172 172
173 173
174/** 174/**
175 * Closure for #handle_send_transmit_continuation()
176 */
177struct SendTransmitContinuationContext
178{
179 /**
180 * Client that made the request.
181 */
182 struct GNUNET_SERVER_Client *client;
183
184 /**
185 * Peer that was the target.
186 */
187 struct GNUNET_PeerIdentity target;
188
189 /**
190 * At what time did we receive the message?
191 */
192 struct GNUNET_TIME_Absolute send_time;
193
194 /**
195 * Unique ID, for logging.
196 */
197 unsigned long long uuid;
198
199 /**
200 * Set to #GNUNET_YES if the connection for @e target goes
201 * down and we thus must no longer send the
202 * #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK message.
203 */
204 int down;
205};
206
207
208/**
175 * Head of linked list of all clients to this service. 209 * Head of linked list of all clients to this service.
176 */ 210 */
177static struct TransportClient *clients_head; 211static struct TransportClient *clients_head;
@@ -182,6 +216,14 @@ static struct TransportClient *clients_head;
182static struct TransportClient *clients_tail; 216static struct TransportClient *clients_tail;
183 217
184/** 218/**
219 * Map of peer identities to active send transmit continuation
220 * contexts. Used to flag contexts as 'dead' when a connection goes
221 * down. Values are of type `struct SendTransmitContinuationContext
222 * *`.
223 */
224static struct GNUNET_CONTAINER_MultiPeerMap *active_stccs;
225
226/**
185 * Head of linked list of all pending address iterations 227 * Head of linked list of all pending address iterations
186 */ 228 */
187static struct AddressToStringContext *a2s_head; 229static struct AddressToStringContext *a2s_head;
@@ -675,33 +717,6 @@ clients_handle_hello (void *cls,
675 717
676 718
677/** 719/**
678 * Closure for #handle_send_transmit_continuation()
679 */
680struct SendTransmitContinuationContext
681{
682 /**
683 * Client that made the request.
684 */
685 struct GNUNET_SERVER_Client *client;
686
687 /**
688 * Peer that was the target.
689 */
690 struct GNUNET_PeerIdentity target;
691
692 /**
693 * At what time did we receive the message?
694 */
695 struct GNUNET_TIME_Absolute send_time;
696
697 /**
698 * Unique ID, for logging.
699 */
700 unsigned long long uuid;
701};
702
703
704/**
705 * Function called after the transmission is done. Notify the client that it is 720 * Function called after the transmission is done. Notify the client that it is
706 * OK to send the next message. 721 * OK to send the next message.
707 * 722 *
@@ -744,7 +759,7 @@ handle_send_transmit_continuation (void *cls,
744 success, 759 success,
745 (NULL != addr) ? addr->transport_name : "%"); 760 (NULL != addr) ? addr->transport_name : "%");
746 761
747 if (GST_neighbours_test_connected (&stcc->target)) 762 if (GNUNET_NO == stcc->down)
748 { 763 {
749 /* Only send confirmation if we are still connected */ 764 /* Only send confirmation if we are still connected */
750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -761,6 +776,10 @@ handle_send_transmit_continuation (void *cls,
761 GNUNET_NO); 776 GNUNET_NO);
762 } 777 }
763 GNUNET_SERVER_client_drop (stcc->client); 778 GNUNET_SERVER_client_drop (stcc->client);
779 GNUNET_assert (GNUNET_OK ==
780 GNUNET_CONTAINER_multipeermap_remove (active_stccs,
781 &stcc->target,
782 stcc));
764 GNUNET_free (stcc); 783 GNUNET_free (stcc);
765} 784}
766 785
@@ -842,6 +861,10 @@ clients_handle_send (void *cls,
842 stcc->client = client; 861 stcc->client = client;
843 stcc->send_time = GNUNET_TIME_absolute_get (); 862 stcc->send_time = GNUNET_TIME_absolute_get ();
844 stcc->uuid = uuid_gen++; 863 stcc->uuid = uuid_gen++;
864 (void) GNUNET_CONTAINER_multipeermap_put (active_stccs,
865 &stcc->target,
866 stcc,
867 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
845 GNUNET_SERVER_client_keep (client); 868 GNUNET_SERVER_client_keep (client);
846 GST_manipulation_send (&obm->peer, 869 GST_manipulation_send (&obm->peer,
847 obmm, 870 obmm,
@@ -1548,6 +1571,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server)
1548 sizeof (struct GNUNET_MessageHeader) }, 1571 sizeof (struct GNUNET_MessageHeader) },
1549 {NULL, NULL, 0, 0} 1572 {NULL, NULL, 0, 0}
1550 }; 1573 };
1574 active_stccs = GNUNET_CONTAINER_multipeermap_create (128,
1575 GNUNET_YES);
1551 peer_nc = GNUNET_SERVER_notification_context_create (server, 0); 1576 peer_nc = GNUNET_SERVER_notification_context_create (server, 0);
1552 val_nc = GNUNET_SERVER_notification_context_create (server, 0); 1577 val_nc = GNUNET_SERVER_notification_context_create (server, 0);
1553 plugin_nc = GNUNET_SERVER_notification_context_create (server, 0); 1578 plugin_nc = GNUNET_SERVER_notification_context_create (server, 0);
@@ -1587,6 +1612,8 @@ GST_clients_stop ()
1587 GNUNET_SERVER_notification_context_destroy (plugin_nc); 1612 GNUNET_SERVER_notification_context_destroy (plugin_nc);
1588 plugin_nc = NULL; 1613 plugin_nc = NULL;
1589 } 1614 }
1615 GNUNET_CONTAINER_multipeermap_destroy (active_stccs);
1616 active_stccs = NULL;
1590} 1617}
1591 1618
1592 1619
@@ -1713,4 +1740,50 @@ GST_clients_broadcast_validation_notification (const struct GNUNET_PeerIdentity
1713} 1740}
1714 1741
1715 1742
1743/**
1744 * Mark the peer as down so we don't call the continuation
1745 * context in the future.
1746 *
1747 * @param cls NULL
1748 * @param peer peer that got disconnected
1749 * @param value a `struct SendTransmitContinuationContext` to mark
1750 * @return #GNUNET_OK (continue to iterate)
1751 */
1752static int
1753mark_peer_down (void *cls,
1754 const struct GNUNET_PeerIdentity *peer,
1755 void *value)
1756{
1757 struct SendTransmitContinuationContext *stcc = value;
1758
1759 stcc->down = GNUNET_YES;
1760 return GNUNET_OK;
1761}
1762
1763
1764/**
1765 * Notify all clients about a disconnect, and cancel
1766 * pending SEND_OK messages for this peer.
1767 *
1768 * @param peer peer that disconnected
1769 */
1770void
1771GST_clients_broadcast_disconnect (const struct GNUNET_PeerIdentity *peer)
1772{
1773 struct DisconnectInfoMessage disconnect_msg;
1774
1775 GNUNET_CONTAINER_multipeermap_get_multiple (active_stccs,
1776 peer,
1777 &mark_peer_down,
1778 NULL);
1779 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage));
1780 disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
1781 disconnect_msg.reserved = htonl (0);
1782 disconnect_msg.peer = *peer;
1783 GST_clients_broadcast (&disconnect_msg.header,
1784 GNUNET_NO);
1785
1786}
1787
1788
1716/* end of file gnunet-service-transport_clients.c */ 1789/* end of file gnunet-service-transport_clients.c */
diff --git a/src/transport/gnunet-service-transport_clients.h b/src/transport/gnunet-service-transport_clients.h
index a7cfe7815..d46fd82ca 100644
--- a/src/transport/gnunet-service-transport_clients.h
+++ b/src/transport/gnunet-service-transport_clients.h
@@ -88,6 +88,16 @@ GST_clients_broadcast_peer_notification (const struct GNUNET_PeerIdentity *peer,
88 88
89 89
90/** 90/**
91 * Notify all clients about a disconnect, and cancel
92 * pending SEND_OK messages for this peer.
93 *
94 * @param peer peer that disconnected
95 */
96void
97GST_clients_broadcast_disconnect (const struct GNUNET_PeerIdentity *peer);
98
99
100/**
91 * Broadcast the new validation changes to all clients monitoring the peer. 101 * Broadcast the new validation changes to all clients monitoring the peer.
92 * 102 *
93 * @param peer peer this update is about (never NULL) 103 * @param peer peer this update is about (never NULL)
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 6664dd332..9f4982b67 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -597,18 +597,11 @@ neighbours_connect_notification (struct NeighbourMapEntry *n)
597static void 597static void
598neighbours_disconnect_notification (struct NeighbourMapEntry *n) 598neighbours_disconnect_notification (struct NeighbourMapEntry *n)
599{ 599{
600 struct DisconnectInfoMessage disconnect_msg;
601
602 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 600 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
603 "Peer `%s' disconnected\n", 601 "Peer `%s' disconnected\n",
604 GNUNET_i2s (&n->id)); 602 GNUNET_i2s (&n->id));
605 GST_manipulation_peer_disconnect (&n->id); 603 GST_manipulation_peer_disconnect (&n->id);
606 disconnect_msg.header.size = htons (sizeof(struct DisconnectInfoMessage)); 604 GST_clients_broadcast_disconnect (&n->id);
607 disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
608 disconnect_msg.reserved = htonl (0);
609 disconnect_msg.peer = n->id;
610 GST_clients_broadcast (&disconnect_msg.header,
611 GNUNET_NO);
612} 605}
613 606
614 607