/*
This file is part of GNUnet.
(C) 2010,2011 Christian Grothoff (and other contributing authors)
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 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.
*/
/**
* @file transport/gnunet-service-transport_validation.c
* @brief address validation subsystem
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet-service-transport_validation.h"
#include "gnunet-service-transport_plugins.h"
#include "gnunet-service-transport_hello.h"
#include "gnunet-service-transport_blacklist.h"
#include "gnunet-service-transport.h"
#include "gnunet_hello_lib.h"
#include "gnunet_ats_service.h"
#include "gnunet_peerinfo_service.h"
#include "gnunet_signatures.h"
/**
* How long is a PONG signature valid? We'll recycle a signature until
* 1/4 of this time is remaining. PONGs should expire so that if our
* external addresses change an adversary cannot replay them indefinitely.
* OTOH, we don't want to spend too much time generating PONG signatures,
* so they must have some lifetime to reduce our CPU usage.
*/
#define PONG_SIGNATURE_LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1)
/**
* After how long do we expire an address in a HELLO that we just
* validated? This value is also used for our own addresses when we
* create a HELLO.
*/
#define HELLO_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
/**
* How often do we allow PINGing an address that we have not yet
* validated? This also determines how long we track an address that
* we cannot validate (because after this time we can destroy the
* validation record).
*/
#define UNVALIDATED_PING_KEEPALIVE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
/**
* How often do we PING an address that we have successfully validated
* in the past but are not actively using? Should be (significantly)
* smaller than HELLO_ADDRESS_EXPIRATION.
*/
#define VALIDATED_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
/**
* How often do we PING an address that we are currently using?
*/
#define CONNECTED_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
/**
* How much delay is acceptable for sending the PING or PONG?
*/
#define ACCEPTABLE_PING_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
/**
* Size of the validation map hashmap.
*/
#define VALIDATION_MAP_SIZE 256
/**
* Priority to use for PINGs
*/
#define PING_PRIORITY 2
/**
* Priority to use for PONGs
*/
#define PONG_PRIORITY 4
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Message used to ask a peer to validate receipt (to check an address
* from a HELLO). Followed by the address we are trying to validate,
* or an empty address if we are just sending a PING to confirm that a
* connection which the receiver (of the PING) initiated is still valid.
*/
struct TransportPingMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PING
*/
struct GNUNET_MessageHeader header;
/**
* Challenge code (to ensure fresh reply).
*/
uint32_t challenge GNUNET_PACKED;
/**
* Who is the intended recipient?
*/
struct GNUNET_PeerIdentity target;
};
/**
* Message used to validate a HELLO. The challenge is included in the
* confirmation to make matching of replies to requests possible. The
* signature signs our public key, an expiration time and our address.<p>
*
* This message is followed by our transport address that the PING tried
* to confirm (if we liked it). The address can be empty (zero bytes)
* if the PING had not address either (and we received the request via
* a connection that we initiated).
*/
struct TransportPongMessage
{
/**
* Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PONG
*/
struct GNUNET_MessageHeader header;
/**
* Challenge code from PING (showing freshness). Not part of what
* is signed so that we can re-use signatures.
*/
uint32_t challenge GNUNET_PACKED;
/**
* Signature.
*/
struct GNUNET_CRYPTO_RsaSignature signature;
/**
* GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN to confirm that this is a
* plausible address for the signing peer.
*/
struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
/**
* When does this signature expire?
*/
struct GNUNET_TIME_AbsoluteNBO expiration;
/**
* Size of address appended to this message (part of what is
* being signed, hence not redundant).
*/
uint32_t addrlen GNUNET_PACKED;
};
GNUNET_NETWORK_STRUCT_END
/**
* Information about an address under validation
*/
struct ValidationEntry
{
/**
* The address.
*/
struct GNUNET_HELLO_Address *address;
/**
* Handle to the blacklist check (if we're currently in it).
*/
struc