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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file ats/gnunet-service-ats_connectivity.c
23 * @brief ats service, interaction with 'connecivity' API
24 * @author Matthias Wachs
25 * @author Christian Grothoff
28 #include "gnunet-service-ats.h"
29 #include "gnunet-service-ats_addresses.h"
30 #include "gnunet-service-ats_connectivity.h"
31 #include "gnunet-service-ats_plugins.h"
36 * Active connection requests.
38 struct ConnectionRequest {
40 * Client that made the request.
42 struct GNUNET_SERVICE_Client *client;
44 /* TODO: allow client to express a 'strength' for this request */
49 * Address suggestion requests by peer.
51 static struct GNUNET_CONTAINER_MultiPeerMap *connection_requests;
55 * Is the given peer in the list of peers for which we
56 * have an address request?
58 * @param cls unused, NULL
59 * @param peer peer to query for
60 * @return #GNUNET_YES if so, #GNUNET_NO if not
63 GAS_connectivity_has_peer(void *cls,
64 const struct GNUNET_PeerIdentity *peer)
66 if (NULL == connection_requests)
68 /* TODO: return sum of 'strength's of connectivity requests */
69 return GNUNET_CONTAINER_multipeermap_contains(connection_requests,
75 * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS messages from clients.
77 * @param client client that sent the request
78 * @param message the request message
81 GAS_handle_request_address(struct GNUNET_SERVICE_Client *client,
82 const struct RequestAddressMessage *msg)
84 struct ConnectionRequest *cr;
86 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
87 "Received `%s' message\n",
88 "GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS");
89 /* FIXME: should not ignore "msg->strength" */
90 cr = GNUNET_new(struct ConnectionRequest);
92 (void)GNUNET_CONTAINER_multipeermap_put(connection_requests,
95 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
96 GAS_plugin_request_connect_start(&msg->peer);
101 * Free the connection request from the map if the
102 * closure matches the client.
104 * @param cls the client to match
105 * @param pid peer for which the request was made
106 * @param value the `struct ConnectionRequest`
107 * @return #GNUNET_OK (continue to iterate)
110 free_matching_requests(void *cls,
111 const struct GNUNET_PeerIdentity *pid,
114 struct GNUNET_SERVICE_Client *client = cls;
115 struct ConnectionRequest *cr = value;
117 if (cr->client == client)
119 GAS_plugin_request_connect_stop(pid);
120 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
121 "Removed request pending for peer `%s\n",
123 GNUNET_assert(GNUNET_YES ==
124 GNUNET_CONTAINER_multipeermap_remove(connection_requests,
134 * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL messages
137 * @param client the client that sent the request
138 * @param msg the request message
141 GAS_handle_request_address_cancel(struct GNUNET_SERVICE_Client *client,
142 const struct RequestAddressMessage *msg)
144 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
145 "Received GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL message for peer %s\n",
146 GNUNET_i2s(&msg->peer));
147 GNUNET_break(0 == ntohl(msg->strength));
148 GNUNET_CONTAINER_multipeermap_get_multiple(connection_requests,
150 &free_matching_requests,
156 * Unregister a client (which may have been a connectivity client,
157 * but this is not assured).
159 * @param client handle of the (now dead) client
162 GAS_connectivity_remove_client(struct GNUNET_SERVICE_Client *client)
164 GNUNET_CONTAINER_multipeermap_iterate(connection_requests,
165 &free_matching_requests,
171 * Shutdown connectivity subsystem.
174 GAS_connectivity_init()
177 = GNUNET_CONTAINER_multipeermap_create(32,
183 * Free the connection request from the map.
186 * @param pid peer for which the request was made
187 * @param value the `struct ConnectionRequest`
188 * @return #GNUNET_OK (continue to iterate)
191 free_request(void *cls,
192 const struct GNUNET_PeerIdentity *pid,
195 struct ConnectionRequest *cr = value;
197 free_matching_requests(cr->client,
205 * Shutdown connectivity subsystem.
208 GAS_connectivity_done()
210 GAS_plugin_solver_lock();
211 GNUNET_CONTAINER_multipeermap_iterate(connection_requests,
214 GAS_plugin_solver_unlock();
215 GNUNET_CONTAINER_multipeermap_destroy(connection_requests);
216 connection_requests = NULL;
220 /* end of gnunet-service-ats_connectivity.c */