-fixing silly NPEs
[oweals/gnunet.git] / src / ats / gnunet-service-ats_connectivity.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011-2015 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
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   /**
41    * Client that made the request.
42    */
43   struct GNUNET_SERVER_Client *client;
44 };
45
46
47 /**
48  * Address suggestion requests by peer.
49  */
50 static struct GNUNET_CONTAINER_MultiPeerMap *connection_requests;
51
52
53 /**
54  * Handle 'request address' messages from clients.
55  *
56  * @param cls unused, NULL
57  * @param client client that sent the request
58  * @param message the request message
59  */
60 void
61 GAS_handle_request_address (void *cls,
62                             struct GNUNET_SERVER_Client *client,
63                             const struct GNUNET_MessageHeader *message)
64 {
65   const struct RequestAddressMessage *msg =
66       (const struct RequestAddressMessage *) message;
67   struct ConnectionRequest *cr;
68
69   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
70               "Received `%s' message\n",
71               "REQUEST_ADDRESS");
72   GNUNET_break (0 == ntohl (msg->reserved));
73   cr = GNUNET_new (struct ConnectionRequest);
74   cr->client = client;
75   (void) GNUNET_CONTAINER_multipeermap_put (connection_requests,
76                                             &msg->peer,
77                                             cr,
78                                             GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
79   GAS_plugin_request_connect_start (&msg->peer);
80   GNUNET_SERVER_receive_done (client, GNUNET_OK);
81 }
82
83
84 /**
85  * Free the connection request from the map if the
86  * closure matches the client.
87  *
88  * @param cls the client to match
89  * @param pid peer for which the request was made
90  * @param value the `struct ConnectionRequest`
91  * @return #GNUNET_OK (continue to iterate)
92  */
93 static int
94 free_matching_requests (void *cls,
95                         const struct GNUNET_PeerIdentity *pid,
96                         void *value)
97 {
98   struct GNUNET_SERVER_Client *client = cls;
99   struct ConnectionRequest *cr = value;
100
101   if (cr->client == client)
102   {
103     GAS_plugin_request_connect_stop (pid);
104     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
105                 "Removed request pending for peer `%s\n",
106                 GNUNET_i2s (pid));
107     GNUNET_assert (GNUNET_YES ==
108                    GNUNET_CONTAINER_multipeermap_remove (connection_requests,
109                                                          pid,
110                                                          cr));
111     GNUNET_free (cr);
112   }
113   return GNUNET_OK;
114 }
115
116
117 /**
118  * Handle 'request address cancel' messages from clients.
119  *
120  * @param cls unused, NULL
121  * @param client client that sent the request
122  * @param message the request message
123  */
124 void
125 GAS_handle_request_address_cancel (void *cls,
126                                    struct GNUNET_SERVER_Client *client,
127                                    const struct GNUNET_MessageHeader *message)
128 {
129   const struct RequestAddressMessage *msg =
130       (const struct RequestAddressMessage *) message;
131
132   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
133               "Received REQUEST_ADDRESS_CANCEL message for peer %s\n",
134               GNUNET_i2s (&msg->peer));
135   GNUNET_break (0 == ntohl (msg->reserved));
136   GNUNET_CONTAINER_multipeermap_get_multiple (connection_requests,
137                                               &msg->peer,
138                                               &free_matching_requests,
139                                               client);
140   GNUNET_SERVER_receive_done (client, GNUNET_OK);
141 }
142
143
144 /**
145  * Unregister a client (which may have been a connectivity client,
146  * but this is not assured).
147  *
148  * @param client handle of the (now dead) client
149  */
150 void
151 GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client)
152 {
153   GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
154                                          &free_matching_requests,
155                                          client);
156 }
157
158
159 /**
160  * Shutdown connectivity subsystem.
161  */
162 void
163 GAS_connectivity_init ()
164 {
165   connection_requests = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_NO);
166 }
167
168
169 /**
170  * Free the connection request from the map.
171  *
172  * @param cls NULL
173  * @param pid peer for which the request was made
174  * @param value the `struct ConnectionRequest`
175  * @return #GNUNET_OK (continue to iterate)
176  */
177 static int
178 free_request (void *cls,
179               const struct GNUNET_PeerIdentity *pid,
180               void *value)
181 {
182   struct ConnectionRequest *cr = value;
183
184   free_matching_requests (cr->client,
185                           pid,
186                           cr);
187   return GNUNET_OK;
188 }
189
190
191 /**
192  * Shutdown connectivity subsystem.
193  */
194 void
195 GAS_connectivity_done ()
196 {
197   GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
198                                          &free_request,
199                                          NULL);
200   GNUNET_CONTAINER_multipeermap_destroy (connection_requests);
201 }
202
203
204 /* end of gnunet-service-ats_connectivity.c */