remove CYGWIN codeblocks, drop vendored Windows openvpn, drop win32 specific files.
[oweals/gnunet.git] / src / ats / gnunet-service-ats_connectivity.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2011-2015 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file ats/gnunet-service-ats_connectivity.c
23  * @brief ats service, interaction with 'connecivity' API
24  * @author Matthias Wachs
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
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"
32 #include "ats.h"
33
34
35 /**
36  * Active connection requests.
37  */
38 struct ConnectionRequest {
39   /**
40    * Client that made the request.
41    */
42   struct GNUNET_SERVICE_Client *client;
43
44   /* TODO: allow client to express a 'strength' for this request */
45 };
46
47
48 /**
49  * Address suggestion requests by peer.
50  */
51 static struct GNUNET_CONTAINER_MultiPeerMap *connection_requests;
52
53
54 /**
55  * Is the given peer in the list of peers for which we
56  * have an address request?
57  *
58  * @param cls unused, NULL
59  * @param peer peer to query for
60  * @return #GNUNET_YES if so, #GNUNET_NO if not
61  */
62 unsigned int
63 GAS_connectivity_has_peer(void *cls,
64                           const struct GNUNET_PeerIdentity *peer)
65 {
66   if (NULL == connection_requests)
67     return 0;
68   /* TODO: return sum of 'strength's of connectivity requests */
69   return GNUNET_CONTAINER_multipeermap_contains(connection_requests,
70                                                 peer);
71 }
72
73
74 /**
75  * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS messages from clients.
76  *
77  * @param client client that sent the request
78  * @param message the request message
79  */
80 void
81 GAS_handle_request_address(struct GNUNET_SERVICE_Client *client,
82                            const struct RequestAddressMessage *msg)
83 {
84   struct ConnectionRequest *cr;
85
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);
91   cr->client = client;
92   (void)GNUNET_CONTAINER_multipeermap_put(connection_requests,
93                                           &msg->peer,
94                                           cr,
95                                           GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
96   GAS_plugin_request_connect_start(&msg->peer);
97 }
98
99
100 /**
101  * Free the connection request from the map if the
102  * closure matches the client.
103  *
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)
108  */
109 static int
110 free_matching_requests(void *cls,
111                        const struct GNUNET_PeerIdentity *pid,
112                        void *value)
113 {
114   struct GNUNET_SERVICE_Client *client = cls;
115   struct ConnectionRequest *cr = value;
116
117   if (cr->client == client)
118     {
119       GAS_plugin_request_connect_stop(pid);
120       GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
121                  "Removed request pending for peer `%s\n",
122                  GNUNET_i2s(pid));
123       GNUNET_assert(GNUNET_YES ==
124                     GNUNET_CONTAINER_multipeermap_remove(connection_requests,
125                                                          pid,
126                                                          cr));
127       GNUNET_free(cr);
128     }
129   return GNUNET_OK;
130 }
131
132
133 /**
134  * Handle #GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL messages
135  * from clients.
136  *
137  * @param client the client that sent the request
138  * @param msg the request message
139  */
140 void
141 GAS_handle_request_address_cancel(struct GNUNET_SERVICE_Client *client,
142                                   const struct RequestAddressMessage *msg)
143 {
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,
149                                              &msg->peer,
150                                              &free_matching_requests,
151                                              client);
152 }
153
154
155 /**
156  * Unregister a client (which may have been a connectivity client,
157  * but this is not assured).
158  *
159  * @param client handle of the (now dead) client
160  */
161 void
162 GAS_connectivity_remove_client(struct GNUNET_SERVICE_Client *client)
163 {
164   GNUNET_CONTAINER_multipeermap_iterate(connection_requests,
165                                         &free_matching_requests,
166                                         client);
167 }
168
169
170 /**
171  * Shutdown connectivity subsystem.
172  */
173 void
174 GAS_connectivity_init()
175 {
176   connection_requests
177     = GNUNET_CONTAINER_multipeermap_create(32,
178                                            GNUNET_NO);
179 }
180
181
182 /**
183  * Free the connection request from the map.
184  *
185  * @param cls NULL
186  * @param pid peer for which the request was made
187  * @param value the `struct ConnectionRequest`
188  * @return #GNUNET_OK (continue to iterate)
189  */
190 static int
191 free_request(void *cls,
192              const struct GNUNET_PeerIdentity *pid,
193              void *value)
194 {
195   struct ConnectionRequest *cr = value;
196
197   free_matching_requests(cr->client,
198                          pid,
199                          cr);
200   return GNUNET_OK;
201 }
202
203
204 /**
205  * Shutdown connectivity subsystem.
206  */
207 void
208 GAS_connectivity_done()
209 {
210   GAS_plugin_solver_lock();
211   GNUNET_CONTAINER_multipeermap_iterate(connection_requests,
212                                         &free_request,
213                                         NULL);
214   GAS_plugin_solver_unlock();
215   GNUNET_CONTAINER_multipeermap_destroy(connection_requests);
216   connection_requests = NULL;
217 }
218
219
220 /* end of gnunet-service-ats_connectivity.c */