GNUnet  0.10.x
gnunet-service-transport_hello.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010,2011 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 
26 #include "platform.h"
27 #include "gnunet_constants.h"
28 #include "gnunet_hello_lib.h"
34 
35 
39 #define HELLO_REFRESH_PERIOD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
40 
45 
46 
52 {
57 
62 
67 
73 
78 
84  unsigned int rc;
85 
86 };
87 
88 
93 
98 
102 static void *hello_cb_cls;
103 
107 static struct OwnAddressList *oal_head;
108 
112 static struct OwnAddressList *oal_tail;
113 
117 static int friend_option;
118 
123 
124 
129 {
134 
139 };
140 
141 
151 static ssize_t
152 address_generator (void *cls,
153  size_t max,
154  void *buf)
155 {
156  struct GeneratorContext *gc = cls;
157  ssize_t ret;
158 
159  if (NULL == gc->addr_pos)
160  return GNUNET_SYSERR; /* Done */
162  gc->expiration,
163  buf,
164  max);
165  gc->addr_pos = gc->addr_pos->next;
166  return ret;
167 }
168 
169 
176 static void
178 {
179  struct GeneratorContext gc;
180 
181  hello_task = NULL;
182  gc.addr_pos = oal_head;
184 
185  GNUNET_free_non_null (our_hello);
188  &gc,
189  friend_option);
191  "Refreshed my %s HELLO, new size is %d\n",
192  (GNUNET_YES == friend_option) ? "friend-only" : "public",
193  GNUNET_HELLO_size (our_hello));
195  gettext_noop ("# refreshed my HELLO"),
196  1,
197  GNUNET_NO);
198  if (NULL != hello_cb)
200  GST_hello_get ());
202  our_hello,
203  NULL,
204  NULL);
205  hello_task =
208  NULL);
209 }
210 
211 
217 static void
219 {
220  if (NULL != hello_task)
221  {
222  GNUNET_SCHEDULER_cancel (hello_task);
224  NULL);
225  }
226 }
227 
228 
236 void
237 GST_hello_start (int friend_only,
239  void *cb_cls)
240 {
241  hello_cb = cb;
242  hello_cb_cls = cb_cls;
243  friend_option = friend_only;
244  refresh_hello_task (NULL);
245 }
246 
247 
251 void
253 {
254  hello_cb = NULL;
255  hello_cb_cls = NULL;
256  if (NULL != hello_task)
257  {
258  GNUNET_SCHEDULER_cancel (hello_task);
259  hello_task = NULL;
260  }
261  if (NULL != our_hello)
262  {
263  GNUNET_free (our_hello);
264  our_hello = NULL;
265  }
266 }
267 
268 
274 const struct GNUNET_MessageHeader *
276 {
277  return (const struct GNUNET_MessageHeader *) our_hello;
278 }
279 
280 
287 void
289  const struct GNUNET_HELLO_Address *address)
290 {
291  struct OwnAddressList *al;
292 
294  (GNUNET_YES == addremove)
295  ? "Adding `%s' to the set of our addresses\n"
296  : "Removing `%s' from the set of our addresses\n",
297  GST_plugins_a2s (address));
298  GNUNET_assert (NULL != address);
299  for (al = oal_head; al != NULL; al = al->next)
300  if (0 == GNUNET_HELLO_address_cmp (address, al->address))
301  break;
302  if (GNUNET_NO == addremove)
303  {
304  if (NULL == al)
305  {
306  /* address to be removed not found!? */
307  GNUNET_break (0);
308  return;
309  }
310  al->rc--;
311  if (0 != al->rc)
312  return; /* RC not yet zero */
313  GNUNET_CONTAINER_DLL_remove (oal_head,
314  oal_tail,
315  al);
317  GNUNET_free (al);
318  refresh_hello ();
319  return;
320  }
321  if (NULL != al)
322  {
323  /* address added twice or more */
324  al->rc++;
325  return;
326  }
327  al = GNUNET_new (struct OwnAddressList);
328  al->rc = 1;
329  GNUNET_CONTAINER_DLL_insert (oal_head,
330  oal_tail,
331  al);
332  al->address = GNUNET_HELLO_address_copy (address);
333  refresh_hello ();
334 }
335 
336 
347 int
349  struct GNUNET_CRYPTO_EddsaSignature **sig,
350  struct GNUNET_TIME_Absolute **sig_expiration)
351 {
352  struct OwnAddressList *al;
353 
354  for (al = oal_head; al != NULL; al = al->next)
355  if (0 == GNUNET_HELLO_address_cmp (address,
356  al->address))
357  {
358  *sig = &al->pong_signature;
359  *sig_expiration = &al->pong_sig_expires;
360  return GNUNET_YES;
361  }
362  *sig = NULL;
363  *sig_expiration = NULL;
364  return GNUNET_NO;
365 }
366 
367 
368 /* end of file gnunet-service-transport_hello.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
static int friend_option
Should we use a friend-only HELLO?
struct OwnAddressList * next
This is a doubly-linked list.
A HELLO message is used to exchange information about transports with other peers.
static char * expiration
Credential TTL.
void(* GST_HelloCallback)(void *cls, const struct GNUNET_MessageHeader *hello)
Signature of a function to call whenever our hello changes.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
struct GNUNET_HELLO_Message * GNUNET_HELLO_create(const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, GNUNET_HELLO_GenerateAddressListCallback addrgen, void *addrgen_cls, int friend_only)
Construct a HELLO message given the public key, expiration time and an iterator that spews the transp...
Definition: hello.c:204
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GST_hello_start(int friend_only, GST_HelloCallback cb, void *cb_cls)
Initialize the HELLO module.
static void refresh_hello_task(void *cls)
Construct our HELLO message from all of the addresses of all of the transports.
static struct GNUNET_HELLO_Message * our_hello
Our HELLO message.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int ret
Final status code.
Definition: gnunet-arm.c:89
int GST_hello_test_address(const struct GNUNET_HELLO_Address *address, struct GNUNET_CRYPTO_EddsaSignature **sig, struct GNUNET_TIME_Absolute **sig_expiration)
Test if a particular address is one of ours.
static GST_HelloCallback hello_cb
Function to call on HELLO changes.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void refresh_hello()
Schedule task to refresh hello (but only if such a task exists already, as otherwise the module might...
int GNUNET_HELLO_address_cmp(const struct GNUNET_HELLO_Address *a1, const struct GNUNET_HELLO_Address *a2)
Compare two addresses.
Definition: address.c:130
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:1246
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
static struct OwnAddressList * oal_tail
Tail of my addresses.
struct GNUNET_TIME_Absolute pong_sig_expires
How long until the current signature expires? (ZERO if the signature was never created).
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1273
static void * hello_cb_cls
Closure for hello_cb.
static char buf[2048]
static ssize_t address_generator(void *cls, size_t max, void *buf)
Add an address from the struct OwnAddressList to the buffer.
struct OwnAddressList * addr_pos
Where are we in the DLL?
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
struct GNUNET_TIME_Absolute expiration
When do addresses expire?
Closure for address_generator().
struct GNUNET_MQ_Envelope * GNUNET_PEERINFO_add_peer(struct GNUNET_PEERINFO_Handle *h, const struct GNUNET_HELLO_Message *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Add a host to the persistent list.
Definition: peerinfo_api.c:557
size_t GNUNET_HELLO_add_address(const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration, char *target, size_t max)
Copy the given address information into the given buffer using the format of HELLOs.
Definition: hello.c:109
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define HELLO_REFRESH_PERIOD
How often do we refresh our HELLO (due to expiration concerns)?
static struct OwnAddressList * oal_head
Head of my addresses.
an ECC signature using EdDSA.
const struct GNUNET_MessageHeader * GST_hello_get()
Obtain this peers HELLO message.
struct GNUNET_CRYPTO_EddsaSignature pong_signature
Signature for a &#39;struct TransportPongMessage&#39; for this address.
struct GNUNET_PEERINFO_Handle * GST_peerinfo
Handle to peerinfo service.
static struct GNUNET_SCHEDULER_Task * hello_task
Identifier of refresh_hello_task().
struct GNUNET_HELLO_Address * address
The address.
An address for communicating with a peer.
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_copy(const struct GNUNET_HELLO_Address *address)
Copy an address struct.
Definition: address.c:109
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:649
Entry in linked list of network addresses for ourselves.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_TIME_Relative hello_expiration
Hello address expiration.
void GST_hello_modify_addresses(int addremove, const struct GNUNET_HELLO_Address *address)
Add or remove an address from this peer&#39;s HELLO message.
struct OwnAddressList * prev
This is a doubly-linked list.
#define GNUNET_HELLO_address_free(addr)
Free an address.
unsigned int rc
How often has this address been added/removed? Used as some plugins may learn the same external addre...
void GST_hello_stop()
Shutdown the HELLO module.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965