/*
This file is part of GNUnet.
- Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2010-2015 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ Affero General Public License for more details.
*/
/**
*/
#include "platform.h"
#include "gnunet-service-transport_ats.h"
-#include "gnunet-service-transport_blacklist.h"
-#include "gnunet-service-transport_clients.h"
#include "gnunet-service-transport_hello.h"
#include "gnunet-service-transport_neighbours.h"
#include "gnunet-service-transport_plugins.h"
#include "gnunet_peerinfo_service.h"
#include "gnunet_signatures.h"
+/**
+ * Current state of a validation process.
+ *
+ * FIXME: what state is used to indicate that a validation
+ * was successful? If that is clarified/determined, "UGH" in
+ * ~gnunetpeerinfogtk.c:1103 should be resolved.
+ */
+enum GNUNET_TRANSPORT_ValidationState
+{
+ /**
+ * Undefined state
+ *
+ * Used for final callback indicating operation done
+ */
+ GNUNET_TRANSPORT_VS_NONE,
+
+ /**
+ * Fresh validation entry
+ *
+ * Entry was just created, no validation process was executed
+ */
+ GNUNET_TRANSPORT_VS_NEW,
+
+ /**
+ * Updated validation entry
+ *
+ * This is an update for an existing validation entry
+ */
+ GNUNET_TRANSPORT_VS_UPDATE,
+
+ /**
+ * Timeout for validation entry
+ *
+ * A timeout occured during the validation process
+ */
+ GNUNET_TRANSPORT_VS_TIMEOUT,
+
+ /**
+ * Validation entry is removed
+ *
+ * The validation entry is getting removed due to a failed validation
+ */
+ GNUNET_TRANSPORT_VS_REMOVE
+};
+
+
+
/**
* How long is a PONG signature valid? We'll recycle a signature until
enum GNUNET_TRANSPORT_ValidationState state)
{
ve->state = state;
- GST_clients_broadcast_validation_notification (&ve->address->peer,
- ve->address,
- ve->send_time,
- ve->valid_until,
- ve->next_validation,
- state);
}
* longer valid and then possibly triggers its removal.
*
* @param cls the `struct ValidationEntry`
- * @param tc scheduler context (unused)
*/
static void
-timeout_hello_validation (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+timeout_hello_validation (void *cls)
{
struct ValidationEntry *ve = cls;
struct GNUNET_TIME_Absolute max;
transmit_ping_if_allowed (void *cls,
const struct GNUNET_PeerIdentity *pid,
const struct GNUNET_HELLO_Address *address_null,
- struct Session *session_null,
+ struct GNUNET_ATS_Session *session_null,
int result)
{
struct ValidationEntry *ve = cls;
size_t tsize;
size_t slen;
uint16_t hsize;
- struct Session *session;
+ struct GNUNET_ATS_Session *session;
ve->bc = NULL;
if (GNUNET_OK != result)
ping.challenge = htonl (ve->challenge);
ping.target = *pid;
- if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ if (tsize >= GNUNET_MAX_MESSAGE_SIZE)
{
GNUNET_break (0);
hsize = 0;
{
char message_buf[tsize] GNUNET_ALIGN;
- memcpy (message_buf,
+ GNUNET_memcpy (message_buf,
hello,
hsize);
- memcpy (&message_buf[hsize],
+ GNUNET_memcpy (&message_buf[hsize],
&ping,
sizeof (struct TransportPingMessage));
- memcpy (&message_buf[sizeof (struct TransportPingMessage) + hsize],
+ GNUNET_memcpy (&message_buf[sizeof (struct TransportPingMessage) + hsize],
ve->address->transport_name,
slen);
- memcpy (&message_buf[sizeof (struct TransportPingMessage) + slen + hsize],
+ GNUNET_memcpy (&message_buf[sizeof (struct TransportPingMessage) + slen + hsize],
ve->address->address,
ve->address->address_length);
papi = GST_plugins_find (ve->address->transport_name);
* Do address validation again to keep address valid.
*
* @param cls the `struct ValidationEntry`
- * @param tc scheduler context (unused)
*/
static void
-revalidate_address (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+revalidate_address (void *cls)
{
struct ValidationEntry *ve = cls;
struct GNUNET_TIME_Relative canonical_delay;
GNUNET_STATISTICS_update (GST_stats,
gettext_noop ("# address revalidations started"), 1,
GNUNET_NO);
+ if (NULL != ve->bc)
+ {
+ GST_blacklist_test_cancel (ve->bc);
+ ve->bc = NULL;
+ }
bc = GST_blacklist_test_allowed (&ve->address->peer,
- ve->address->transport_name,
+ ve->address->transport_name,
&transmit_ping_if_allowed,
- ve,
- NULL,
- NULL);
+ ve,
+ NULL,
+ NULL);
if (NULL != bc)
- ve->bc = bc; /* only set 'bc' if 'transmit_ping_if_allowed' was not already
- * called... */
+ {
+ /* If transmit_ping_if_allowed was already called it may have freed ve,
+ * so only set ve->bc if it has not been called.
+ */
+ ve->bc = bc;
+ }
}
{
/* Why do we try to add an ill-formed address? */
GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Address with %u bytes for plugin %s and peer %s is malformed\n",
+ (unsigned int) address->address_length,
+ address->transport_name,
+ GNUNET_i2s (&pid));
return GNUNET_OK;
}
validation_entry_changed (ve,
GNUNET_TRANSPORT_VS_UPDATE);
memset (&prop, 0, sizeof (prop));
- GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != ve->network);
prop.scope = ve->network;
prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2);
if (GNUNET_YES != ve->known_to_ats)
{
struct TransportPongMessage *pong = cls;
struct GNUNET_TRANSPORT_PluginFunctions *papi;
- struct Session *session;
+ struct GNUNET_ATS_Session *session;
papi = GST_plugins_find (address->transport_name);
if (NULL == papi)
GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
const struct GNUNET_MessageHeader *hdr,
const struct GNUNET_HELLO_Address *sender_address,
- struct Session *session)
+ struct GNUNET_ATS_Session *session)
{
const struct TransportPingMessage *ping;
struct TransportPongMessage *pong;
ssize_t ret;
struct GNUNET_HELLO_Address address;
+ if (0 ==
+ memcmp (&GST_my_identity,
+ sender,
+ sizeof (struct GNUNET_PeerIdentity)))
+ return GNUNET_OK; /* our own, ignore! */
if (ntohs (hdr->size) < sizeof (struct TransportPingMessage))
{
GNUNET_break_op (0);
sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
len_address + len_plugin);
pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
- memcpy (&pong->challenge, &ping->challenge, sizeof (ping->challenge));
+ GNUNET_memcpy (&pong->challenge, &ping->challenge, sizeof (ping->challenge));
pong->addrlen = htonl (len_address + len_plugin);
- memcpy (&pong[1], addr, len_plugin); /* Copy transport plugin */
+ GNUNET_memcpy (&pong[1], addr, len_plugin); /* Copy transport plugin */
if (len_address > 0)
{
GNUNET_assert (NULL != addrend);
- memcpy (&((char *) &pong[1])[len_plugin], addrend, len_address);
+ GNUNET_memcpy (&((char *) &pong[1])[len_plugin], addrend, len_address);
}
if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value_us <
PONG_SIGNATURE_LIFETIME.rel_value_us / 4)
if (NULL == papi)
{
/* This plugin is currently unvailable ... ignore */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "No plugin available for %s\n",
+ address->transport_name);
return;
}
ve = find_validation_entry (address);
GNUNET_i2s (&ve->address->peer));
ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve);
}
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Validation already running for address `%s' of %s\n",
+ GST_plugins_a2s (ve->address),
+ GNUNET_i2s (&ve->address->peer));
+ }
}
int sig_res;
int do_verify;
+ if (0 ==
+ memcmp (&GST_my_identity,
+ sender,
+ sizeof (struct GNUNET_PeerIdentity)))
+ return GNUNET_OK; /* our own, ignore! */
+
if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
{
GNUNET_break_op (0);
GNUNET_TRANSPORT_VS_UPDATE);
/* build HELLO to store in PEERINFO */
+ GNUNET_STATISTICS_update (GST_stats,
+ gettext_noop ("# HELLOs given to peerinfo"),
+ 1,
+ GNUNET_NO);
ve->copied = GNUNET_NO;
hello = GNUNET_HELLO_create (&ve->address->peer.public_key,
&add_valid_peer_address,
ve,
GNUNET_NO);
- GNUNET_PEERINFO_add_peer (GST_peerinfo,
- hello,
- NULL,
- NULL);
+ GNUNET_break (NULL !=
+ GNUNET_PEERINFO_add_peer (GST_peerinfo,
+ hello,
+ NULL,
+ NULL));
GNUNET_free (hello);
return GNUNET_OK;
}
sizeof (struct GNUNET_PeerIdentity)))
{
/* got our own HELLO, how boring */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Validation received our own HELLO (%s), ignoring\n",
+ GNUNET_i2s (&pid));
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
}
-/**
- * Closure for the validation_entries_iterate function.
- */
-struct ValidationIteratorContext
-{
- /**
- * Function to call on each validation entry
- */
- GST_ValidationChangedCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-};
-
-
-/**
- * Function called on each entry in the validation map.
- * Passes the information from the validation entry to
- * the callback given in the closure.
- *
- * @param cls the `struct ValidationIteratorContext`
- * @param key peer this is about
- * @param value the `struct ValidationEntry`
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-validation_entries_iterate (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct ValidationIteratorContext *ic = cls;
- struct ValidationEntry *ve = value;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Notifying about validation entry for peer `%s' address `%s' \n",
- GNUNET_i2s (&ve->address->peer),
- GST_plugins_a2s (ve->address));
- ic->cb (ic->cb_cls,
- ve->address,
- ve->send_time,
- ve->valid_until,
- ve->next_validation,
- ve->state);
- return GNUNET_OK;
-}
-
-
-/**
- * Iterate over all iteration entries
- *
- * @param cb function to call
- * @param cb_cls closure for @a cb
- */
-void
-GST_validation_iterate (GST_ValidationChangedCallback cb,
- void *cb_cls)
-{
- struct ValidationIteratorContext ic;
-
- if (NULL == validation_map)
- return; /* can happen during shutdown */
- ic.cb = cb;
- ic.cb_cls = cb_cls;
- GNUNET_CONTAINER_multipeermap_iterate (validation_map,
- &validation_entries_iterate,
- &ic);
-}
-
/* end of file gnunet-service-transport_validation.c */