/*
This file is part of GNUnet.
Copyright (C) 2009, 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 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.
*/
/**
* @file hello/hello.c
* @brief helper library for handling HELLOs
* @author Christian Grothoff
* @author Matthias Wachs
*/
#include "platform.h"
#include "gnunet_hello_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_util_lib.h"
#include "gnunet_transport_plugin.h"
GNUNET_NETWORK_STRUCT_BEGIN
/**
* A HELLO message is used to exchange information about
* transports with other peers. This struct is always
* followed by the actual network addresses which have
* the format:
*
* 1) transport-name (0-terminated)
* 2) address-length (uint16_t, network byte order; possibly
* unaligned!)
* 3) address expiration (`struct GNUNET_TIME_AbsoluteNBO`); possibly
* unaligned!)
* 4) address (address-length bytes; possibly unaligned!)
*/
struct GNUNET_HELLO_Message
{
/**
* Type will be #GNUNET_MESSAGE_TYPE_HELLO.
*/
struct GNUNET_MessageHeader header;
/**
* Use in F2F mode: Do not gossip this HELLO message
*/
uint32_t friend_only GNUNET_PACKED;
/**
* The public key of the peer.
*/
struct GNUNET_CRYPTO_EddsaPublicKey publicKey;
};
GNUNET_NETWORK_STRUCT_END
/**
* Context used for building our own URI.
*/
struct GNUNET_HELLO_ComposeUriContext
{
/**
* Final URI.
*/
char *uri;
/**
* Function for finding transport plugins by name.
*/
GNUNET_HELLO_TransportPluginsFind plugins_find;
};
/**
* Context for #add_address_to_hello().
*/
struct GNUNET_HELLO_ParseUriContext
{
/**
* Position in the URI with the next address to parse.
*/
const char *pos;
/**
* Set to #GNUNET_SYSERR to indicate parse errors.
*/
int ret;
/**
* Counter
*/
unsigned int counter_total;
/**
* Counter skipped addresses
*/
unsigned int counter_added;
/**
* Function for finding transport plugins by name.
*/
GNUNET_HELLO_TransportPluginsFind plugins_find;
};
/**
* Return HELLO type
*
* @param h HELLO Message to test
* @return #GNUNET_YES for friend-only or #GNUNET_NO otherwise
*/
int
GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h)
{
if (GNUNET_YES == ntohl(h->friend_only))
return GNUNET_YES;
return GNUNET_NO;
}
/**
* Copy the given address information into
* the given buffer using the format of HELLOs.
*
* @param address the address
* @param expiration expiration for the @a address
* @param target where to copy the @a address
* @param max maximum number of bytes to copy to target
* @return number of bytes copied, 0 if
* the target buffer was not big enough.
*/
size_t
GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address,
struct GNUNET_TIME_Absolute expiration,
char *target,
size_t max)
{
uint16_t alen;
size_t slen;
struct GNUNET_TIME_AbsoluteNBO exp;
slen = strlen (address->transport_name) + 1;
if (slen + sizeof (uint16_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
address->address_length > max)
return 0;
exp = GNUNET_TIME_absolute_hton (expiration);
alen = htons ((uint16_t) address->address_length);