2 This file is part of GNUnet.
3 Copyright (C) 2011-2015 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file ats/gnunet-service-ats_connectivity.c
21 * @brief ats service, interaction with 'connecivity' API
22 * @author Matthias Wachs
23 * @author Christian Grothoff
26 #include "gnunet-service-ats.h"
27 #include "gnunet-service-ats_addresses.h"
28 #include "gnunet-service-ats_connectivity.h"
29 #include "gnunet-service-ats_plugins.h"
34 * Active connection requests.
36 struct ConnectionRequest
39 * Client that made the request.
41 struct GNUNET_SERVICE_Client *client;
43 /* TODO: allow client to express a 'strength' for this request */
48 * Address suggestion requests by peer.
50 static struct GNUNET_CONTAINER_MultiPeerMap *connection_requests;
54 * Is the given peer in the list of peers for which we
55 * have an address request?
57 * @param cls unused, NULL
58 * @param peer peer to query for
59 * @return #GNUNET_YES if so, #GNUNET_NO if not
62 GAS_connectivity_has_peer (void *cls,
63 const struct GNUNET_PeerIdentity *peer)
65 if (NULL == connection_requests)
67 /* TODO: return sum of 'strength's of connectivity requests */
68 return GNUNET_CONTAINER_multipeermap_contains (connection_requests,
74 * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS messages from clients.
76 * @param client client that sent the request
77 * @param message the request message
80 GAS_handle_request_address (struct GNUNET_SERVICE_Client *client,
81 const struct RequestAddressMessage *msg)
83 struct ConnectionRequest *cr;
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Received `%s' message\n",
87 "GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS");
88 /* FIXME: should not ignore "msg->strength" */
89 cr = GNUNET_new (struct ConnectionRequest);
91 (void) GNUNET_CONTAINER_multipeermap_put (connection_requests,
94 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
95 GAS_plugin_request_connect_start (&msg->peer);
100 * Free the connection request from the map if the
101 * closure matches the client.
103 * @param cls the client to match
104 * @param pid peer for which the request was made
105 * @param value the `struct ConnectionRequest`
106 * @return #GNUNET_OK (continue to iterate)
109 free_matching_requests (void *cls,
110 const struct GNUNET_PeerIdentity *pid,
113 struct GNUNET_SERVICE_Client *client = cls;
114 struct ConnectionRequest *cr = value;
116 if (cr->client == client)
118 GAS_plugin_request_connect_stop (pid);
119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
120 "Removed request pending for peer `%s\n",
122 GNUNET_assert (GNUNET_YES ==
123 GNUNET_CONTAINER_multipeermap_remove (connection_requests,
133 * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL messages
136 * @param client the client that sent the request
137 * @param msg the request message
140 GAS_handle_request_address_cancel (struct GNUNET_SERVICE_Client *client,
141 const struct RequestAddressMessage *msg)
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
144 "Received GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL message for peer %s\n",
145 GNUNET_i2s (&msg->peer));
146 GNUNET_break (0 == ntohl (msg->strength));
147 GNUNET_CONTAINER_multipeermap_get_multiple (connection_requests,
149 &free_matching_requests,
155 * Unregister a client (which may have been a connectivity client,
156 * but this is not assured).
158 * @param client handle of the (now dead) client
161 GAS_connectivity_remove_client (struct GNUNET_SERVICE_Client *client)
163 GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
164 &free_matching_requests,
170 * Shutdown connectivity subsystem.
173 GAS_connectivity_init ()
176 = GNUNET_CONTAINER_multipeermap_create (32,
182 * Free the connection request from the map.
185 * @param pid peer for which the request was made
186 * @param value the `struct ConnectionRequest`
187 * @return #GNUNET_OK (continue to iterate)
190 free_request (void *cls,
191 const struct GNUNET_PeerIdentity *pid,
194 struct ConnectionRequest *cr = value;
196 free_matching_requests (cr->client,
204 * Shutdown connectivity subsystem.
207 GAS_connectivity_done ()
209 GAS_plugin_solver_lock ();
210 GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
213 GAS_plugin_solver_unlock ();
214 GNUNET_CONTAINER_multipeermap_destroy (connection_requests);
215 connection_requests = NULL;
219 /* end of gnunet-service-ats_connectivity.c */