diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-28 13:02:55 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-28 13:02:55 +0000 |
commit | 47cdfc6435d41f410ac7b9d25701905fbdeed6ea (patch) | |
tree | c0d827ea09bc5e3156897156fd5ecda371d32417 /src/transport/gnunet-service-transport_clients.c | |
parent | 78b3c3c0c977d4686cabfc8291d082e517f66998 (diff) | |
download | gnunet-47cdfc6435d41f410ac7b9d25701905fbdeed6ea.tar.gz gnunet-47cdfc6435d41f410ac7b9d25701905fbdeed6ea.zip |
-fix #4025
Diffstat (limited to 'src/transport/gnunet-service-transport_clients.c')
-rw-r--r-- | src/transport/gnunet-service-transport_clients.c | 129 |
1 files changed, 101 insertions, 28 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 | */ | ||
177 | struct 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 | */ |
177 | static struct TransportClient *clients_head; | 211 | static struct TransportClient *clients_head; |
@@ -182,6 +216,14 @@ static struct TransportClient *clients_head; | |||
182 | static struct TransportClient *clients_tail; | 216 | static 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 | */ | ||
224 | static 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 | */ |
187 | static struct AddressToStringContext *a2s_head; | 229 | static 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 | */ | ||
680 | struct 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 | */ | ||
1752 | static int | ||
1753 | mark_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 | */ | ||
1770 | void | ||
1771 | GST_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 */ |