/*
This file is part of GNUnet.
- Copyright (C) 2010,2011 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2010,2011 GNUnet e.V.
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
*/
struct GNUNET_CRYPTO_EddsaSignature pong_signature;
+ /**
+ * How often has this address been added/removed? Used as
+ * some plugins may learn the same external address from
+ * multiple origins.
+ */
+ unsigned int rc;
+
};
/**
* Identifier of #refresh_hello_task().
*/
-static struct GNUNET_SCHEDULER_Task * hello_task;
+static struct GNUNET_SCHEDULER_Task *hello_task;
/**
/**
- * Add an address from the 'OwnAddressList' to the buffer.
+ * Add an address from the `struct OwnAddressList` to the buffer.
*
* @param cls the `struct GeneratorContext`
* @param max maximum number of bytes left
if (NULL == gc->addr_pos)
return GNUNET_SYSERR; /* Done */
- ret = GNUNET_HELLO_add_address (gc->addr_pos->address, gc->expiration, buf,
- max);
+ ret = GNUNET_HELLO_add_address (gc->addr_pos->address,
+ gc->expiration,
+ buf,
+ max);
gc->addr_pos = gc->addr_pos->next;
return ret;
}
* all of the transports.
*
* @param cls unused
- * @param tc scheduler context
*/
static void
-refresh_hello_task (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+refresh_hello_task (void *cls)
{
struct GeneratorContext gc;
&address_generator,
&gc,
friend_option);
- GNUNET_assert (NULL != our_hello);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Refreshed my %s HELLO, new size is %d\n",
(GNUNET_YES == friend_option) ? "friend-only" : "public",
/**
- * Schedule task to refresh hello (unless such a
- * task exists already).
+ * Schedule task to refresh hello (but only if such a
+ * task exists already, as otherwise the module might
+ * have been shutdown).
*/
static void
refresh_hello ()
{
if (NULL != hello_task)
+ {
GNUNET_SCHEDULER_cancel (hello_task);
- hello_task = GNUNET_SCHEDULER_add_now (&refresh_hello_task,
- NULL);
+ hello_task = GNUNET_SCHEDULER_add_now (&refresh_hello_task,
+ NULL);
+ }
}
hello_cb = cb;
hello_cb_cls = cb_cls;
friend_option = friend_only;
- refresh_hello ();
+ refresh_hello_task (NULL);
}
const struct GNUNET_MessageHeader *
GST_hello_get ()
{
- return (struct GNUNET_MessageHeader *) our_hello;
+ return (const struct GNUNET_MessageHeader *) our_hello;
}
struct OwnAddressList *al;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- (addremove ==
- GNUNET_YES) ? "Adding `%s' to the set of our addresses\n" :
- "Removing `%s' from the set of our addresses\n",
+ (GNUNET_YES == addremove)
+ ? "Adding `%s' to the set of our addresses\n"
+ : "Removing `%s' from the set of our addresses\n",
GST_plugins_a2s (address));
- GNUNET_assert (address != NULL);
+ GNUNET_assert (NULL != address);
+ for (al = oal_head; al != NULL; al = al->next)
+ if (0 == GNUNET_HELLO_address_cmp (address, al->address))
+ break;
if (GNUNET_NO == addremove)
{
- for (al = oal_head; al != NULL; al = al->next)
- if (0 == GNUNET_HELLO_address_cmp (address, al->address))
- {
- GNUNET_CONTAINER_DLL_remove (oal_head, oal_tail, al);
- GNUNET_HELLO_address_free (al->address);
- GNUNET_free (al);
- refresh_hello ();
- return;
- }
- /* address to be removed not found!? */
- GNUNET_break (0);
+ if (NULL == al)
+ {
+ /* address to be removed not found!? */
+ GNUNET_break (0);
+ return;
+ }
+ al->rc--;
+ if (0 != al->rc)
+ return; /* RC not yet zero */
+ GNUNET_CONTAINER_DLL_remove (oal_head,
+ oal_tail,
+ al);
+ GNUNET_HELLO_address_free (al->address);
+ GNUNET_free (al);
+ refresh_hello ();
+ return;
+ }
+ if (NULL != al)
+ {
+ /* address added twice or more */
+ al->rc++;
return;
}
al = GNUNET_new (struct OwnAddressList);
- GNUNET_CONTAINER_DLL_insert (oal_head, oal_tail, al);
+ al->rc = 1;
+ GNUNET_CONTAINER_DLL_insert (oal_head,
+ oal_tail,
+ al);
al->address = GNUNET_HELLO_address_copy (address);
refresh_hello ();
}