GNUnet  0.19.4
ats_api_connectivity.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2016 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  */
26 #include "platform.h"
27 #include "gnunet_ats_service.h"
28 #include "ats.h"
29 
30 
31 #define LOG(kind, ...) GNUNET_log_from (kind, "ats-connectivity-api", \
32  __VA_ARGS__)
33 
34 
39 {
43  struct GNUNET_PeerIdentity id;
44 
49 
53  uint32_t strength;
54 };
55 
56 
61 {
66 
73 
78 
83 
88 };
89 
90 
96 static void
98 
99 
105 static void
106 reconnect_task (void *cls)
107 {
108  struct GNUNET_ATS_ConnectivityHandle *ch = cls;
109 
110  ch->task = NULL;
111  reconnect (ch);
112 }
113 
114 
120 static void
122 {
123  if (NULL != ch->mq)
124  {
126  ch->mq = NULL;
127  }
128  ch->backoff = GNUNET_TIME_STD_BACKOFF (ch->backoff);
129  ch->task = GNUNET_SCHEDULER_add_delayed (ch->backoff,
131  ch);
132 }
133 
134 
142 static void
143 error_handler (void *cls,
144  enum GNUNET_MQ_Error error)
145 {
146  struct GNUNET_ATS_ConnectivityHandle *ch = cls;
147 
149  "ATS connection died (code %d), reconnecting\n",
150  (int) error);
152 }
153 
154 
164 static int
166  const struct GNUNET_PeerIdentity *peer,
167  void *value)
168 {
169  struct GNUNET_ATS_ConnectivityHandle *ch = cls;
171  struct GNUNET_MQ_Envelope *ev;
172  struct RequestAddressMessage *m;
173 
174  if (NULL == ch->mq)
175  return GNUNET_SYSERR;
177  m->strength = htonl (sh->strength);
178  m->peer = *peer;
179  GNUNET_MQ_send (ch->mq, ev);
180  return GNUNET_OK;
181 }
182 
183 
189 static void
191 {
192  static const struct GNUNET_MQ_MessageHandler handlers[] =
193  { { NULL, 0, 0 } };
194  struct GNUNET_MQ_Envelope *ev;
195  struct ClientStartMessage *init;
196 
197  GNUNET_assert (NULL == ch->mq);
198  ch->mq = GNUNET_CLIENT_connect (ch->cfg,
199  "ats",
200  handlers,
201  &error_handler,
202  ch);
203  if (NULL == ch->mq)
204  {
206  return;
207  }
208  ev = GNUNET_MQ_msg (init,
210  init->start_flag = htonl (START_FLAG_CONNECTION_SUGGESTION);
211  GNUNET_MQ_send (ch->mq, ev);
212  if (NULL == ch->mq)
213  return;
216  ch);
217 }
218 
219 
228 {
230 
232  ch->cfg = cfg;
233  ch->sug_requests = GNUNET_CONTAINER_multipeermap_create (32,
234  GNUNET_YES);
235  reconnect (ch);
236  return ch;
237 }
238 
239 
249 static int
250 free_sug_handle (void *cls,
251  const struct GNUNET_PeerIdentity *key,
252  void *value)
253 {
255 
256  GNUNET_free (cur);
257  return GNUNET_OK;
258 }
259 
260 
266 void
268 {
269  if (NULL != ch->mq)
270  {
272  ch->mq = NULL;
273  }
274  if (NULL != ch->task)
275  {
276  GNUNET_SCHEDULER_cancel (ch->task);
277  ch->task = NULL;
278  }
281  NULL);
283  GNUNET_free (ch);
284 }
285 
286 
300  const struct GNUNET_PeerIdentity *peer,
301  uint32_t strength)
302 {
304 
306  s->ch = ch;
307  s->id = *peer;
308  s->strength = strength;
309  if (GNUNET_OK !=
310  GNUNET_CONTAINER_multipeermap_put (ch->sug_requests,
311  &s->id,
312  s,
314  {
316  "Not requesting ATS to suggest address for `%s', request already pending\n",
317  GNUNET_i2s (peer));
318  GNUNET_free (s);
319  return NULL;
320  }
322  "Requesting ATS to suggest address for `%s'\n",
323  GNUNET_i2s (peer));
324  if (NULL == ch->mq)
325  return s;
326  (void) transmit_suggestion (ch,
327  &s->id,
328  s);
329  return s;
330 }
331 
332 
333 void
336 {
337  struct GNUNET_ATS_ConnectivityHandle *ch = sh->ch;
338  struct GNUNET_MQ_Envelope *ev;
339  struct RequestAddressMessage *m;
340 
342  "Telling ATS we no longer care for an address for `%s'\n",
343  GNUNET_i2s (&sh->id));
346  &sh->id,
347  sh));
348  if (NULL == ch->mq)
349  {
350  GNUNET_free (sh);
351  return;
352  }
353  ev = GNUNET_MQ_msg (m,
355  m->strength = htonl (0);
356  m->peer = sh->id;
357  GNUNET_MQ_send (ch->mq, ev);
358  GNUNET_free (sh);
359 }
360 
361 
362 /* end of ats_api_connectivity.c */
automatic transport selection messages
@ START_FLAG_CONNECTION_SUGGESTION
Connection suggestion handle.
Definition: ats.h:59
static void reconnect(struct GNUNET_ATS_ConnectivityHandle *ch)
Re-establish the connection to the ATS service.
static void error_handler(void *cls, enum GNUNET_MQ_Error error)
We encountered an error handling the MQ to the ATS service.
static int transmit_suggestion(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Transmit request for an address suggestion.
static void force_reconnect(struct GNUNET_ATS_ConnectivityHandle *ch)
Disconnect from ATS and then reconnect.
static int free_sug_handle(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called to free all struct GNUNET_ATS_ConnectivitySuggestHandles in the map.
#define LOG(kind,...)
static void reconnect_task(void *cls)
Re-establish the connection to the ATS service.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
static char * init
Set to the name of a service to start.
Definition: gnunet-arm.c:74
static struct SolverHandle * sh
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
Automatic transport selection and outbound bandwidth determination.
struct GNUNET_ATS_ConnectivityHandle * GNUNET_ATS_connectivity_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the ATS connectivity suggestion client handle.
struct GNUNET_ATS_ConnectivitySuggestHandle * GNUNET_ATS_connectivity_suggest(struct GNUNET_ATS_ConnectivityHandle *ch, const struct GNUNET_PeerIdentity *peer, uint32_t strength)
We would like to receive address suggestions for a peer.
void GNUNET_ATS_connectivity_done(struct GNUNET_ATS_ConnectivityHandle *ch)
Client is done with ATS connectivity management, release resources.
void GNUNET_ATS_connectivity_suggest_cancel(struct GNUNET_ATS_ConnectivitySuggestHandle *sh)
We no longer care about being connected to a peer.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS
Type of the 'struct RequestAddressMessage' sent by clients to ATS to request an address to help conne...
#define GNUNET_MESSAGE_TYPE_ATS_START
Type of the 'struct ClientStartMessage' sent by clients to ATS to identify the type of the client.
#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL
Type of the 'struct RequestAddressMessage' sent by clients to ATS to request an address to help conne...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
First message any client sends to ATS, used to self-identify (what type of client this is).
Definition: ats.h:70
Handle to the ATS subsystem for connectivity management.
struct GNUNET_CONTAINER_MultiPeerMap * sug_requests
Map with the identities of all the peers for which we would like to have address suggestions.
struct GNUNET_TIME_Relative backoff
Reconnect backoff delay.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_SCHEDULER_Task * task
Task to trigger reconnect.
struct GNUNET_MQ_Handle * mq
Message queue for sending requests to the ATS service.
Handle for ATS address suggestion requests.
struct GNUNET_PeerIdentity id
ID of the peer for which address suggestion was requested.
struct GNUNET_ATS_ConnectivityHandle * ch
Connecitivity handle this suggestion handle belongs to.
uint32_t strength
How urgent is the request.
struct GNUNET_MQ_Handle * mq
Message Queue for the channel (which we are implementing).
Definition: cadet.h:142
Internal representation of the hash map.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.
Connectivity client to ATS service: we would like to have address suggestions for this peer.
Definition: ats.h:88
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.