GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-communicator-tcp.c File Reference

Transport plugin using TCP. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
#include "gnunet_peerstore_service.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_constants.h"
#include "gnunet_nt_lib.h"
#include "gnunet_nat_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_communication_service.h"
#include "gnunet_resolver_service.h"
Include dependency graph for gnunet-communicator-tcp.c:

Go to the source code of this file.

Data Structures

struct  TcpHandshakeSignature
 Signature we use to verify that the ephemeral key was really chosen by the specified sender. More...
 
struct  TcpHandshakeAckSignature
 Signature we use to verify that the ack from the receiver of the ephemeral key was really send by the specified sender. More...
 
struct  TCPConfirmation
 Encrypted continuation of TCP initial handshake. More...
 
struct  TCPConfirmationAck
 Ack for the encrypted continuation of TCP initial handshake. More...
 
struct  TCPBox
 TCP message box. More...
 
struct  TCPRekey
 TCP rekey message box. More...
 
struct  TcpRekeySignature
 Signature we use to verify that the ephemeral key was really chosen by the specified sender. More...
 
struct  TCPFinish
 TCP finish. More...
 
struct  ListenTask
 Struct to use as closure. More...
 
struct  Queue
 Handle for a queue. More...
 
struct  ProtoQueue
 Handle for an incoming connection where we do not yet have enough information to setup a full queue. More...
 
struct  PortOnlyIpv4Ipv6
 In case of port only configuration we like to bind to ipv4 and ipv6 addresses. More...
 
struct  Addresses
 DLL to store the addresses we like to register at NAT service. More...
 

Macros

#define ADDRESS_VALIDITY_PERIOD    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
 How long do we believe our addresses to remain up (before the other peer should revalidate). More...
 
#define DEFAULT_MAX_QUEUE_LENGTH   8
 How many messages do we keep at most in the queue to the transport service before we start to drop (default, can be changed via the configuration file). More...
 
#define BUF_SIZE   (2 * 64 * 1024 + sizeof(struct TCPBox))
 Size of our IO buffers for ciphertext data. More...
 
#define DEFAULT_REKEY_INTERVAL   GNUNET_TIME_UNIT_DAYS
 How often do we rekey based on time (at least) More...
 
#define PROTO_QUEUE_TIMEOUT   GNUNET_TIME_UNIT_MINUTES
 How long do we wait until we must have received the initial KX? More...
 
#define REKEY_MAX_BYTES   (1024LLU * 1024 * 1024 * 4LLU)
 How often do we rekey based on number of bytes transmitted? (additionally randomized). More...
 
#define INITIAL_KX_SIZE
 Size of the initial key exchange message sent first in both directions. More...
 
#define INITIAL_CORE_KX_SIZE
 Size of the initial core key exchange messages. More...
 
#define COMMUNICATOR_ADDRESS_PREFIX   "tcp"
 Address prefix used by the communicator. More...
 
#define COMMUNICATOR_CONFIG_SECTION   "communicator-tcp"
 Configuration section used by the communicator. More...
 

Functions

static void listen_cb (void *cls)
 We have been notified that our listen socket has something to read. More...
 
static void queue_destroy (struct Queue *queue)
 Functions with this signature are called whenever we need to close a queue due to a disconnect or failure to establish a connection. More...
 
static void calculate_hmac (struct GNUNET_HashCode *hmac_secret, const void *buf, size_t buf_size, struct GNUNET_ShortHashCode *smac)
 Compute mac over buf, and ratched the hmac_secret. More...
 
static void queue_finish (struct Queue *queue)
 Append a 'finish' message to the outgoing transmission. More...
 
static void reschedule_queue_timeout (struct Queue *queue)
 Increment queue timeout due to activity. More...
 
static void queue_read (void *cls)
 Queue read task. More...
 
static void core_read_finished_cb (void *cls, int success)
 Core tells us it is done processing a message that transport received on a queue with status success. More...
 
static void pass_plaintext_to_core (struct Queue *queue, const void *plaintext, size_t plaintext_len)
 We received plaintext_len bytes of plaintext on queue. More...
 
static void setup_cipher (const struct GNUNET_HashCode *dh, const struct GNUNET_PeerIdentity *pid, gcry_cipher_hd_t *cipher, struct GNUNET_HashCode *hmac_key)
 Setup cipher based on shared secret dh and decrypting peer pid. More...
 
static void rekey_monotime_store_cb (void *cls, int success)
 Callback called when peerstore store operation for rekey monotime value is finished. More...
 
static void rekey_monotime_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY where found. More...
 
static void setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct Queue *queue)
 Setup cipher of queue for decryption. More...
 
static void do_rekey (struct Queue *queue, const struct TCPRekey *rekey)
 Handle rekey message on queue. More...
 
static void handshake_ack_monotime_store_cb (void *cls, int success)
 Callback called when peerstore store operation for handshake ack monotime value is finished. More...
 
static void handshake_ack_monotime_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK where found. More...
 
static void send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct Queue *queue)
 Sending challenge with TcpConfirmationAck back to sender of ephemeral key. More...
 
static void setup_out_cipher (struct Queue *queue)
 Setup cipher for outgoing data stream based on target and our ephemeral private key. More...
 
static void inject_rekey (struct Queue *queue)
 Inject a struct TCPRekey message into the queue's plaintext buffer. More...
 
static void queue_write (void *cls)
 We have been notified that our socket is ready to write. More...
 
static size_t try_handle_plaintext (struct Queue *queue)
 Test if we have received a full message in plaintext. More...
 
static struct sockaddr * tcp_address_to_sockaddr_numeric_v6 (socklen_t *sock_len, struct sockaddr_in6 v6, unsigned int port)
 Convert a struct sockaddr_in6 to astruct sockaddr *`. More...
 
static struct sockaddr * tcp_address_to_sockaddr_numeric_v4 (socklen_t *sock_len, struct sockaddr_in v4, unsigned int port)
 Convert a struct sockaddr_in4 to astruct sockaddr *`. More...
 
static struct PortOnlyIpv4Ipv6tcp_address_to_sockaddr_port_only (const char *bindto, unsigned int *port)
 Convert TCP bind specification to a struct PortOnlyIpv4Ipv6 * More...
 
static char * extract_address (const char *bindto)
 This Method extracts the address part of the BINDTO string. More...
 
static unsigned int extract_port (const char *addr_and_port)
 This Method extracts the port part of the BINDTO string. More...
 
static struct sockaddr * tcp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
 Convert TCP bind specification to a struct sockaddr * More...
 
static void mq_send (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
 Signature of functions implementing the sending functionality of a message queue. More...
 
static void mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Signature of functions implementing the destruction of a message queue. More...
 
static void mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Implementation function that cancels the currently sent message. More...
 
static void mq_error (void *cls, enum GNUNET_MQ_Error error)
 Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue. More...
 
static void boot_queue (struct Queue *queue)
 Add the given queue to our internal data structure. More...
 
static void transmit_kx (struct Queue *queue, const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
 Generate and transmit our ephemeral key and the signature for the initial KX with the other peer. More...
 
static void start_initial_kx_out (struct Queue *queue)
 Initialize our key material for outgoing transmissions and inform the other peer about it. More...
 
static void handshake_monotime_store_cb (void *cls, int success)
 Callback called when peerstore store operation for handshake monotime is finished. More...
 
static void handshake_monotime_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE where found. More...
 
static int decrypt_and_check_tc (struct Queue *queue, struct TCPConfirmation *tc, char *ibuf)
 We have received the first bytes from the other side on a queue. More...
 
static void free_proto_queue (struct ProtoQueue *pq)
 Closes socket and frees memory associated with pq. More...
 
static void proto_read_kx (void *cls)
 Read from the socket of the proto queue until we have enough data to upgrade to full queue. More...
 
static void queue_read_kx (void *cls)
 Read from the socket of the queue until we have enough data to initialize the decryption logic and can switch to regular reading. More...
 
static int mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
 Function called by the transport service to initialize a message queue given address information about another peer. More...
 
static int get_lt_delete_it (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over all ListenTasks to clean up. More...
 
static int get_queue_delete_it (void *cls, const struct GNUNET_PeerIdentity *target, void *value)
 Iterator over all message queues to clean up. More...
 
static void do_shutdown (void *cls)
 Shutdown the UNIX communicator. More...
 
static void enc_notify_cb (void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
 Function called when the transport service has received an acknowledgement for this communicator (!) via a different return path. More...
 
static void nat_address_cb (void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
 Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of 'valid' addresses changes. More...
 
static void add_addr (struct sockaddr *in, socklen_t in_len)
 This method adds addresses to the DLL, that are later register at the NAT service. More...
 
static int init_socket (struct sockaddr *addr, socklen_t in_len)
 This method launch network interactions for each address we like to bind to. More...
 
static void nat_register ()
 This method reads from the DLL addrs_head to register them at the NAT service. More...
 
static void init_socket_resolv (void *cls, const struct sockaddr *addr, socklen_t in_len)
 This method is the callback called by the resolver API, and wraps method init_socket. More...
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Setup communicator and launch network interactions. More...
 
int main (int argc, char *const *argv)
 The main function for the UNIX communicator. More...
 

Variables

static unsigned long long max_queue_length
 Maximum queue length before we stop reading towards the transport service. More...
 
static struct GNUNET_STATISTICS_Handlestats
 For logging statistics. More...
 
static struct GNUNET_TRANSPORT_CommunicatorHandlech
 Our environment. More...
 
static struct GNUNET_CONTAINER_MultiPeerMapqueue_map
 Queues (map from peer identity to struct Queue) More...
 
static struct GNUNET_CONTAINER_MultiHashMaplt_map
 ListenTasks (map from socket to struct ListenTask) More...
 
static struct GNUNET_PeerIdentity my_identity
 Our public key. More...
 
static struct GNUNET_TIME_Relative rekey_interval
 The rekey interval. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration. More...
 
static struct GNUNET_NT_InterfaceScanneris
 Network scanner to determine network types. More...
 
static struct GNUNET_NAT_Handlenat
 Connection to NAT service. More...
 
static struct ProtoQueueproto_head
 Protoqueues DLL head. More...
 
static struct ProtoQueueproto_tail
 Protoqueues DLL tail. More...
 
struct GNUNET_RESOLVER_RequestHandleresolve_request_handle
 Handle for DNS lookup of bindto address. More...
 
struct Addressesaddrs_head
 Head of DLL with addresses we like to register at NAT servcie. More...
 
struct Addressesaddrs_tail
 Head of DLL with addresses we like to register at NAT servcie. More...
 
struct ListenTasklts_head
 Head of DLL with ListenTasks. More...
 
struct ListenTasklts_tail
 Head of DLL with ListenTask. More...
 
int addrs_lens
 Number of addresses in the DLL for register at NAT service. More...
 
size_t unverified_size
 Size of data received without KX challenge played back. More...
 
static struct GNUNET_PEERSTORE_Handlepeerstore
 Database for peer's HELLOs. More...
 
int shutdown_running = GNUNET_NO
 A flag indicating we are already doing a shutdown. More...
 
unsigned int bind_port
 The port the communicator should be assigned to. More...
 

Detailed Description

Transport plugin using TCP.

Author
Christian Grothoff

TODO:

Definition in file gnunet-communicator-tcp.c.

Macro Definition Documentation

◆ ADDRESS_VALIDITY_PERIOD

#define ADDRESS_VALIDITY_PERIOD    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)

How long do we believe our addresses to remain up (before the other peer should revalidate).

Definition at line 47 of file gnunet-communicator-tcp.c.

◆ DEFAULT_MAX_QUEUE_LENGTH

#define DEFAULT_MAX_QUEUE_LENGTH   8

How many messages do we keep at most in the queue to the transport service before we start to drop (default, can be changed via the configuration file).

Should be below the level of the communicator API, as otherwise we may read messages just to have them dropped by the communicator API.

Definition at line 58 of file gnunet-communicator-tcp.c.

◆ BUF_SIZE

#define BUF_SIZE   (2 * 64 * 1024 + sizeof(struct TCPBox))

Size of our IO buffers for ciphertext data.

Must be at least UINT_MAX + sizeof (struct TCPBox).

Definition at line 64 of file gnunet-communicator-tcp.c.

◆ DEFAULT_REKEY_INTERVAL

#define DEFAULT_REKEY_INTERVAL   GNUNET_TIME_UNIT_DAYS

How often do we rekey based on time (at least)

Definition at line 69 of file gnunet-communicator-tcp.c.

◆ PROTO_QUEUE_TIMEOUT

#define PROTO_QUEUE_TIMEOUT   GNUNET_TIME_UNIT_MINUTES

How long do we wait until we must have received the initial KX?

Definition at line 74 of file gnunet-communicator-tcp.c.

◆ REKEY_MAX_BYTES

#define REKEY_MAX_BYTES   (1024LLU * 1024 * 1024 * 4LLU)

How often do we rekey based on number of bytes transmitted? (additionally randomized).

Definition at line 80 of file gnunet-communicator-tcp.c.

◆ INITIAL_KX_SIZE

#define INITIAL_KX_SIZE
Value:
(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey) \
+ sizeof(struct TCPConfirmation))
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
Encrypted continuation of TCP initial handshake.

Size of the initial key exchange message sent first in both directions.

Definition at line 86 of file gnunet-communicator-tcp.c.

◆ INITIAL_CORE_KX_SIZE

#define INITIAL_CORE_KX_SIZE
Value:
(sizeof(struct EphemeralKeyMessage) \
+ sizeof(struct PingMessage) \
+ sizeof(struct PongMessage))
Message transmitted with the signed ephemeral key of a peer.
We're sending an (encrypted) PING to the other peer to check if it can decrypt.
Response to a PING.

Size of the initial core key exchange messages.

Definition at line 93 of file gnunet-communicator-tcp.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "tcp"

Address prefix used by the communicator.

Definition at line 101 of file gnunet-communicator-tcp.c.

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-tcp"

Configuration section used by the communicator.

Definition at line 106 of file gnunet-communicator-tcp.c.

Function Documentation

◆ listen_cb()

static void listen_cb ( void *  cls)
static

We have been notified that our listen socket has something to read.

Do the read and reschedule this function to be called again once more is available.

Parameters
clsNULL

Do the read and reschedule this function to be called again once more is available.

Parameters
clsListenTask with listening socket and task

Definition at line 2780 of file gnunet-communicator-tcp.c.

2781 {
2782  struct sockaddr_storage in;
2783  socklen_t addrlen;
2784  struct GNUNET_NETWORK_Handle *sock;
2785  struct ProtoQueue *pq;
2786  struct ListenTask *lt;
2787 
2789  "listen_cb\n");
2790 
2791  lt = cls;
2792 
2793  lt->listen_task = NULL;
2794  GNUNET_assert (NULL != lt->listen_sock);
2795  addrlen = sizeof(in);
2796  memset (&in, 0, sizeof(in));
2798  (struct sockaddr*) &in,
2799  &addrlen);
2800  if ((NULL == sock) && ((EMFILE == errno) || (ENFILE == errno)))
2801  return; /* system limit reached, wait until connection goes down */
2803  lt->listen_sock,
2804  &listen_cb,
2805  lt);
2806  if ((NULL == sock) && ((EAGAIN == errno) || (ENOBUFS == errno)))
2807  return;
2808  if (NULL == sock)
2809  {
2811  return;
2812  }
2813  pq = GNUNET_new (struct ProtoQueue);
2814  pq->address_len = addrlen;
2815  pq->address = GNUNET_memdup (&in, addrlen);
2817  pq->sock = sock;
2819  pq->sock,
2820  &proto_read_kx,
2821  pq);
2823 }
static void listen_cb(void *cls)
We have been notified that our listen socket has something to read.
static struct ProtoQueue * proto_tail
Protoqueues DLL tail.
static void proto_read_kx(void *cls)
Read from the socket of the proto queue until we have enough data to upgrade to full queue.
#define PROTO_QUEUE_TIMEOUT
How long do we wait until we must have received the initial KX?
static struct ProtoQueue * proto_head
Protoqueues DLL head.
#define GNUNET_log(kind,...)
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:392
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1502
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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:315
handle to a socket
Definition: network.c:53
Struct to use as closure.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.
struct GNUNET_SCHEDULER_Task * listen_task
ID of listen task.
Handle for an incoming connection where we do not yet have enough information to setup a full queue.
socklen_t address_len
Length of the address.
struct GNUNET_TIME_Absolute timeout
Timeout for this protoqueue.
struct GNUNET_NETWORK_Handle * sock
socket that we transmit all data with on this queue
struct sockaddr * address
Address of the other peer.
struct GNUNET_SCHEDULER_Task * read_task
ID of read task for this connection.

References ProtoQueue::address, ProtoQueue::address_len, GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_memdup, GNUNET_NETWORK_socket_accept(), GNUNET_new, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_REL, ListenTask::listen_sock, ListenTask::listen_task, proto_head, PROTO_QUEUE_TIMEOUT, proto_read_kx(), proto_tail, ProtoQueue::read_task, ProtoQueue::sock, and ProtoQueue::timeout.

Referenced by GNUNET_SET_listen(), GNUNET_SETI_listen(), GNUNET_SETU_listen(), init_socket(), and queue_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_destroy()

static void queue_destroy ( struct Queue queue)
static

Functions with this signature are called whenever we need to close a queue due to a disconnect or failure to establish a connection.

Parameters
queuequeue to close down

Definition at line 876 of file gnunet-communicator-tcp.c.

877 {
878  struct ListenTask *lt = NULL;
879  struct GNUNET_HashCode h_sock;
880  int sockfd;
881 
882  if (NULL != queue->listen_sock)
883  {
884  sockfd = GNUNET_NETWORK_get_fd (queue->listen_sock);
885  GNUNET_CRYPTO_hash (&sockfd,
886  sizeof(int),
887  &h_sock);
888 
890  }
891 
893  "Disconnecting queue for peer `%s'\n",
894  GNUNET_i2s (&queue->target));
895  if (NULL != queue->rekey_monotime_sc)
896  {
897  GNUNET_PEERSTORE_store_cancel (queue->rekey_monotime_sc);
898  queue->rekey_monotime_sc = NULL;
899  }
900  if (NULL != queue->handshake_monotime_sc)
901  {
902  GNUNET_PEERSTORE_store_cancel (queue->handshake_monotime_sc);
903  queue->handshake_monotime_sc = NULL;
904  }
905  if (NULL != queue->handshake_ack_monotime_sc)
906  {
907  GNUNET_PEERSTORE_store_cancel (queue->handshake_ack_monotime_sc);
908  queue->handshake_ack_monotime_sc = NULL;
909  }
910  if (NULL != queue->rekey_monotime_get)
911  {
912  GNUNET_PEERSTORE_iterate_cancel (queue->rekey_monotime_get);
913  queue->rekey_monotime_get = NULL;
914  }
915  if (NULL != queue->handshake_monotime_get)
916  {
917  GNUNET_PEERSTORE_iterate_cancel (queue->handshake_monotime_get);
918  queue->handshake_monotime_get = NULL;
919  }
920  if (NULL != queue->handshake_ack_monotime_get)
921  {
922  GNUNET_PEERSTORE_iterate_cancel (queue->handshake_ack_monotime_get);
923  queue->handshake_ack_monotime_get = NULL;
924  }
925  if (NULL != queue->qh)
926  {
928  queue->qh = NULL;
929  }
930  GNUNET_assert (
931  GNUNET_YES ==
934  "# queues active",
936  GNUNET_NO);
937  if (NULL != queue->read_task)
938  {
939  GNUNET_SCHEDULER_cancel (queue->read_task);
940  queue->read_task = NULL;
941  }
942  if (NULL != queue->write_task)
943  {
944  GNUNET_SCHEDULER_cancel (queue->write_task);
945  queue->write_task = NULL;
946  }
948  {
950  "closing socket failed\n");
951  }
952  gcry_cipher_close (queue->in_cipher);
953  gcry_cipher_close (queue->out_cipher);
954  GNUNET_free (queue->address);
955  if (0 != queue->backpressure)
956  queue->destroyed = GNUNET_YES;
957  else
958  GNUNET_free (queue);
959 
960  if (NULL == lt)
961  return;
962 
963  if ((! shutdown_running) && (NULL == lt->listen_task))
964  {
966  "add read net listen\n");
969  lt->listen_sock,
970  &listen_cb,
971  lt);
972  }
973  else
974  GNUNET_free (lt);
975 }
static struct GNUNET_CONTAINER_MultiPeerMap * queue_map
Queues (map from peer identity to struct Queue)
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
int shutdown_running
A flag indicating we are already doing a shutdown.
static struct GNUNET_CONTAINER_MultiHashMap * lt_map
ListenTasks (map from socket to struct ListenTask)
static void queue(const char *hostname)
Add hostname to the list of requests to be made.
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1023
void GNUNET_PEERSTORE_store_cancel(struct GNUNET_PEERSTORE_StoreContext *sc)
Cancel a store request.
void GNUNET_PEERSTORE_iterate_cancel(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_TRANSPORT_communicator_mq_del(struct GNUNET_TRANSPORT_QueueHandle *qh)
Notify transport service that an MQ became unavailable due to a disconnect or timeout.
A 512-bit hashcode.

References GNUNET_assert, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_close(), GNUNET_NO, GNUNET_PEERSTORE_iterate_cancel(), GNUNET_PEERSTORE_store_cancel(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_communicator_mq_del(), GNUNET_YES, listen_cb(), ListenTask::listen_sock, ListenTask::listen_task, lt_map, queue(), queue_map, shutdown_running, and stats.

Referenced by get_queue_delete_it(), queue_read_kx(), queue_write(), and try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_hmac()

static void calculate_hmac ( struct GNUNET_HashCode hmac_secret,
const void *  buf,
size_t  buf_size,
struct GNUNET_ShortHashCode smac 
)
static

Compute mac over buf, and ratched the hmac_secret.

Parameters
[in,out]hmac_secretsecret for HMAC calculation
bufbuffer to MAC
buf_sizenumber of bytes in buf
smac[out]where to write the HMAC

Definition at line 987 of file gnunet-communicator-tcp.c.

991 {
992  struct GNUNET_HashCode mac;
993 
994  GNUNET_CRYPTO_hmac_raw (hmac_secret,
995  sizeof(struct GNUNET_HashCode),
996  buf,
997  buf_size,
998  &mac);
999  /* truncate to `struct GNUNET_ShortHashCode` */
1000  memcpy (smac, &mac, sizeof(struct GNUNET_ShortHashCode));
1001  /* ratchet hmac key */
1002  GNUNET_CRYPTO_hash (hmac_secret,
1003  sizeof(struct GNUNET_HashCode),
1004  hmac_secret);
1005 }
static char buf[2048]
void GNUNET_CRYPTO_hmac_raw(const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac)
Calculate HMAC of a message (RFC 2104) TODO: Shouldn't this be the standard hmac function and the abo...
Definition: crypto_hash.c:299
A 256-bit hashcode.

References buf, GNUNET_CRYPTO_hash(), and GNUNET_CRYPTO_hmac_raw().

Referenced by inject_rekey(), mq_send(), queue_finish(), and try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_finish()

static void queue_finish ( struct Queue queue)
static

Append a 'finish' message to the outgoing transmission.

Once the finish has been transmitted, destroy the queue.

Parameters
queuequeue to shut down nicely

Definition at line 1015 of file gnunet-communicator-tcp.c.

1016 {
1017  struct TCPFinish fin;
1018 
1019  memset (&fin, 0, sizeof(fin));
1020  fin.header.size = htons (sizeof(fin));
1021  fin.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH);
1022  calculate_hmac (&queue->out_hmac, &fin, sizeof(fin), &fin.hmac);
1023  /* if there is any message left in pwrite_buf, we
1024  overwrite it (possibly dropping the last message
1025  from CORE hard here) */
1026  memcpy (queue->pwrite_buf, &fin, sizeof(fin));
1027  queue->pwrite_off = sizeof(fin);
1028  /* This flag will ensure that #queue_write() no longer
1029  notifies CORE about the possibility of sending
1030  more data, and that #queue_write() will call
1031  #queue_destroy() once the @c fin was fully written. */
1032  queue->finishing = GNUNET_YES;
1033 }
static void calculate_hmac(struct GNUNET_HashCode *hmac_secret, const void *buf, size_t buf_size, struct GNUNET_ShortHashCode *smac)
Compute mac over buf, and ratched the hmac_secret.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH
TCP communicator end of stream.

References calculate_hmac(), GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH, GNUNET_YES, TCPFinish::header, TCPFinish::hmac, queue(), GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by do_rekey(), handshake_ack_monotime_cb(), handshake_monotime_cb(), mq_destroy(), mq_error(), queue_read(), rekey_monotime_cb(), and try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reschedule_queue_timeout()

static void reschedule_queue_timeout ( struct Queue queue)
static

Increment queue timeout due to activity.

We do not immediately notify the monitor here as that might generate excessive signalling.

Parameters
queuequeue for which the timeout should be rescheduled

Definition at line 1044 of file gnunet-communicator-tcp.c.

1045 {
1046  queue->timeout =
1048 }
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don't receive messages from the peer?

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_TIME_relative_to_absolute(), and queue().

Referenced by core_read_finished_cb(), queue_read(), queue_read_kx(), and queue_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_read()

static void queue_read ( void *  cls)
static

Queue read task.

If we hit the timeout, disconnect it

Parameters
clsthe struct Queue * to disconnect

Definition at line 1900 of file gnunet-communicator-tcp.c.

1901 {
1902  struct Queue *queue = cls;
1903  struct GNUNET_TIME_Relative left;
1904  ssize_t rcvd;
1905 
1906  queue->read_task = NULL;
1907  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
1908  &queue->cread_buf[queue->cread_off],
1909  BUF_SIZE - queue->cread_off);
1911  "Received %lu bytes from TCP queue\n", rcvd);
1913  "transport",
1914  "Received %lu bytes from TCP queue\n", rcvd);
1915  if (-1 == rcvd)
1916  {
1917  if ((EAGAIN != errno) && (EINTR != errno))
1918  {
1920  queue_finish (queue);
1921  return;
1922  }
1923  /* try again */
1924  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1925  queue->read_task =
1927  return;
1928  }
1929  if (0 != rcvd)
1931  queue->cread_off += rcvd;
1932  while ((queue->pread_off < sizeof(queue->pread_buf)) &&
1933  (queue->cread_off > 0))
1934  {
1935  size_t max = GNUNET_MIN (sizeof(queue->pread_buf) - queue->pread_off,
1936  queue->cread_off);
1937  size_t done;
1938  size_t total;
1939  size_t old_pread_off = queue->pread_off;
1940 
1941  GNUNET_assert (0 ==
1942  gcry_cipher_decrypt (queue->in_cipher,
1943  &queue->pread_buf[queue->pread_off],
1944  max,
1945  queue->cread_buf,
1946  max));
1947  queue->pread_off += max;
1948  total = 0;
1949  while (0 != (done = try_handle_plaintext (queue)))
1950  {
1951  /* 'done' bytes of plaintext were used, shift buffer */
1952  GNUNET_assert (done <= queue->pread_off);
1953  /* NOTE: this memmove() could possibly sometimes be
1954  avoided if we pass 'total' into try_handle_plaintext()
1955  and use it at an offset into the buffer there! */
1956  memmove (queue->pread_buf,
1957  &queue->pread_buf[done],
1958  queue->pread_off - done);
1959  queue->pread_off -= done;
1960  total += done;
1961  /* The last plaintext was a rekey, abort for now */
1962  if (GNUNET_YES == queue->rekeyed)
1963  break;
1964  }
1965  /* when we encounter a rekey message, the decryption above uses the
1966  wrong key for everything after the rekey; in that case, we have
1967  to re-do the decryption at 'total' instead of at 'max'.
1968  However, we have to take into account that the plaintext buffer may have
1969  already contained data and not jumped too far ahead in the ciphertext.
1970  If there is no rekey and the last message is incomplete (max > total),
1971  it is safe to keep the decryption so we shift by 'max' */
1972  if (GNUNET_YES == queue->rekeyed)
1973  {
1974  max = total - old_pread_off;
1975  queue->rekeyed = GNUNET_NO;
1976  queue->pread_off = 0;
1977  }
1978  memmove (queue->cread_buf, &queue->cread_buf[max], queue->cread_off - max);
1979  queue->cread_off -= max;
1980  }
1981  if (BUF_SIZE == queue->cread_off)
1982  return; /* buffer full, suspend reading */
1983  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1984  if (0 != left.rel_value_us)
1985  {
1986  if (max_queue_length > queue->backpressure)
1987  {
1988  /* continue reading */
1989  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
1990  queue->read_task =
1992  }
1993  return;
1994  }
1996  "Queue %p was idle for %s, disconnecting\n",
1997  queue,
2000  GNUNET_YES));
2001  queue_finish (queue);
2002 }
static void done()
static void queue_finish(struct Queue *queue)
Append a 'finish' message to the outgoing transmission.
static size_t try_handle_plaintext(struct Queue *queue)
Test if we have received a full message in plaintext.
#define BUF_SIZE
Size of our IO buffers for ciphertext data.
static void reschedule_queue_timeout(struct Queue *queue)
Increment queue timeout due to activity.
static unsigned long long max_queue_length
Maximum queue length before we stop reading towards the transport service.
static void queue_read(void *cls)
Queue read task.
#define GNUNET_MIN(a, b)
void GNUNET_log_from_nocheck(enum GNUNET_ErrorType kind, const char *comp, const char *message,...) __attribute__((format(printf
Log function that specifies an alternative component.
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition: network.c:731
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:404
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
#define max(x, y)
Time for relative time used by GNUnet, in microseconds.
Handle for a queue.

References BUF_SIZE, done(), GNUNET_assert, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_log_from_nocheck(), GNUNET_log_strerror, GNUNET_MIN, GNUNET_NETWORK_socket_recv(), GNUNET_NO, GNUNET_SCHEDULER_add_read_net(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, max, max_queue_length, queue(), queue_finish(), GNUNET_TIME_Relative::rel_value_us, reschedule_queue_timeout(), and try_handle_plaintext().

Referenced by core_read_finished_cb(), proto_read_kx(), and queue_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ core_read_finished_cb()

static void core_read_finished_cb ( void *  cls,
int  success 
)
static

Core tells us it is done processing a message that transport received on a queue with status success.

Parameters
clsa struct Queue * where the message originally came from
successGNUNET_OK on success

Definition at line 1068 of file gnunet-communicator-tcp.c.

1069 {
1070  struct Queue *queue = cls;
1071  if (GNUNET_OK != success)
1073  "# messages lost in communicator API towards CORE",
1074  1,
1075  GNUNET_NO);
1076  if (NULL == queue)
1077  return;
1078 
1080  "backpressure %u\n",
1081  queue->backpressure);
1082 
1083  queue->backpressure--;
1084  /* handle deferred queue destruction */
1085  if ((queue->destroyed) && (0 == queue->backpressure))
1086  {
1087  GNUNET_free (queue);
1088  return;
1089  }
1090  else if (GNUNET_YES != queue->destroyed)
1091  {
1093  /* possibly unchoke reading, now that CORE made progress */
1094  if (NULL == queue->read_task)
1095  queue->read_task =
1097  queue->timeout),
1098  queue->sock,
1099  &queue_read,
1100  queue);
1101  }
1102 }
@ GNUNET_OK
Definition: gnunet_common.h:95
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, queue(), queue_read(), reschedule_queue_timeout(), and stats.

Referenced by pass_plaintext_to_core().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ pass_plaintext_to_core()

static void pass_plaintext_to_core ( struct Queue queue,
const void *  plaintext,
size_t  plaintext_len 
)
static

We received plaintext_len bytes of plaintext on queue.

Pass it on to CORE. If transmission is actually happening, increase backpressure counter.

Parameters
queuethe queue that received the plaintext
plaintextthe plaintext that was received
plaintext_lennumber of bytes of plaintext received

Definition at line 1115 of file gnunet-communicator-tcp.c.

1118 {
1119  const struct GNUNET_MessageHeader *hdr = plaintext;
1120  int ret;
1121 
1123  "pass message from %s to core\n",
1124  GNUNET_i2s (&queue->target));
1125 
1126  if (ntohs (hdr->size) != plaintext_len)
1127  {
1128  /* NOTE: If we ever allow multiple CORE messages in one
1129  BOX, this will have to change! */
1130  GNUNET_break (0);
1131  return;
1132  }
1134  &queue->target,
1135  hdr,
1138  queue);
1140  "passed to core\n");
1141  if (GNUNET_OK == ret)
1142  queue->backpressure++;
1143  GNUNET_break (GNUNET_NO != ret); /* backpressure not working!? */
1144  if (GNUNET_SYSERR == ret)
1146  "# bytes lost due to CORE not running",
1147  plaintext_len,
1148  GNUNET_NO);
1149 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
static void core_read_finished_cb(void *cls, int success)
Core tells us it is done processing a message that transport received on a queue with status success.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
int GNUNET_TRANSPORT_communicator_receive(struct GNUNET_TRANSPORT_CommunicatorHandle *handle, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, struct GNUNET_TIME_Relative expected_addr_validity, GNUNET_TRANSPORT_MessageCompletedCallback cb, void *cb_cls)
Notify transport service that the communicator has received a message.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.

References ADDRESS_VALIDITY_PERIOD, ch, core_read_finished_cb(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TRANSPORT_communicator_receive(), queue(), ret, GNUNET_MessageHeader::size, and stats.

Referenced by try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_cipher()

static void setup_cipher ( const struct GNUNET_HashCode dh,
const struct GNUNET_PeerIdentity pid,
gcry_cipher_hd_t *  cipher,
struct GNUNET_HashCode hmac_key 
)
static

Setup cipher based on shared secret dh and decrypting peer pid.

Parameters
dhshared secret
piddecrypting peer's identity
cipher[out]cipher to initialize
hmac_key[out]HMAC key to initialize

Definition at line 1162 of file gnunet-communicator-tcp.c.

1166 {
1167  char key[256 / 8];
1168  char ctr[128 / 8];
1169 
1170  GNUNET_assert (0 == gcry_cipher_open (cipher,
1171  GCRY_CIPHER_AES256 /* low level: go for speed */,
1172  GCRY_CIPHER_MODE_CTR,
1173  0 /* flags */));
1175  sizeof(key),
1176  "TCP-key",
1177  strlen ("TCP-key"),
1178  dh,
1179  sizeof(*dh),
1180  pid,
1181  sizeof(*pid),
1182  NULL,
1183  0));
1184  GNUNET_assert (0 == gcry_cipher_setkey (*cipher, key, sizeof(key)));
1186  sizeof(ctr),
1187  "TCP-ctr",
1188  strlen ("TCP-ctr"),
1189  dh,
1190  sizeof(*dh),
1191  pid,
1192  sizeof(*pid),
1193  NULL,
1194  0));
1195  gcry_cipher_setctr (*cipher, ctr, sizeof(ctr));
1197  GNUNET_CRYPTO_kdf (hmac_key,
1198  sizeof(struct GNUNET_HashCode),
1199  "TCP-hmac",
1200  strlen ("TCP-hmac"),
1201  dh,
1202  sizeof(*dh),
1203  pid,
1204  sizeof(*pid),
1205  NULL,
1206  0));
1207 }
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:69

References GNUNET_assert, GNUNET_CRYPTO_kdf(), GNUNET_YES, key, and pid.

Referenced by setup_in_cipher(), and setup_out_cipher().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rekey_monotime_store_cb()

static void rekey_monotime_store_cb ( void *  cls,
int  success 
)
static

Callback called when peerstore store operation for rekey monotime value is finished.

Parameters
clsQueue context the store operation was executed.
successStore operation was successful (GNUNET_OK) or not.

Definition at line 1216 of file gnunet-communicator-tcp.c.

1217 {
1218  struct Queue *queue = cls;
1219  if (GNUNET_OK != success)
1220  {
1222  "Failed to store rekey monotonic time in PEERSTORE!\n");
1223  }
1224  queue->rekey_monotime_sc = NULL;
1225 }

References GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, and queue().

Referenced by rekey_monotime_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rekey_monotime_cb()

static void rekey_monotime_cb ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY where found.

Parameters
clsQueue context the store operation was executed.
recordThe record found or NULL if there is no record left.
emsgMessage from peerstore.

Definition at line 1236 of file gnunet-communicator-tcp.c.

1239 {
1240  struct Queue *queue = cls;
1241  struct GNUNET_TIME_AbsoluteNBO *mtbe;
1242  struct GNUNET_TIME_Absolute mt;
1243  const struct GNUNET_PeerIdentity *pid;
1244  struct GNUNET_TIME_AbsoluteNBO *rekey_monotonic_time;
1245 
1246  (void) emsg;
1247 
1248  rekey_monotonic_time = &queue->rekey_monotonic_time;
1249  pid = &queue->target;
1250  if (NULL == record)
1251  {
1252  queue->rekey_monotime_get = NULL;
1253  return;
1254  }
1255  if (sizeof(*mtbe) != record->value_size)
1256  {
1257  GNUNET_break (0);
1258  return;
1259  }
1260  mtbe = record->value;
1261  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1262  if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1263  queue->rekey_monotonic_time).abs_value_us)
1264  {
1266  "Queue from %s dropped, rekey monotime in the past\n",
1267  GNUNET_i2s (&queue->target));
1268  GNUNET_break (0);
1269  queue_finish (queue);
1270  return;
1271  }
1272  queue->rekey_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
1273  "transport_tcp_communicator",
1274  pid,
1276  rekey_monotonic_time,
1277  sizeof(*
1278  rekey_monotonic_time),
1282  queue);
1283 }
static struct GNUNET_PEERSTORE_Handle * peerstore
Database for peer's HELLOs.
static void rekey_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for rekey monotime value is finished.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_PEERSTORE_StoreContext * GNUNET_PEERSTORE_store(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a new entry in the PEERSTORE.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY
Key used to store sender's monotonic time from rekey message.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:736
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
The identity of the host (wraps the signing key of the peer).
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, GNUNET_PEERSTORE_store(), GNUNET_PEERSTORE_STOREOPTION_REPLACE, GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY, GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_UNIT_FOREVER_ABS, peerstore, pid, queue(), queue_finish(), record(), and rekey_monotime_store_cb().

Referenced by do_rekey().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_in_cipher()

static void setup_in_cipher ( const struct GNUNET_CRYPTO_EcdhePublicKey ephemeral,
struct Queue queue 
)
static

Setup cipher of queue for decryption.

Parameters
ephemeralephemeral key we received from the other peer
queue[in,out]queue to initialize decryption cipher for

Definition at line 1293 of file gnunet-communicator-tcp.c.

1295 {
1296  struct GNUNET_HashCode dh;
1297 
1298  GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh);
1299  setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac);
1300 }
static struct GNUNET_PeerIdentity my_identity
Our public key.
static void setup_cipher(const struct GNUNET_HashCode *dh, const struct GNUNET_PeerIdentity *pid, gcry_cipher_hd_t *cipher, struct GNUNET_HashCode *hmac_key)
Setup cipher based on shared secret dh and decrypting peer pid.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition: crypto_ecc.c:718

References GNUNET_CRYPTO_eddsa_ecdh(), my_identity, my_private_key, queue(), and setup_cipher().

Referenced by do_rekey(), proto_read_kx(), and queue_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_rekey()

static void do_rekey ( struct Queue queue,
const struct TCPRekey rekey 
)
static

Handle rekey message on queue.

The message was already HMAC'ed, but we should additionally still check the signature. Then we need to stop the old cipher and start afresh.

Parameters
queuethe queue rekey was received on
rekeythe rekey message

Definition at line 1312 of file gnunet-communicator-tcp.c.

1313 {
1314  struct TcpRekeySignature thp;
1315 
1317  thp.purpose.size = htonl (sizeof(thp));
1319  "do_rekey size %u\n",
1320  thp.purpose.size);
1321  thp.sender = queue->target;
1323  "sender %s\n",
1324  GNUNET_p2s (&thp.sender.public_key));
1326  "sender %s\n",
1327  GNUNET_p2s (&queue->target.public_key));
1328  thp.receiver = my_identity;
1330  "receiver %s\n",
1331  GNUNET_p2s (&thp.receiver.public_key));
1332  thp.ephemeral = rekey->ephemeral;
1334  "ephemeral %s\n",
1335  GNUNET_e2s (&thp.ephemeral));
1336  thp.monotonic_time = rekey->monotonic_time;
1338  "time %s\n",
1340  GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1341  GNUNET_assert (ntohl ((&thp)->purpose.size) == sizeof (*(&thp)));
1342  if (GNUNET_OK !=
1344  &thp,
1345  &rekey->sender_sig,
1346  &queue->target.public_key))
1347  {
1348  GNUNET_break (0);
1349  queue_finish (queue);
1350  return;
1351  }
1352  queue->rekey_monotonic_time = rekey->monotonic_time;
1353  queue->rekey_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1354  "transport_tcp_communicator",
1355  &queue->target,
1358  queue);
1359  gcry_cipher_close (queue->in_cipher);
1360  queue->rekeyed = GNUNET_YES;
1361  setup_in_cipher (&rekey->ephemeral, queue);
1362 }
static void rekey_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY where...
static void setup_in_cipher(const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, struct Queue *queue)
Setup cipher of queue for decryption.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY
Signature used by TCP communicator rekey.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
const char * GNUNET_e2s(const struct GNUNET_CRYPTO_EcdhePublicKey *p)
Convert a public key value to a string (for printing debug messages).
const char * GNUNET_p2s(const struct GNUNET_CRYPTO_EddsaPublicKey *p)
Convert a public key value to a string (for printing debug messages).
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iterate(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over records matching supplied key information.
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
struct GNUNET_TIME_AbsoluteNBO monotonic_time
Monotonic time of sender, to possibly help detect replay attacks (if receiver persists times by sende...
struct GNUNET_CRYPTO_EcdhePublicKey ephemeral
New ephemeral key.
struct GNUNET_CRYPTO_EddsaSignature sender_sig
Sender's signature of type GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.
Signature we use to verify that the ephemeral key was really chosen by the specified sender.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY.

References TCPRekey::ephemeral, TcpRekeySignature::ephemeral, GNUNET_assert, GNUNET_break, GNUNET_CRYPTO_eddsa_verify, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, GNUNET_p2s(), GNUNET_PEERSTORE_iterate(), GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_REKEY, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, TcpRekeySignature::monotonic_time, TCPRekey::monotonic_time, my_identity, peerstore, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TcpRekeySignature::purpose, queue(), queue_finish(), TcpRekeySignature::receiver, rekey_monotime_cb(), TcpRekeySignature::sender, TCPRekey::sender_sig, setup_in_cipher(), and GNUNET_CRYPTO_EccSignaturePurpose::size.

Referenced by try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handshake_ack_monotime_store_cb()

static void handshake_ack_monotime_store_cb ( void *  cls,
int  success 
)
static

Callback called when peerstore store operation for handshake ack monotime value is finished.

Parameters
clsQueue context the store operation was executed.
successStore operation was successful (GNUNET_OK) or not.

Definition at line 1371 of file gnunet-communicator-tcp.c.

1372 {
1373  struct Queue *queue = cls;
1374 
1375  if (GNUNET_OK != success)
1376  {
1378  "Failed to store handshake ack monotonic time in PEERSTORE!\n");
1379  }
1380  queue->handshake_ack_monotime_sc = NULL;
1381 }

References GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, and queue().

Referenced by handshake_ack_monotime_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handshake_ack_monotime_cb()

static void handshake_ack_monotime_cb ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK where found.

Parameters
clsQueue context the store operation was executed.
recordThe record found or NULL if there is no record left.
emsgMessage from peerstore.

Definition at line 1392 of file gnunet-communicator-tcp.c.

1395 {
1396  struct Queue *queue = cls;
1397  struct GNUNET_TIME_AbsoluteNBO *mtbe;
1398  struct GNUNET_TIME_Absolute mt;
1399  const struct GNUNET_PeerIdentity *pid;
1400  struct GNUNET_TIME_AbsoluteNBO *handshake_ack_monotonic_time;
1401 
1402  (void) emsg;
1403 
1404  handshake_ack_monotonic_time = &queue->handshake_ack_monotonic_time;
1405  pid = &queue->target;
1406  if (NULL == record)
1407  {
1408  queue->handshake_ack_monotime_get = NULL;
1409  return;
1410  }
1411  if (sizeof(*mtbe) != record->value_size)
1412  {
1413  GNUNET_break (0);
1414  return;
1415  }
1416  mtbe = record->value;
1417  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
1418  if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
1419  queue->handshake_ack_monotonic_time).abs_value_us)
1420  {
1422  "Queue from %s dropped, handshake ack monotime in the past\n",
1423  GNUNET_i2s (&queue->target));
1424  GNUNET_break (0);
1425  queue_finish (queue);
1426  return;
1427  }
1428  queue->handshake_ack_monotime_sc =
1430  "transport_tcp_communicator",
1431  pid,
1433  handshake_ack_monotonic_time,
1434  sizeof(*handshake_ack_monotonic_time),
1437  &
1439  queue);
1440 }
static void handshake_ack_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake ack monotime value is finished.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK
Key used to store sender's monotonic time from handshake ack message.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, GNUNET_PEERSTORE_store(), GNUNET_PEERSTORE_STOREOPTION_REPLACE, GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK, GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_UNIT_FOREVER_ABS, handshake_ack_monotime_store_cb(), peerstore, pid, queue(), queue_finish(), and record().

Referenced by try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_challenge()

static void send_challenge ( struct GNUNET_CRYPTO_ChallengeNonceP  challenge,
struct Queue queue 
)
static

Sending challenge with TcpConfirmationAck back to sender of ephemeral key.

Parameters
tcThe TCPConfirmation originally send.
queueThe queue context.

Definition at line 1450 of file gnunet-communicator-tcp.c.

1451 {
1452  struct TCPConfirmationAck tca;
1453  struct TcpHandshakeAckSignature thas;
1454 
1456  "transport",
1457  "sending challenge\n");
1458 
1459  tca.header.type = ntohs (
1461  tca.header.size = ntohs (sizeof(tca));
1462  tca.challenge = challenge;
1463  tca.sender = my_identity;
1464  tca.monotonic_time =
1466  thas.purpose.purpose = htonl (
1468  thas.purpose.size = htonl (sizeof(thas));
1469  thas.sender = my_identity;
1470  thas.receiver = queue->target;
1471  thas.monotonic_time = tca.monotonic_time;
1472  thas.challenge = tca.challenge;
1474  &thas,
1475  &tca.sender_sig);
1476  GNUNET_assert (0 ==
1477  gcry_cipher_encrypt (queue->out_cipher,
1478  &queue->cwrite_buf[queue->cwrite_off],
1479  sizeof(tca),
1480  &tca,
1481  sizeof(tca)));
1482  queue->cwrite_off += sizeof(tca);
1484  "transport",
1485  "sending challenge done\n");
1486 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK
Signature by a peer sending back the nonce received at initial handshake.
#define GNUNET_CRYPTO_eddsa_sign(priv, ps, sig)
EdDSA sign a given block.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK
TCP communicator confirmation ack.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_monotonic(const struct GNUNET_CONFIGURATION_Handle *cfg)
Obtain the current time and make sure it is monotonically increasing.
Definition: time.c:859
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
Ack for the encrypted continuation of TCP initial handshake.
Signature we use to verify that the ack from the receiver of the ephemeral key was really send by the...
struct GNUNET_CRYPTO_ChallengeNonceP challenge
Challenge value used to protect against replay attack, if there is no stored monotonic time value.

References cfg, TcpHandshakeAckSignature::challenge, TCPConfirmationAck::challenge, GNUNET_assert, GNUNET_CRYPTO_eddsa_sign, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log_from_nocheck(), GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK, GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), TCPConfirmationAck::header, TCPConfirmationAck::monotonic_time, TcpHandshakeAckSignature::monotonic_time, my_identity, my_private_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TcpHandshakeAckSignature::purpose, queue(), TcpHandshakeAckSignature::receiver, TCPConfirmationAck::sender, TcpHandshakeAckSignature::sender, TCPConfirmationAck::sender_sig, GNUNET_MessageHeader::size, GNUNET_CRYPTO_EccSignaturePurpose::size, and GNUNET_MessageHeader::type.

Referenced by queue_read_kx(), and try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_out_cipher()

static void setup_out_cipher ( struct Queue queue)
static

Setup cipher for outgoing data stream based on target and our ephemeral private key.

Parameters
queuequeue to setup outgoing (encryption) cipher for

Definition at line 1496 of file gnunet-communicator-tcp.c.

1497 {
1498  struct GNUNET_HashCode dh;
1499 
1500  GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1501  /* we don't need the private key anymore, drop it! */
1502  memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1503  setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1505  queue->rekey_left_bytes =
1507 }
static struct GNUNET_TIME_Relative rekey_interval
The rekey interval.
#define REKEY_MAX_BYTES
How often do we rekey based on number of bytes transmitted? (additionally randomized).
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Random on unsigned 64-bit values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition: crypto_ecc.c:758
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).

References GNUNET_CRYPTO_ecdh_eddsa(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), GNUNET_TIME_relative_to_absolute(), queue(), rekey_interval, REKEY_MAX_BYTES, and setup_cipher().

Referenced by inject_rekey(), and start_initial_kx_out().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ inject_rekey()

static void inject_rekey ( struct Queue queue)
static

Inject a struct TCPRekey message into the queue's plaintext buffer.

Parameters
queuequeue to perform rekeying on

Definition at line 1517 of file gnunet-communicator-tcp.c.

1518 {
1519  struct TCPRekey rekey;
1520  struct TcpRekeySignature thp;
1521 
1522  GNUNET_assert (0 == queue->pwrite_off);
1523  memset (&rekey, 0, sizeof(rekey));
1524  GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
1525  rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1526  rekey.header.size = ntohs (sizeof(rekey));
1527  GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral);
1528  rekey.monotonic_time =
1530  thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
1531  thp.purpose.size = htonl (sizeof(thp));
1533  "inject_rekey size %u\n",
1534  thp.purpose.size);
1535  thp.sender = my_identity;
1537  "sender %s\n",
1538  GNUNET_p2s (&thp.sender.public_key));
1539  thp.receiver = queue->target;
1541  "receiver %s\n",
1542  GNUNET_p2s (&thp.receiver.public_key));
1543  thp.ephemeral = rekey.ephemeral;
1545  "ephemeral %s\n",
1546  GNUNET_e2s (&thp.ephemeral));
1547  thp.monotonic_time = rekey.monotonic_time;
1549  "time %s\n",
1551  GNUNET_TIME_absolute_ntoh (thp.monotonic_time)));
1553  &thp,
1554  &rekey.sender_sig);
1555  calculate_hmac (&queue->out_hmac, &rekey, sizeof(rekey), &rekey.hmac);
1556  /* Encrypt rekey message with 'old' cipher */
1557  GNUNET_assert (0 ==
1558  gcry_cipher_encrypt (queue->out_cipher,
1559  &queue->cwrite_buf[queue->cwrite_off],
1560  sizeof(rekey),
1561  &rekey,
1562  sizeof(rekey)));
1563  queue->cwrite_off += sizeof(rekey);
1564  /* Setup new cipher for successive messages */
1565  gcry_cipher_close (queue->out_cipher);
1567 }
static void setup_out_cipher(struct Queue *queue)
Setup cipher for outgoing data stream based on target and our ephemeral private key.
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition: crypto_ecc.c:435
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:213
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY
TCP communicator rekey message.
TCP rekey message box.

References calculate_hmac(), cfg, TcpRekeySignature::ephemeral, TCPRekey::ephemeral, GNUNET_assert, GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_ecdhe_key_get_public(), GNUNET_CRYPTO_eddsa_sign, GNUNET_e2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY, GNUNET_p2s(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY, GNUNET_STRINGS_absolute_time_to_string(), GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_absolute_ntoh(), TCPRekey::header, TCPRekey::hmac, TCPRekey::monotonic_time, TcpRekeySignature::monotonic_time, my_identity, my_private_key, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TcpRekeySignature::purpose, queue(), TcpRekeySignature::receiver, TcpRekeySignature::sender, TCPRekey::sender_sig, setup_out_cipher(), GNUNET_MessageHeader::size, GNUNET_CRYPTO_EccSignaturePurpose::size, and GNUNET_MessageHeader::type.

Referenced by queue_write().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_write()

static void queue_write ( void *  cls)
static

We have been notified that our socket is ready to write.

Then reschedule this function to be called again once more is available.

Parameters
clsa struct Queue

Definition at line 1577 of file gnunet-communicator-tcp.c.

1578 {
1579  struct Queue *queue = cls;
1580  ssize_t sent;
1581  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "In queue write\n");
1582  queue->write_task = NULL;
1583  if (0 != queue->cwrite_off)
1584  {
1585  sent = GNUNET_NETWORK_socket_send (queue->sock,
1586  queue->cwrite_buf,
1587  queue->cwrite_off);
1589  "Sent %lu bytes to TCP queue\n", sent);
1590  if ((-1 == sent) && (EAGAIN != errno) && (EINTR != errno))
1591  {
1593  queue_destroy (queue);
1594  return;
1595  }
1596  if (sent > 0)
1597  {
1598  size_t usent = (size_t) sent;
1599  queue->cwrite_off -= usent;
1600  memmove (queue->cwrite_buf,
1601  &queue->cwrite_buf[usent],
1602  queue->cwrite_off);
1604  }
1605  }
1606  /* can we encrypt more? (always encrypt full messages, needed
1607  such that #mq_cancel() can work!) */
1608  if ((0 < queue->rekey_left_bytes) &&
1609  (queue->pwrite_off > 0) &&
1610  (queue->cwrite_off + queue->pwrite_off <= BUF_SIZE))
1611  {
1613  "Encrypting %lu bytes\n", queue->pwrite_off);
1614  GNUNET_assert (0 ==
1615  gcry_cipher_encrypt (queue->out_cipher,
1616  &queue->cwrite_buf[queue->cwrite_off],
1617  queue->pwrite_off,
1618  queue->pwrite_buf,
1619  queue->pwrite_off));
1620  if (queue->rekey_left_bytes > queue->pwrite_off)
1621  queue->rekey_left_bytes -= queue->pwrite_off;
1622  else
1623  queue->rekey_left_bytes = 0;
1624  queue->cwrite_off += queue->pwrite_off;
1625  queue->pwrite_off = 0;
1626  }
1627  // if ((-1 != unverified_size)&& ((0 == queue->pwrite_off) &&
1628  if (((0 == queue->pwrite_off) &&
1629  ((0 == queue->rekey_left_bytes) ||
1630  (0 ==
1632  queue->rekey_time).rel_value_us))))
1633  {
1634  inject_rekey (queue);
1635  }
1636  if ((0 == queue->pwrite_off) && (! queue->finishing) &&
1637  (GNUNET_YES == queue->mq_awaits_continue))
1638  {
1639  queue->mq_awaits_continue = GNUNET_NO;
1641  }
1642  /* did we just finish writing 'finish'? */
1643  if ((0 == queue->cwrite_off) && (GNUNET_YES == queue->finishing))
1644  {
1646  "Finishing queue\n");
1647  queue_destroy (queue);
1648  return;
1649  }
1650  /* do we care to write more? */
1651  if ((0 < queue->cwrite_off) || (0 < queue->pwrite_off))
1652  queue->write_task =
1654  queue->sock,
1655  &queue_write,
1656  queue);
1657 }
static void queue_destroy(struct Queue *queue)
Functions with this signature are called whenever we need to close a queue due to a disconnect or fai...
static void inject_rekey(struct Queue *queue)
Inject a struct TCPRekey message into the queue's plaintext buffer.
static void queue_write(void *cls)
We have been notified that our socket is ready to write.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
Definition: mq.c:423
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:760
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_write_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *wfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1573
uint64_t rel_value_us
The actual value.

References BUF_SIZE, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror, GNUNET_MQ_impl_send_continue(), GNUNET_NETWORK_socket_send(), GNUNET_NO, GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, inject_rekey(), queue(), queue_destroy(), GNUNET_TIME_Relative::rel_value_us, and reschedule_queue_timeout().

Referenced by mq_init(), mq_send(), proto_read_kx(), queue_read_kx(), and try_handle_plaintext().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_handle_plaintext()

static size_t try_handle_plaintext ( struct Queue queue)
static

Test if we have received a full message in plaintext.

If so, handle it.

Parameters
queuequeue to process inbound plaintext for
Returns
number of bytes of plaintext handled, 0 for none

Definition at line 1668 of file gnunet-communicator-tcp.c.

1669 {
1670  const struct GNUNET_MessageHeader *hdr =
1671  (const struct GNUNET_MessageHeader *) queue->pread_buf;
1672  const struct TCPConfirmationAck *tca = (const struct
1673  TCPConfirmationAck *) queue->pread_buf;
1674  const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf;
1675  const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
1676  const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
1677  struct TCPRekey rekeyz;
1678  struct TCPFinish finz;
1679  struct GNUNET_ShortHashCode tmac;
1680  uint16_t type;
1681  size_t size = 0; /* make compiler happy */
1682  struct TcpHandshakeAckSignature thas;
1683  const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1684 
1686  "try handle plaintext!\n");
1687 
1688  if ((sizeof(*hdr) > queue->pread_off))
1689  {
1691  "Handling plaintext, not even a header!\n");
1692  return 0; /* not even a header */
1693  }
1694 
1696  {
1698  "Already received data of size %lu bigger than KX size %lu!\n",
1701  GNUNET_break_op (0);
1702  queue_finish (queue);
1703  return 0;
1704  }
1705 
1706  type = ntohs (hdr->type);
1707  switch (type)
1708  {
1711  "start processing ack\n");
1712  if (sizeof(*tca) > queue->pread_off)
1713  {
1715  "Handling plaintext size of tca greater than pread offset.\n");
1716  return 0;
1717  }
1718  if (ntohs (hdr->size) != sizeof(*tca))
1719  {
1721  "Handling plaintext size does not match message type.\n");
1722  GNUNET_break_op (0);
1723  queue_finish (queue);
1724  return 0;
1725  }
1726 
1727  thas.purpose.purpose = htonl (
1729  thas.purpose.size = htonl (sizeof(thas));
1730  thas.sender = tca->sender;
1731  thas.receiver = my_identity;
1732  thas.monotonic_time = tca->monotonic_time;
1733  thas.challenge = tca->challenge;
1734 
1737  &thas,
1738  &tca->sender_sig,
1739  &tca->sender.public_key))
1740  {
1742  "Verification of signature failed!\n");
1743  GNUNET_break (0);
1744  queue_finish (queue);
1745  return 0;
1746  }
1747  if (0 != GNUNET_memcmp (&tca->challenge, &challenge))
1748  {
1750  "Challenge in TCPConfirmationAck not correct!\n");
1751  GNUNET_break (0);
1752  queue_finish (queue);
1753  return 0;
1754  }
1755 
1756  queue->handshake_ack_monotime_get = GNUNET_PEERSTORE_iterate (peerstore,
1757  "transport_tcp_communicator",
1758  &queue->target,
1760  &
1762  queue);
1763 
1765  "Handling plaintext, ack processed!\n");
1766 
1768  {
1769  send_challenge (queue->challenge_received, queue);
1770  queue->write_task =
1772  queue->sock,
1773  &queue_write,
1774  queue);
1775  }
1776 
1777  unverified_size = -1;
1778 
1779  char *foreign_addr;
1780 
1781  switch (queue->address->sa_family)
1782  {
1783  case AF_INET:
1784  GNUNET_asprintf (&foreign_addr,
1785  "%s-%s",
1787  GNUNET_a2s (queue->address, queue->address_len));
1788  break;
1789 
1790  case AF_INET6:
1791  GNUNET_asprintf (&foreign_addr,
1792  "%s-%s",
1794  GNUNET_a2s (queue->address, queue->address_len));
1795  break;
1796 
1797  default:
1798  GNUNET_assert (0);
1799  }
1800 
1802  &queue->target,
1803  foreign_addr,
1804  UINT16_MAX, /* no MTU */
1806  0, /* Priority */
1807  queue->nt,
1808  queue->cs,
1809  queue->mq);
1810 
1811  GNUNET_free (foreign_addr);
1812 
1813  size = ntohs (hdr->size);
1814  break;
1816  /* Special case: header size excludes box itself! */
1817  if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
1818  return 0;
1819  calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
1820  if (0 != memcmp (&tmac, &box->hmac, sizeof(tmac)))
1821  {
1822  GNUNET_break_op (0);
1823  queue_finish (queue);
1824  return 0;
1825  }
1826  pass_plaintext_to_core (queue, (const void *) &box[1], ntohs (hdr->size));
1827  size = ntohs (hdr->size) + sizeof(*box);
1829  "Handling plaintext, box processed!\n");
1830  break;
1831 
1833  if (sizeof(*rekey) > queue->pread_off)
1834  return 0;
1835  if (ntohs (hdr->size) != sizeof(*rekey))
1836  {
1837  GNUNET_break_op (0);
1838  queue_finish (queue);
1839  return 0;
1840  }
1841  rekeyz = *rekey;
1842  memset (&rekeyz.hmac, 0, sizeof(rekeyz.hmac));
1843  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1844  if (0 != memcmp (&tmac, &rekey->hmac, sizeof(tmac)))
1845  {
1846  GNUNET_break_op (0);
1847  queue_finish (queue);
1848  return 0;
1849  }
1850  do_rekey (queue, rekey);
1851  size = ntohs (hdr->size);
1853  "Handling plaintext, rekey processed!\n");
1854  break;
1855 
1857  if (sizeof(*fin) > queue->pread_off)
1858  return 0;
1859  if (ntohs (hdr->size) != sizeof(*fin))
1860  {
1861  GNUNET_break_op (0);
1862  queue_finish (queue);
1863  return 0;
1864  }
1865  finz = *fin;
1866  memset (&finz.hmac, 0, sizeof(finz.hmac));
1867  calculate_hmac (&queue->in_hmac, &rekeyz, sizeof(rekeyz), &tmac);
1868  if (0 != memcmp (&tmac, &fin->hmac, sizeof(tmac)))
1869  {
1870  GNUNET_break_op (0);
1871  queue_finish (queue);
1872  return 0;
1873  }
1874  /* handle FINISH by destroying queue */
1875  queue_destroy (queue);
1877  "Handling plaintext, finish processed!\n");
1878  break;
1879 
1880  default:
1882  "Handling plaintext, nothing processed!\n");
1883  GNUNET_break_op (0);
1884  queue_finish (queue);
1885  return 0;
1886  }
1887  GNUNET_assert (0 != size);
1888  if (-1 != unverified_size)
1889  unverified_size += size;
1890  return size;
1891 }
static void pass_plaintext_to_core(struct Queue *queue, const void *plaintext, size_t plaintext_len)
We received plaintext_len bytes of plaintext on queue.
size_t unverified_size
Size of data received without KX challenge played back.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
#define INITIAL_CORE_KX_SIZE
Size of the initial core key exchange messages.
static void do_rekey(struct Queue *queue, const struct TCPRekey *rekey)
Handle rekey message on queue.
static void handshake_ack_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_A...
static void send_challenge(struct GNUNET_CRYPTO_ChallengeNonceP challenge, struct Queue *queue)
Sending challenge with TcpConfirmationAck back to sender of ephemeral key.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX
TCP communicator payload box.
#define GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED
Queue length.
struct GNUNET_TRANSPORT_QueueHandle * GNUNET_TRANSPORT_communicator_mq_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const struct GNUNET_PeerIdentity *peer, const char *address, uint32_t mtu, uint64_t q_len, uint32_t priority, enum GNUNET_NetworkType nt, enum GNUNET_TRANSPORT_ConnectionStatus cs, struct GNUNET_MQ_Handle *mq)
Notify transport service that a MQ became available due to an "inbound" connection or because the com...
@ GNUNET_TRANSPORT_CS_INBOUND
this is an inbound connection (communicator initiated)
static unsigned int size
Size of the "table".
Definition: peer.c:67
Type of a nonce used for challenges.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
TCP message box.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
struct GNUNET_ShortHashCode hmac
HMAC for the following encrypted message.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model

References calculate_hmac(), ch, COMMUNICATOR_ADDRESS_PREFIX, do_rekey(), GNUNET_a2s(), GNUNET_asprintf(), GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_eddsa_verify, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_memcmp, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY, GNUNET_PEERSTORE_iterate(), GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE_ACK, GNUNET_SCHEDULER_add_write_net(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE_ACK, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_communicator_mq_add(), GNUNET_TRANSPORT_CS_INBOUND, GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, handshake_ack_monotime_cb(), TCPFinish::hmac, TCPBox::hmac, INITIAL_CORE_KX_SIZE, my_identity, pass_plaintext_to_core(), peerstore, queue(), queue_destroy(), queue_finish(), queue_write(), send_challenge(), GNUNET_MessageHeader::size, size, GNUNET_MessageHeader::type, type, and unverified_size.

Referenced by queue_read().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tcp_address_to_sockaddr_numeric_v6()

static struct sockaddr* tcp_address_to_sockaddr_numeric_v6 ( socklen_t *  sock_len,
struct sockaddr_in6  v6,
unsigned int  port 
)
static

Convert a struct sockaddr_in6 to astruct sockaddr *`.

Parameters
[out]sock_lenset to the length of the address.
v6The sockaddr_in6 to be converted.
Returns
The struct sockaddr *.

Definition at line 2013 of file gnunet-communicator-tcp.c.

2016 {
2017  struct sockaddr *in;
2018 
2019  v6.sin6_family = AF_INET6;
2020  v6.sin6_port = htons ((uint16_t) port);
2021 #if HAVE_SOCKADDR_IN_SIN_LEN
2022  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
2023 #endif
2024  v6.sin6_flowinfo = 0;
2025  v6.sin6_scope_id = 0;
2026  in = GNUNET_memdup (&v6, sizeof(v6));
2027  *sock_len = sizeof(struct sockaddr_in6);
2028 
2029  return in;
2030 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147

References GNUNET_memdup, and port.

Referenced by init_socket_resolv(), run(), tcp_address_to_sockaddr(), and tcp_address_to_sockaddr_port_only().

Here is the caller graph for this function:

◆ tcp_address_to_sockaddr_numeric_v4()

static struct sockaddr* tcp_address_to_sockaddr_numeric_v4 ( socklen_t *  sock_len,
struct sockaddr_in  v4,
unsigned int  port 
)
static

Convert a struct sockaddr_in4 to astruct sockaddr *`.

Parameters
[out]sock_lenset to the length of the address.
v4The sockaddr_in4 to be converted.
Returns
The struct sockaddr *.

Definition at line 2041 of file gnunet-communicator-tcp.c.

2044 {
2045  struct sockaddr *in;
2046 
2047  v4.sin_family = AF_INET;
2048  v4.sin_port = htons ((uint16_t) port);
2049 #if HAVE_SOCKADDR_IN_SIN_LEN
2050  v4.sin_len = sizeof(struct sockaddr_in);
2051 #endif
2052  in = GNUNET_memdup (&v4, sizeof(v4));
2053  *sock_len = sizeof(struct sockaddr_in);
2054  return in;
2055 }

References GNUNET_memdup, and port.

Referenced by init_socket_resolv(), run(), tcp_address_to_sockaddr(), and tcp_address_to_sockaddr_port_only().

Here is the caller graph for this function:

◆ tcp_address_to_sockaddr_port_only()

static struct PortOnlyIpv4Ipv6* tcp_address_to_sockaddr_port_only ( const char *  bindto,
unsigned int *  port 
)
static

Convert TCP bind specification to a struct PortOnlyIpv4Ipv6 *

Parameters
bindtobind specification to convert.
Returns
The converted bindto specification.

Definition at line 2065 of file gnunet-communicator-tcp.c.

2066 {
2067  struct PortOnlyIpv4Ipv6 *po;
2068  struct sockaddr_in *i4;
2069  struct sockaddr_in6 *i6;
2070  socklen_t sock_len_ipv4;
2071  socklen_t sock_len_ipv6;
2072 
2073  /* interpreting value as just a PORT number */
2074  if (*port > UINT16_MAX)
2075  {
2077  "BINDTO specification `%s' invalid: value too large for port\n",
2078  bindto);
2079  return NULL;
2080  }
2081 
2082  po = GNUNET_new (struct PortOnlyIpv4Ipv6);
2083 
2084  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
2085  (GNUNET_YES ==
2088  "DISABLE_V6")))
2089  {
2090  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2091  po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2092  *port);
2093  po->addr_len_ipv4 = sock_len_ipv4;
2094  }
2095  else
2096  {
2097 
2098  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
2099  po->addr_ipv4 = tcp_address_to_sockaddr_numeric_v4 (&sock_len_ipv4, *i4,
2100  *port);
2101  po->addr_len_ipv4 = sock_len_ipv4;
2102 
2103  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
2104  po->addr_ipv6 = tcp_address_to_sockaddr_numeric_v6 (&sock_len_ipv6, *i6,
2105  *port);
2106 
2107  po->addr_len_ipv6 = sock_len_ipv6;
2108 
2109  GNUNET_free (i6);
2110  }
2111 
2112  GNUNET_free (i4);
2113 
2114  return po;
2115 }
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static struct sockaddr * tcp_address_to_sockaddr_numeric_v4(socklen_t *sock_len, struct sockaddr_in v4, unsigned int port)
Convert a struct sockaddr_in4 to astruct sockaddr *`.
static struct sockaddr * tcp_address_to_sockaddr_numeric_v6(socklen_t *sock_len, struct sockaddr_in6 v6, unsigned int port)
Convert a struct sockaddr_in6 to astruct sockaddr *`.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
#define GNUNET_malloc(size)
Wrapper around malloc.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:79
In case of port only configuration we like to bind to ipv4 and ipv6 addresses.
struct sockaddr * addr_ipv4
Ipv4 address we like to bind to.
struct sockaddr * addr_ipv6
Ipv6 address we like to bind to.
socklen_t addr_len_ipv6
Length of ipv6 address.
socklen_t addr_len_ipv4
Length of ipv4 address.

References PortOnlyIpv4Ipv6::addr_ipv4, PortOnlyIpv4Ipv6::addr_ipv6, PortOnlyIpv4Ipv6::addr_len_ipv4, PortOnlyIpv4Ipv6::addr_len_ipv6, cfg, COMMUNICATOR_CONFIG_SECTION, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_NETWORK_test_pf(), GNUNET_new, GNUNET_NO, GNUNET_YES, port, tcp_address_to_sockaddr_numeric_v4(), and tcp_address_to_sockaddr_numeric_v6().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ extract_address()

static char* extract_address ( const char *  bindto)
static

This Method extracts the address part of the BINDTO string.

Parameters
bindtoString we extract the address part from.
Returns
The extracted address string.

Definition at line 2125 of file gnunet-communicator-tcp.c.

2126 {
2127  char *addr;
2128  char *start;
2129  char *token;
2130  char *cp;
2131  char *rest = NULL;
2132  char *res;
2133 
2135  "extract address with bindto %s\n",
2136  bindto);
2137 
2138  if (NULL == bindto)
2140  "bindto is NULL\n");
2141 
2142  cp = GNUNET_strdup (bindto);
2143 
2145  "extract address 2\n");
2146 
2147  start = cp;
2148  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
2149  {
2150  start++; /* skip over '['*/
2151  cp[strlen (cp) - 1] = '\0'; /* eat ']'*/
2152  addr = GNUNET_strdup (start);
2153  }
2154  else
2155  {
2156  token = strtok_r (cp, "]", &rest);
2157  if (strlen (bindto) == strlen (token))
2158  {
2159  token = strtok_r (cp, ":", &rest);
2160  addr = GNUNET_strdup (token);
2161  }
2162  else
2163  {
2164  token++;
2165  res = GNUNET_strdup (token);
2166  addr = GNUNET_strdup (res);
2167  }
2168  }
2169 
2171  "tcp address: %s\n",
2172  addr);
2173  GNUNET_free (cp);
2174  return addr;
2175 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int res
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_strdup, res, and start.

Referenced by run(), and tcp_address_to_sockaddr().

Here is the caller graph for this function:

◆ extract_port()

static unsigned int extract_port ( const char *  addr_and_port)
static

This Method extracts the port part of the BINDTO string.

Parameters
addr_and_portString we extract the port from.
Returns
The extracted port as unsigned int.

Definition at line 2185 of file gnunet-communicator-tcp.c.

2186 {
2187  unsigned int port;
2188  char dummy[2];
2189  char *token;
2190  char *addr;
2191  char *colon;
2192  char *cp;
2193  char *rest = NULL;
2194 
2195  if (NULL != addr_and_port)
2196  {
2197  cp = GNUNET_strdup (addr_and_port);
2198  token = strtok_r (cp, "]", &rest);
2199  if (strlen (addr_and_port) == strlen (token))
2200  {
2201  colon = strrchr (cp, ':');
2202  if (NULL == colon)
2203  {
2204  GNUNET_free (cp);
2205  return 0;
2206  }
2207  addr = colon;
2208  addr++;
2209  }
2210  else
2211  {
2212  token = strtok_r (NULL, "]", &rest);
2213  if (NULL == token)
2214  {
2215  GNUNET_free (cp);
2216  return 0;
2217  }
2218  else
2219  {
2220  addr = token;
2221  addr++;
2222  }
2223  }
2224 
2225 
2226  if (1 == sscanf (addr, "%u%1s", &port, dummy))
2227  {
2228  /* interpreting value as just a PORT number */
2229  if (port > UINT16_MAX)
2230  {
2232  "Port `%u' invalid: value too large for port\n",
2233  port);
2234  GNUNET_free (cp);
2235  return 0;
2236  }
2237  }
2238  else
2239  {
2241  "BINDTO specification invalid: last ':' not followed by number\n");
2242  GNUNET_free (cp);
2243  return 0;
2244  }
2245  GNUNET_free (cp);
2246  }
2247  else
2248  {
2250  "return 0\n");
2251  /* interpret missing port as 0, aka pick any free one */
2252  port = 0;
2253  }
2254 
2255  return port;
2256 }
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.

References dummy, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_strdup, and port.

Referenced by run(), and tcp_address_to_sockaddr().

Here is the caller graph for this function:

◆ tcp_address_to_sockaddr()

static struct sockaddr* tcp_address_to_sockaddr ( const char *  bindto,
socklen_t *  sock_len 
)
static

Convert TCP bind specification to a struct sockaddr *

Parameters
bindtobind specification to convert
[out]sock_lenset to the length of the address
Returns
converted bindto specification

Definition at line 2267 of file gnunet-communicator-tcp.c.

2268 {
2269  struct sockaddr *in;
2270  unsigned int port;
2271  struct sockaddr_in v4;
2272  struct sockaddr_in6 v6;
2273  char *start;
2274 
2275  start = extract_address (bindto);
2276  // FIXME: check NULL == start
2278  "start %s\n",
2279  start);
2280 
2282  "!bindto %s\n",
2283  bindto);
2284 
2285 
2286  if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
2287  {
2288  // colon = strrchr (cp, ':');
2289  port = extract_port (bindto);
2290 
2292  "port %u\n",
2293  port);
2294 
2295  in = tcp_address_to_sockaddr_numeric_v4 (sock_len, v4, port);
2296  }
2297  else if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
2298  {
2299  // colon = strrchr (cp, ':');
2300  port = extract_port (bindto);
2301  in = tcp_address_to_sockaddr_numeric_v6 (sock_len, v6, port);
2302  }
2303  else
2304  {
2305  GNUNET_assert (0);
2306  }
2307 
2308  GNUNET_free (start);
2309  return in;
2310 }
static char * extract_address(const char *bindto)
This Method extracts the address part of the BINDTO string.
static unsigned int extract_port(const char *addr_and_port)
This Method extracts the port part of the BINDTO string.

References extract_address(), extract_port(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, port, start, tcp_address_to_sockaddr_numeric_v4(), and tcp_address_to_sockaddr_numeric_v6().

Referenced by mq_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_send()

static void mq_send ( struct GNUNET_MQ_Handle mq,
const struct GNUNET_MessageHeader msg,
void *  impl_state 
)
static

Signature of functions implementing the sending functionality of a message queue.

Parameters
mqthe message queue
msgthe message to send
impl_stateour struct Queue

Definition at line 2322 of file gnunet-communicator-tcp.c.

2325 {
2326  struct Queue *queue = impl_state;
2327  uint16_t msize = ntohs (msg->size);
2328  struct TCPBox box;
2330  "In MQ send. Queue finishing: %s; write task running: %s\n",
2331  (GNUNET_YES == queue->finishing) ? "yes" : "no",
2332  (NULL == queue->write_task) ? "yes" : "no");
2333  GNUNET_assert (mq == queue->mq);
2334  queue->mq_awaits_continue = GNUNET_YES;
2335  if (GNUNET_YES == queue->finishing)
2336  return; /* this queue is dying, drop msg */
2337  GNUNET_assert (0 == queue->pwrite_off);
2338  box.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX);
2339  box.header.size = htons (msize);
2340  calculate_hmac (&queue->out_hmac, msg, msize, &box.hmac);
2341  memcpy (&queue->pwrite_buf[queue->pwrite_off], &box, sizeof(box));
2342  queue->pwrite_off += sizeof(box);
2343  memcpy (&queue->pwrite_buf[queue->pwrite_off], msg, msize);
2344  queue->pwrite_off += msize;
2346  "%lu bytes of plaintext to send\n", queue->pwrite_off);
2347  GNUNET_assert (NULL != queue->sock);
2348  if (NULL == queue->write_task)
2349  queue->write_task =
2351  queue->sock,
2352  &queue_write,
2353  queue);
2354 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2

References calculate_hmac(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX, GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, TCPBox::header, TCPBox::hmac, mq, msg, queue(), queue_write(), GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by boot_queue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_destroy()

static void mq_destroy ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Signature of functions implementing the destruction of a message queue.

Implementations must not free mq, but should take care of impl_state.

Parameters
mqthe message queue to destroy
impl_stateour struct Queue

Definition at line 2366 of file gnunet-communicator-tcp.c.

2367 {
2368  struct Queue *queue = impl_state;
2369 
2370  if (mq == queue->mq)
2371  {
2372  queue->mq = NULL;
2373  queue_finish (queue);
2374  }
2375 }

References mq, queue(), and queue_finish().

Referenced by boot_queue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_cancel()

static void mq_cancel ( struct GNUNET_MQ_Handle mq,
void *  impl_state 
)
static

Implementation function that cancels the currently sent message.

Parameters
mqmessage queue
impl_stateour struct Queue

Definition at line 2385 of file gnunet-communicator-tcp.c.

2386 {
2387  struct Queue *queue = impl_state;
2388 
2389  GNUNET_assert (0 != queue->pwrite_off);
2390  queue->pwrite_off = 0;
2391 }

References GNUNET_assert, and queue().

Referenced by boot_queue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_error()

static void mq_error ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

Generic error handler, called with the appropriate error code and the same closure specified at the creation of the message queue.

Not every message queue implementation supports an error handler.

Parameters
clsour struct Queue
errorerror code

Definition at line 2404 of file gnunet-communicator-tcp.c.

2405 {
2406  struct Queue *queue = cls;
2407 
2409  "MQ error in queue to %s: %d\n",
2410  GNUNET_i2s (&queue->target),
2411  (int) error);
2412  queue_finish (queue);
2413 }

References GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, queue(), and queue_finish().

Referenced by boot_queue().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ boot_queue()

static void boot_queue ( struct Queue queue)
static

Add the given queue to our internal data structure.

Setup the MQ processing and inform transport that the queue is ready. Must be called after the KX for outgoing messages has been bootstrapped.

Parameters
queuequeue to boot

Definition at line 2424 of file gnunet-communicator-tcp.c.

2425 {
2426  queue->nt =
2427  GNUNET_NT_scanner_get_type (is, queue->address, queue->address_len);
2429  queue_map,
2430  &queue->target,
2431  queue,
2434  "# queues active",
2436  GNUNET_NO);
2437  queue->timeout =
2440  &mq_destroy,
2441  &mq_cancel,
2442  queue,
2443  NULL,
2444  &mq_error,
2445  queue);
2446 }
static void mq_destroy(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static void mq_send(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
struct GNUNET_MQ_Handle * GNUNET_MQ_queue_for_callbacks(GNUNET_MQ_SendImpl send, GNUNET_MQ_DestroyImpl destroy, GNUNET_MQ_CancelImpl cancel, void *impl_state, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *cls)
Create a message queue for the specified handlers.
Definition: mq.c:467
enum GNUNET_NetworkType GNUNET_NT_scanner_get_type(struct GNUNET_NT_InterfaceScanner *is, const struct sockaddr *addr, socklen_t addrlen)
Returns where the address is located: loopback, LAN or WAN.
Definition: nt.c:314

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_MQ_queue_for_callbacks(), GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_STATISTICS_set(), GNUNET_TIME_relative_to_absolute(), is, mq_cancel(), mq_destroy(), mq_error(), mq_send(), queue(), queue_map, and stats.

Referenced by mq_init(), and proto_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_kx()

static void transmit_kx ( struct Queue queue,
const struct GNUNET_CRYPTO_EcdhePublicKey epub 
)
static

Generate and transmit our ephemeral key and the signature for the initial KX with the other peer.

Must be called first, before any other bytes are ever written to the output buffer. Note that our cipher must already be initialized when calling thi function. Helper function for start_initial_kx_out().

Parameters
queuequeue to do KX for
epubour public key for the KX

Definition at line 2460 of file gnunet-communicator-tcp.c.

2462 {
2463  struct TcpHandshakeSignature ths;
2464  struct TCPConfirmation tc;
2465 
2466  memcpy (queue->cwrite_buf, epub, sizeof(*epub));
2467  queue->cwrite_off = sizeof(*epub);
2468  /* compute 'tc' and append in encrypted format to cwrite_buf */
2469  tc.sender = my_identity;
2470  tc.monotonic_time =
2473  &tc.challenge,
2474  sizeof(tc.challenge));
2475  ths.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2476  ths.purpose.size = htonl (sizeof(ths));
2477  ths.sender = my_identity;
2478  ths.receiver = queue->target;
2479  ths.ephemeral = *epub;
2480  ths.monotonic_time = tc.monotonic_time;
2481  ths.challenge = tc.challenge;
2483  &ths,
2484  &tc.sender_sig);
2485  GNUNET_assert (0 ==
2486  gcry_cipher_encrypt (queue->out_cipher,
2487  &queue->cwrite_buf[queue->cwrite_off],
2488  sizeof(tc),
2489  &tc,
2490  sizeof(tc)));
2491  queue->challenge = tc.challenge;
2492  queue->cwrite_off += sizeof(tc);
2493 
2495  "transport",
2496  "handshake written\n");
2497 }
#define GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE
Signature used by TCP communicator handshake.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:423
Signature we use to verify that the ephemeral key was really chosen by the specified sender.

References cfg, TcpHandshakeSignature::challenge, TcpHandshakeSignature::ephemeral, GNUNET_assert, GNUNET_CRYPTO_eddsa_sign, GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_block(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log_from_nocheck(), GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE, GNUNET_TIME_absolute_get_monotonic(), GNUNET_TIME_absolute_hton(), TcpHandshakeSignature::monotonic_time, my_identity, my_private_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TcpHandshakeSignature::purpose, queue(), TcpHandshakeSignature::receiver, TcpHandshakeSignature::sender, GNUNET_CRYPTO_EccSignaturePurpose::size, and tc.

Referenced by start_initial_kx_out().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ start_initial_kx_out()

static void start_initial_kx_out ( struct Queue queue)
static

Initialize our key material for outgoing transmissions and inform the other peer about it.

Must be called first before any data is sent.

Parameters
queuethe queue to setup

Definition at line 2508 of file gnunet-communicator-tcp.c.

2509 {
2510  struct GNUNET_CRYPTO_EcdhePublicKey epub;
2511 
2512  GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral);
2513  GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub);
2515  transmit_kx (queue, &epub);
2516 }
static void transmit_kx(struct Queue *queue, const struct GNUNET_CRYPTO_EcdhePublicKey *epub)
Generate and transmit our ephemeral key and the signature for the initial KX with the other peer.

References GNUNET_CRYPTO_ecdhe_key_create(), GNUNET_CRYPTO_ecdhe_key_get_public(), queue(), setup_out_cipher(), and transmit_kx().

Referenced by mq_init(), and proto_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handshake_monotime_store_cb()

static void handshake_monotime_store_cb ( void *  cls,
int  success 
)
static

Callback called when peerstore store operation for handshake monotime is finished.

Parameters
clsQueue context the store operation was executed.
successStore operation was successful (GNUNET_OK) or not.

Definition at line 2525 of file gnunet-communicator-tcp.c.

2526 {
2527  struct Queue *queue = cls;
2528  if (GNUNET_OK != success)
2529  {
2531  "Failed to store handshake monotonic time in PEERSTORE!\n");
2532  }
2533  queue->handshake_monotime_sc = NULL;
2534 }

References GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, and queue().

Referenced by handshake_monotime_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handshake_monotime_cb()

static void handshake_monotime_cb ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE where found.

Parameters
clsQueue context the store operation was executed.
recordThe record found or NULL if there is no record left.
emsgMessage from peerstore.

Definition at line 2545 of file gnunet-communicator-tcp.c.

2548 {
2549  struct Queue *queue = cls;
2550  struct GNUNET_TIME_AbsoluteNBO *mtbe;
2551  struct GNUNET_TIME_Absolute mt;
2552  const struct GNUNET_PeerIdentity *pid;
2553  struct GNUNET_TIME_AbsoluteNBO *handshake_monotonic_time;
2554 
2555  (void) emsg;
2556 
2557  handshake_monotonic_time = &queue->handshake_monotonic_time;
2558  pid = &queue->target;
2560  "tcp handshake with us %s\n",
2561  GNUNET_i2s (&my_identity));
2562  if (NULL == record)
2563  {
2564  queue->handshake_monotime_get = NULL;
2565  return;
2566  }
2568  "tcp handshake from peer %s\n",
2569  GNUNET_i2s (pid));
2570  if (sizeof(*mtbe) != record->value_size)
2571  {
2572  GNUNET_break (0);
2573  return;
2574  }
2575  mtbe = record->value;
2576  mt = GNUNET_TIME_absolute_ntoh (*mtbe);
2577  if (mt.abs_value_us > GNUNET_TIME_absolute_ntoh (
2578  queue->handshake_monotonic_time).abs_value_us)
2579  {
2581  "Queue from %s dropped, handshake monotime in the past\n",
2582  GNUNET_i2s (&queue->target));
2583  GNUNET_break (0);
2584  queue_finish (queue);
2585  return;
2586  }
2587  queue->handshake_monotime_sc = GNUNET_PEERSTORE_store (peerstore,
2588  "transport_tcp_communicator",
2589  pid,
2591  handshake_monotonic_time,
2592  sizeof(*
2593  handshake_monotonic_time),
2596  &
2598  queue);
2599 }
static void handshake_monotime_store_cb(void *cls, int success)
Callback called when peerstore store operation for handshake monotime is finished.
#define GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE
Key used to store sender's monotonic time from handshake message.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, GNUNET_PEERSTORE_store(), GNUNET_PEERSTORE_STOREOPTION_REPLACE, GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE, GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_UNIT_FOREVER_ABS, handshake_monotime_store_cb(), my_identity, peerstore, pid, queue(), queue_finish(), and record().

Referenced by decrypt_and_check_tc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ decrypt_and_check_tc()

static int decrypt_and_check_tc ( struct Queue queue,
struct TCPConfirmation tc,
char *  ibuf 
)
static

We have received the first bytes from the other side on a queue.

Decrypt the tc contained in ibuf and check the signature. Note that setup_in_cipher() must have already been called.

Parameters
queuequeue to decrypt initial bytes from other peer for
tc[out]where to store the result
ibufincoming data, of size INITIAL_KX_SIZE
Returns
GNUNET_OK if the signature was OK, GNUNET_SYSERR if not

Definition at line 2614 of file gnunet-communicator-tcp.c.

2617 {
2618  struct TcpHandshakeSignature ths;
2620 
2621  GNUNET_assert (
2622  0 ==
2623  gcry_cipher_decrypt (queue->in_cipher,
2624  tc,
2625  sizeof(*tc),
2626  &ibuf[sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)],
2627  sizeof(*tc)));
2628  ths.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE);
2629  ths.purpose.size = htonl (sizeof(ths));
2630  ths.sender = tc->sender;
2631  ths.receiver = my_identity;
2632  memcpy (&ths.ephemeral, ibuf, sizeof(struct GNUNET_CRYPTO_EcdhePublicKey));
2633  ths.monotonic_time = tc->monotonic_time;
2634  ths.challenge = tc->challenge;
2637  &ths,
2638  &tc->sender_sig,
2639  &tc->sender.public_key);
2640  if (GNUNET_YES == ret)
2641  queue->handshake_monotime_get =
2643  "transport_tcp_communicator",
2644  &queue->target,
2647  queue);
2648  return ret;
2649 }
static void handshake_monotime_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Callback called by peerstore when records for GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE w...
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:92

References TcpHandshakeSignature::challenge, TcpHandshakeSignature::ephemeral, GNUNET_assert, GNUNET_CRYPTO_eddsa_verify, GNUNET_PEERSTORE_iterate(), GNUNET_PEERSTORE_TRANSPORT_TCP_COMMUNICATOR_HANDSHAKE, GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_HANDSHAKE, GNUNET_YES, handshake_monotime_cb(), TcpHandshakeSignature::monotonic_time, my_identity, peerstore, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TcpHandshakeSignature::purpose, queue(), TcpHandshakeSignature::receiver, ret, TcpHandshakeSignature::sender, GNUNET_CRYPTO_EccSignaturePurpose::size, and tc.

Referenced by proto_read_kx(), and queue_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_proto_queue()

static void free_proto_queue ( struct ProtoQueue pq)
static

Closes socket and frees memory associated with pq.

Parameters
pqproto queue to free

Definition at line 2658 of file gnunet-communicator-tcp.c.

2659 {
2660  if (NULL != pq->listen_sock)
2661  {
2663  pq->listen_sock = NULL;
2664  }
2666  GNUNET_free (pq->address);
2668  GNUNET_free (pq);
2669 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_NETWORK_Handle * listen_sock
Listen socket.

References ProtoQueue::address, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_OK, ProtoQueue::listen_sock, proto_head, proto_tail, and ProtoQueue::sock.

Referenced by do_shutdown(), and proto_read_kx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ proto_read_kx()

static void proto_read_kx ( void *  cls)
static

Read from the socket of the proto queue until we have enough data to upgrade to full queue.

Parameters
clsa struct ProtoQueue

Definition at line 2679 of file gnunet-communicator-tcp.c.

2680 {
2681  struct ProtoQueue *pq = cls;
2682  ssize_t rcvd;
2683  struct GNUNET_TIME_Relative left;
2684  struct Queue *queue;
2685  struct TCPConfirmation tc;
2686 
2687  pq->read_task = NULL;
2689  if (0 == left.rel_value_us)
2690  {
2691  free_proto_queue (pq);
2692  return;
2693  }
2694  rcvd = GNUNET_NETWORK_socket_recv (pq->sock,
2695  &pq->ibuf[pq->ibuf_off],
2696  sizeof(pq->ibuf) - pq->ibuf_off);
2698  "Received %lu bytes for KX\n", rcvd);
2700  "transport",
2701  "Received %lu bytes for KX\n", rcvd);
2702  if (-1 == rcvd)
2703  {
2704  if ((EAGAIN != errno) && (EINTR != errno))
2705  {
2707  free_proto_queue (pq);
2708  return;
2709  }
2710  /* try again */
2711  pq->read_task =
2713  return;
2714  }
2715  pq->ibuf_off += rcvd;
2716  if (pq->ibuf_off > sizeof(pq->ibuf))
2717  {
2718  /* read more */
2719  pq->read_task =
2721  return;
2722  }
2723  /* we got all the data, let's find out who we are talking to! */
2724  queue = GNUNET_new (struct Queue);
2725  setup_in_cipher ((const struct GNUNET_CRYPTO_EcdhePublicKey *) pq->ibuf,
2726  queue);
2727  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, pq->ibuf))
2728  {
2730  "Invalid TCP KX received from %s\n",
2731  GNUNET_a2s (pq->address, pq->address_len));
2732  gcry_cipher_close (queue->in_cipher);
2733  GNUNET_free (queue);
2734  free_proto_queue (pq);
2735  return;
2736  }
2737  queue->address = pq->address; /* steals reference */
2738  queue->address_len = pq->address_len;
2739  queue->target = tc.sender;
2740  queue->listen_sock = pq->listen_sock;
2741  queue->sock = pq->sock;
2742 
2744  "created queue with target %s\n",
2745  GNUNET_i2s (&queue->target));
2746 
2748  "start kx proto\n");
2749 
2752  boot_queue (queue);
2753  queue->read_task =
2755  queue->sock,
2756  &queue_read,
2757  queue);
2758  queue->write_task =
2760  queue->sock,
2761  &queue_write,
2762  queue);
2763  // TODO To early! Move it somewhere else.
2764  // send_challenge (tc.challenge, queue);
2765  queue->challenge_received = tc.challenge;
2766 
2768  GNUNET_free (pq);
2769 }
static void boot_queue(struct Queue *queue)
Add the given queue to our internal data structure.
static int decrypt_and_check_tc(struct Queue *queue, struct TCPConfirmation *tc, char *ibuf)
We have received the first bytes from the other side on a queue.
static void start_initial_kx_out(struct Queue *queue)
Initialize our key material for outgoing transmissions and inform the other peer about it.
static void free_proto_queue(struct ProtoQueue *pq)
Closes socket and frees memory associated with pq.
@ GNUNET_ERROR_TYPE_INFO
size_t ibuf_off
Current offset for reading into ibuf.
char ibuf[(sizeof(struct GNUNET_CRYPTO_EcdhePublicKey)+sizeof(struct TCPConfirmation))]
Buffer for reading all the information we need to upgrade from protoqueue to queue.

References ProtoQueue::address, ProtoQueue::address_len, boot_queue(), decrypt_and_check_tc(), free_proto_queue(), GNUNET_a2s(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_log_from_nocheck(), GNUNET_log_strerror, GNUNET_NETWORK_socket_recv(), GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_CS_INBOUND, ProtoQueue::ibuf, ProtoQueue::ibuf_off, ProtoQueue::listen_sock, proto_head, proto_tail, queue(), queue_read(), queue_write(), ProtoQueue::read_task, GNUNET_TIME_Relative::rel_value_us, setup_in_cipher(), ProtoQueue::sock, start_initial_kx_out(), tc, and ProtoQueue::timeout.

Referenced by listen_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ queue_read_kx()

static void queue_read_kx ( void *  cls)
static

Read from the socket of the queue until we have enough data to initialize the decryption logic and can switch to regular reading.

Parameters
clsa struct Queue

Definition at line 2834 of file gnunet-communicator-tcp.c.

2835 {
2836  struct Queue *queue = cls;
2837  ssize_t rcvd;
2838  struct GNUNET_TIME_Relative left;
2839  struct TCPConfirmation tc;
2840 
2841  queue->read_task = NULL;
2842  left = GNUNET_TIME_absolute_get_remaining (queue->timeout);
2843  if (0 == left.rel_value_us)
2844  {
2845  queue_destroy (queue);
2846  return;
2847  }
2848  rcvd = GNUNET_NETWORK_socket_recv (queue->sock,
2849  &queue->cread_buf[queue->cread_off],
2850  BUF_SIZE - queue->cread_off);
2852  "Received %lu bytes for KX\n",
2853  rcvd);
2855  "transport",
2856  "Received %lu bytes for KX\n",
2857  rcvd);
2858  if (-1 == rcvd)
2859  {
2860  if ((EAGAIN != errno) && (EINTR != errno))
2861  {
2863  queue_destroy (queue);
2864  return;
2865  }
2866  queue->read_task =
2868  return;
2869  }
2870  queue->cread_off += rcvd;
2871  if (queue->cread_off < INITIAL_KX_SIZE)
2872  {
2873  /* read more */
2874  queue->read_task =
2876  return;
2877  }
2878  /* we got all the data, let's find out who we are talking to! */
2880  queue->cread_buf,
2881  queue);
2882  if (GNUNET_OK != decrypt_and_check_tc (queue, &tc, queue->cread_buf))
2883  {
2885  "Invalid TCP KX received from %s\n",
2886  GNUNET_a2s (queue->address, queue->address_len));
2887  queue_destroy (queue);
2888  return;
2889  }
2890  if (0 !=
2891  memcmp (&tc.sender, &queue->target, sizeof(struct GNUNET_PeerIdentity)))
2892  {
2894  "Invalid sender in TCP KX received from %s\n",
2895  GNUNET_a2s (queue->address, queue->address_len));
2896  queue_destroy (queue);
2897  return;
2898  }
2899  send_challenge (tc.challenge, queue);
2900  queue->write_task =
2902  queue->sock,
2903  &queue_write,
2904  queue);
2905 
2906  /* update queue timeout */
2908  /* prepare to continue with regular read task immediately */
2909  memmove (queue->cread_buf,
2910  &queue->cread_buf[INITIAL_KX_SIZE],
2911  queue->cread_off - (INITIAL_KX_SIZE));
2913  "cread_off is %lu bytes before adjusting\n",
2914  queue->cread_off);
2915  queue->cread_off -= INITIAL_KX_SIZE;
2917  "cread_off set to %lu bytes\n",
2918  queue->cread_off);
2920 }
static void queue_read_kx(void *cls)
Read from the socket of the queue until we have enough data to initialize the decryption logic and ca...
#define INITIAL_KX_SIZE
Size of the initial key exchange message sent first in both directions.
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:1281

References BUF_SIZE, decrypt_and_check_tc(), GNUNET_a2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_from_nocheck(), GNUNET_log_strerror, GNUNET_NETWORK_socket_recv(), GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_write_net(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_UNIT_FOREVER_REL, INITIAL_KX_SIZE, queue(), queue_destroy(), queue_read(), queue_write(), GNUNET_TIME_Relative::rel_value_us, reschedule_queue_timeout(), send_challenge(), setup_in_cipher(), and tc.

Referenced by mq_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_init()

static int mq_init ( void *  cls,
const struct GNUNET_PeerIdentity peer,
const char *  address 
)
static

Function called by the transport service to initialize a message queue given address information about another peer.

If and when the communication channel is established, the communicator must call GNUNET_TRANSPORT_communicator_mq_add() to notify the service that the channel is now up. It is the responsibility of the communicator to manage sane retries and timeouts for any peer/address combination provided by the transport service. Timeouts and retries do not need to be signalled to the transport service.

Parameters
clsclosure
peeridentity of the other peer
addresswhere to send the message, human-readable communicator-specific format, 0-terminated, UTF-8
Returns
GNUNET_OK on success, GNUNET_SYSERR if the provided address is invalid

Definition at line 2942 of file gnunet-communicator-tcp.c.

2943 {
2944  struct Queue *queue;
2945  const char *path;
2946  struct sockaddr *in;
2947  socklen_t in_len = 0;
2948  struct GNUNET_NETWORK_Handle *sock;
2949 
2951  "Connecting to %s\n", address);
2953  "transport",
2954  "Connecting to %s\n", address);
2955  if (0 != strncmp (address,
2957  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
2958  {
2959  GNUNET_break_op (0);
2960  return GNUNET_SYSERR;
2961  }
2962  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
2963  in = tcp_address_to_sockaddr (path, &in_len);
2964 
2965  if (NULL == in)
2966  {
2968  "Failed to setup TCP socket address\n");
2969  return GNUNET_SYSERR;
2970  }
2971 
2973  "in %s\n",
2974  GNUNET_a2s (in, in_len));
2975 
2976  sock = GNUNET_NETWORK_socket_create (in->sa_family, SOCK_STREAM, IPPROTO_TCP);
2977  if (NULL == sock)
2978  {
2980  "socket(%d) failed: %s",
2981  in->sa_family,
2982  strerror (errno));
2983  GNUNET_free (in);
2984  return GNUNET_SYSERR;
2985  }
2986  if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (sock, in, in_len)) &&
2987  (errno != EINPROGRESS))
2988  {
2990  "connect to `%s' failed: %s",
2991  address,
2992  strerror (errno));
2994  GNUNET_free (in);
2995  return GNUNET_SYSERR;
2996  }
2997 
2998  queue = GNUNET_new (struct Queue);
2999  queue->target = *peer;
3000  queue->address = in;
3001  queue->address_len = in_len;
3002  queue->sock = sock;
3004  boot_queue (queue);
3006  "booted queue with target %s\n",
3007  GNUNET_i2s (&queue->target));
3008  // queue->mq_awaits_continue = GNUNET_YES;
3009  queue->read_task =
3011  queue->sock,
3012  &queue_read_kx,
3013  queue);
3014 
3015 
3017  "start kx mq_init\n");
3018 
3020  queue->write_task =
3022  queue->sock,
3023  &queue_write,
3024  queue);
3025  return GNUNET_OK;
3026 }
static struct sockaddr * tcp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert TCP bind specification to a struct sockaddr *
static char * address
GNS address for this phone.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:606
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:855
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.

References address, boot_queue(), COMMUNICATOR_ADDRESS_PREFIX, GNUNET_a2s(), GNUNET_break_op, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_log_from_nocheck(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_write_net(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_CS_OUTBOUND, peer, queue(), queue_read_kx(), queue_write(), start_initial_kx_out(), and tcp_address_to_sockaddr().

Referenced by GNUNET_TRANSPORT_communicator_connect(), and init_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_lt_delete_it()

static int get_lt_delete_it ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Iterator over all ListenTasks to clean up.

Parameters
clsNULL
keyunused
valuethe ListenTask to cancel.
Returns
GNUNET_OK to continue to iterate

Definition at line 3038 of file gnunet-communicator-tcp.c.

3041 {
3042  struct ListenTask *lt = value;
3043 
3044  (void) cls;
3045  (void) key;
3046  if (NULL != lt->listen_task)
3047  {
3049  lt->listen_task = NULL;
3050  }
3051  if (NULL != lt->listen_sock)
3052  {
3054  lt->listen_sock = NULL;
3055  }
3056  return GNUNET_OK;
3057 }
static char * value
Value of the record to add/remove.

References GNUNET_break, GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), key, ListenTask::listen_sock, ListenTask::listen_task, and value.

Referenced by do_shutdown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_queue_delete_it()

static int get_queue_delete_it ( void *  cls,
const struct GNUNET_PeerIdentity target,
void *  value 
)
static

Iterator over all message queues to clean up.

Parameters
clsNULL
targetunused
valuethe queue to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 3069 of file gnunet-communicator-tcp.c.

3072 {
3073  struct Queue *queue = value;
3074 
3075  (void) cls;
3076  (void) target;
3077  queue_destroy (queue);
3078  return GNUNET_OK;
3079 }
struct GNUNET_PeerIdentity target
To whom are we talking to.

References GNUNET_OK, queue(), queue_destroy(), Queue::target, and value.

Referenced by do_shutdown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Shutdown the UNIX communicator.

Parameters
clsNULL (always)

Definition at line 3088 of file gnunet-communicator-tcp.c.

3089 {
3091  "Shutdown %s!\n",
3092  shutdown_running ? "running" : "not running");
3093 
3095  return;
3096  else
3098 
3099  while (NULL != proto_head)
3101  if (NULL != nat)
3102  {
3104  nat = NULL;
3105  }
3109  if (NULL != ch)
3110  {
3113  ch = NULL;
3114  }
3115  if (NULL != stats)
3116  {
3118  stats = NULL;
3119  }
3120  if (NULL != my_private_key)
3121  {
3123  my_private_key = NULL;
3124  }
3125  if (NULL != is)
3126  {
3128  is = NULL;
3129  }
3130  if (NULL != peerstore)
3131  {
3133  peerstore = NULL;
3134  }
3135  if (NULL != resolve_request_handle)
3136  {
3138  resolve_request_handle = NULL;
3139  }
3141  "Shutdown done!\n");
3142 }
static int get_queue_delete_it(void *cls, const struct GNUNET_PeerIdentity *target, void *value)
Iterator over all message queues to clean up.
static int get_lt_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all ListenTasks to clean up.
struct GNUNET_RESOLVER_RequestHandle * resolve_request_handle
Handle for DNS lookup of bindto address.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:701
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition: nt.c:433
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h, int sync_first)
Disconnect from the PEERSTORE service.
void GNUNET_RESOLVER_request_cancel(struct GNUNET_RESOLVER_RequestHandle *rh)
Cancel a request that is still pending with the resolver.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
void GNUNET_TRANSPORT_communicator_address_remove_all(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Notify transport service that this communicator no longer provides all its addresses for this peer.

References ch, free_proto_queue(), get_lt_delete_it(), get_queue_delete_it(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NAT_unregister(), GNUNET_NO, GNUNET_NT_scanner_done(), GNUNET_PEERSTORE_disconnect(), GNUNET_RESOLVER_request_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_TRANSPORT_communicator_address_remove_all(), GNUNET_TRANSPORT_communicator_disconnect(), GNUNET_YES, is, lt_map, my_private_key, nat, peerstore, proto_head, queue_map, resolve_request_handle, shutdown_running, and stats.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ enc_notify_cb()

static void enc_notify_cb ( void *  cls,
const struct GNUNET_PeerIdentity sender,
const struct GNUNET_MessageHeader msg 
)
static

Function called when the transport service has received an acknowledgement for this communicator (!) via a different return path.

Not applicable for TCP.

Parameters
clsclosure
senderwhich peer sent the notification
msgpayload

Definition at line 3157 of file gnunet-communicator-tcp.c.

3160 {
3161  (void) cls;
3162  (void) sender;
3163  (void) msg;
3164  GNUNET_break_op (0);
3165 }

References GNUNET_break_op, and msg.

Referenced by init_socket().

Here is the caller graph for this function:

◆ nat_address_cb()

static void nat_address_cb ( void *  cls,
void **  app_ctx,
int  add_remove,
enum GNUNET_NAT_AddressClass  ac,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of 'valid' addresses changes.

Parameters
clsclosure
app_ctx[in,out]location where the app can store stuff on add and retrieve it on remove
add_removeGNUNET_YES to add a new public IP address, GNUNET_NO to remove a previous (now invalid) one
acaddress class the address belongs to
addreither the previous or the new public IP address
addrlenactual length of the addr

Definition at line 3182 of file gnunet-communicator-tcp.c.

3188 {
3189  char *my_addr;
3191 
3193  "nat address cb %s %s\n",
3194  add_remove ? "add" : "remove",
3195  GNUNET_a2s (addr, addrlen));
3196 
3197  if (GNUNET_YES == add_remove)
3198  {
3199  enum GNUNET_NetworkType nt;
3200 
3201  GNUNET_asprintf (&my_addr,
3202  "%s-%s",
3204  GNUNET_a2s (addr, addrlen));
3205  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3206  ai =
3208  my_addr,
3209  nt,
3211  GNUNET_free (my_addr);
3212  *app_ctx = ai;
3213  }
3214  else
3215  {
3216  ai = *app_ctx;
3218  *app_ctx = NULL;
3219  }
3220 }
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:36
void GNUNET_TRANSPORT_communicator_address_remove(struct GNUNET_TRANSPORT_AddressIdentifier *ai)
Notify transport service about an address that this communicator no longer provides for this peer.
struct GNUNET_TRANSPORT_AddressIdentifier * GNUNET_TRANSPORT_communicator_address_add(struct GNUNET_TRANSPORT_CommunicatorHandle *ch, const char *address, enum GNUNET_NetworkType nt, struct GNUNET_TIME_Relative expiration)
Notify transport service about an address that this communicator provides for this peer.
Internal representation of an address a communicator is currently providing for the transport service...

References ai, ch, COMMUNICATOR_ADDRESS_PREFIX, GNUNET_a2s(), GNUNET_asprintf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NT_scanner_get_type(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_communicator_address_add(), GNUNET_TRANSPORT_communicator_address_remove(), GNUNET_YES, is, and nt.

Referenced by nat_register().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_addr()

static void add_addr ( struct sockaddr *  in,
socklen_t  in_len 
)
static

This method adds addresses to the DLL, that are later register at the NAT service.

Definition at line 3227 of file gnunet-communicator-tcp.c.

3228 {
3229 
3230  struct Addresses *saddrs;
3231 
3233  "add address %s\n",
3234  GNUNET_a2s (in, in_len));
3235 
3236  saddrs = GNUNET_new (struct Addresses);
3237  saddrs->addr = in;
3238  saddrs->addr_len = in_len;
3240 
3242  "after add address %s\n",
3243  GNUNET_a2s (in, in_len));
3244 
3246  "add address %s\n",
3247  GNUNET_a2s (saddrs->addr, saddrs->addr_len));
3248 
3249  addrs_lens++;
3250 }
int addrs_lens
Number of addresses in the DLL for register at NAT service.
struct Addresses * addrs_head
Head of DLL with addresses we like to register at NAT servcie.
struct Addresses * addrs_tail
Head of DLL with addresses we like to register at NAT servcie.
DLL to store the addresses we like to register at NAT service.
struct sockaddr * addr
Address we like to register at NAT service.
socklen_t addr_len
Length of address we like to register at NAT service.

References Addresses::addr, Addresses::addr_len, addrs_head, addrs_lens, addrs_tail, GNUNET_a2s(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and GNUNET_new.

Referenced by init_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_socket()

static int init_socket ( struct sockaddr *  addr,
socklen_t  in_len 
)
static

This method launch network interactions for each address we like to bind to.

Parameters
addrThe address we will listen to.
in_lenThe length of the address we will listen to.
Returns
GNUNET_SYSERR in case of error. GNUNET_OK in case we are successfully listen to the address.

Definition at line 3261 of file gnunet-communicator-tcp.c.

3263 {
3264  struct sockaddr_storage in_sto;
3265  socklen_t sto_len;
3266  struct GNUNET_NETWORK_Handle *listen_sock;
3267  struct ListenTask *lt;
3268  int sockfd;
3269  struct GNUNET_HashCode h_sock;
3270 
3271  if (NULL == addr)
3272  {
3274  "Address is NULL.\n");
3275  return GNUNET_SYSERR;
3276  }
3277 
3279  "address %s\n",
3280  GNUNET_a2s (addr, in_len));
3281 
3282  listen_sock =
3283  GNUNET_NETWORK_socket_create (addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
3284  if (NULL == listen_sock)
3285  {
3287  return GNUNET_SYSERR;
3288  }
3289 
3290  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (listen_sock, addr, in_len))
3291  {
3293  GNUNET_NETWORK_socket_close (listen_sock);
3294  listen_sock = NULL;
3295  return GNUNET_SYSERR;
3296  }
3297 
3298  if (GNUNET_OK !=
3299  GNUNET_NETWORK_socket_listen (listen_sock,
3300  5))
3301  {
3303  "listen");
3304  GNUNET_NETWORK_socket_close (listen_sock);
3305  listen_sock = NULL;
3306  return GNUNET_SYSERR;
3307  }
3308 
3309  /* We might have bound to port 0, allowing the OS to figure it out;
3310  thus, get the real IN-address from the socket */
3311  sto_len = sizeof(in_sto);
3312 
3313  if (0 != getsockname (GNUNET_NETWORK_get_fd (listen_sock),
3314  (struct sockaddr *) &in_sto,
3315  &sto_len))
3316  {
3317  memcpy (&in_sto, addr, in_len);
3318  sto_len = in_len;
3319  }
3320 
3321  // addr = (struct sockaddr *) &in_sto;
3322  in_len = sto_len;
3324  "Bound to `%s'\n",
3325  GNUNET_a2s ((const struct sockaddr *) &in_sto, sto_len));
3326  stats = GNUNET_STATISTICS_create ("C-TCP", cfg);
3327 
3328  if (NULL == is)
3330 
3331  if (NULL == my_private_key)
3333  if (NULL == my_private_key)
3334  {
3335  GNUNET_log (
3337  _ (
3338  "Transport service is lacking key configuration settings. Exiting.\n"));
3339  if (NULL != resolve_request_handle)
3342  return GNUNET_SYSERR;
3343  }
3345  /* start listening */
3346 
3347  lt = GNUNET_new (struct ListenTask);
3348  lt->listen_sock = listen_sock;
3349 
3351  listen_sock,
3352  &listen_cb,
3353  lt);
3354 
3356  "creating hash\n");
3357  sockfd = GNUNET_NETWORK_get_fd (lt->listen_sock);
3358  GNUNET_CRYPTO_hash (&sockfd,
3359  sizeof(int),
3360  &h_sock);
3361 
3363  "creating map\n");
3364  if (NULL == lt_map)
3366 
3368  "creating map entry\n");
3371  &h_sock,
3372  lt,
3374 
3376  "map entry created\n");
3377 
3378  if (NULL == queue_map)
3380 
3381  if (NULL == ch)
3386  &mq_init,
3387  NULL,
3388  &enc_notify_cb,
3389  NULL);
3390 
3391  if (NULL == ch)
3392  {
3393  GNUNET_break (0);
3394  if (NULL != resolve_request_handle)
3397  return GNUNET_SYSERR;
3398  }
3399 
3400  add_addr (addr, in_len);
3401  return GNUNET_OK;
3402 
3403 }
static void enc_notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received an acknowledgement for this communicator (!...
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
static void add_addr(struct sockaddr *in, socklen_t in_len)
This method adds addresses to the DLL, that are later register at the NAT service.
struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration(const struct GNUNET_CONFIGURATION_Handle *cfg)
Create a new private key by reading our peer's key from the file specified in the configuration.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:197
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:656
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:412
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:533
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls)
Connect to the transport service.
@ GNUNET_TRANSPORT_CC_RELIABLE
Transmission is reliabile (with ACKs), e.g.
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References _, add_addr(), cfg, ch, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, enc_notify_cb(), GNUNET_a2s(), GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_create(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_listen(), GNUNET_new, GNUNET_NO, GNUNET_NT_scanner_init(), GNUNET_OK, GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_shutdown(), GNUNET_STATISTICS_create(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_CC_RELIABLE, GNUNET_TRANSPORT_communicator_connect(), is, listen_cb(), ListenTask::listen_sock, ListenTask::listen_task, lt_map, mq_init(), my_identity, my_private_key, GNUNET_PeerIdentity::public_key, queue_map, resolve_request_handle, and stats.

Referenced by init_socket_resolv(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nat_register()

static void nat_register ( )
static

This method reads from the DLL addrs_head to register them at the NAT service.

Definition at line 3410 of file gnunet-communicator-tcp.c.

3411 {
3412  struct sockaddr **saddrs;
3413  socklen_t *saddr_lens;
3414  int i;
3415  size_t len;
3416 
3418  "starting nat register!\n");
3419  len = 0;
3420  i = 0;
3421  saddrs = GNUNET_malloc ((addrs_lens) * sizeof(struct sockaddr *));
3422  saddr_lens = GNUNET_malloc ((addrs_lens) * sizeof(socklen_t));
3423  for (struct Addresses *pos = addrs_head; NULL != pos; pos = pos->next)
3424  {
3426  "registering address %s\n",
3428 
3429  saddr_lens[i] = addrs_head->addr_len;
3430  len += saddr_lens[i];
3431  saddrs[i] = GNUNET_memdup (addrs_head->addr, saddr_lens[i]);
3432  i++;
3433  }
3434 
3436  "registering addresses %lu %lu %lu %lu\n",
3437  (addrs_lens) * sizeof(struct sockaddr *),
3438  (addrs_lens) * sizeof(socklen_t),
3439  len,
3440  sizeof(COMMUNICATOR_CONFIG_SECTION));
3443  IPPROTO_TCP,
3444  addrs_lens,
3445  (const struct sockaddr **) saddrs,
3446  saddr_lens,
3447  &nat_address_cb,
3448  NULL /* FIXME: support reversal: #5529 */,
3449  NULL /* closure */);
3450  for (i = addrs_lens - 1; i >= 0; i--)
3451  GNUNET_free (saddrs[i]);
3452  GNUNET_free (saddrs);
3453  GNUNET_free (saddr_lens);
3454 
3455  if (NULL == nat)
3456  {
3457  GNUNET_break (0);
3458  if (NULL != resolve_request_handle)
3461  }
3462 }
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:386
struct Addresses * next
Kept in a DLL.

References Addresses::addr, Addresses::addr_len, addrs_head, addrs_lens, cfg, COMMUNICATOR_CONFIG_SECTION, GNUNET_a2s(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memdup, GNUNET_NAT_register(), GNUNET_RESOLVER_request_cancel(), GNUNET_SCHEDULER_shutdown(), len, nat, nat_address_cb(), Addresses::next, and resolve_request_handle.

Referenced by init_socket_resolv(), and run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_socket_resolv()

static void init_socket_resolv ( void *  cls,
const struct sockaddr *  addr,
socklen_t  in_len 
)
static

This method is the callback called by the resolver API, and wraps method init_socket.

Parameters
clsThe port we will bind to.
addrThe address we will bind to.
in_lenThe length of the address we will bind to.

Definition at line 3473 of file gnunet-communicator-tcp.c.

3476 {
3477  struct sockaddr_in *v4;
3478  struct sockaddr_in6 *v6;
3479  struct sockaddr *in;
3480 
3481  (void) cls;
3482  if (NULL != addr)
3483  {
3484  if (AF_INET == addr->sa_family)
3485  {
3486  v4 = (struct sockaddr_in *) addr;
3487  in = tcp_address_to_sockaddr_numeric_v4 (&in_len, *v4, bind_port);// _global);
3488  }
3489  else if (AF_INET6 == addr->sa_family)
3490  {
3491  v6 = (struct sockaddr_in6 *) addr;
3492  in = tcp_address_to_sockaddr_numeric_v6 (&in_len, *v6, bind_port);// _global);
3493  }
3494  else
3495  {
3497  "Address family %u not suitable (not AF_INET %u nor AF_INET6 %u \n",
3498  addr->sa_family,
3499  AF_INET,
3500  AF_INET6);
3501  return;
3502  }
3503  init_socket (in, in_len);
3504  }
3505  else
3506  {
3508  "Address is NULL. This might be an error or the resolver finished resolving.\n");
3509  if (NULL == addrs_head)
3510  {
3512  "Resolver finished resolving, but we do not listen to an address!.\n");
3513  return;
3514  }
3515  nat_register ();
3516  }
3517 }
unsigned int bind_port
The port the communicator should be assigned to.
static int init_socket(struct sockaddr *addr, socklen_t in_len)
This method launch network interactions for each address we like to bind to.
static void nat_register()
This method reads from the DLL addrs_head to register them at the NAT service.

References addrs_head, bind_port, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, init_socket(), nat_register(), tcp_address_to_sockaddr_numeric_v4(), and tcp_address_to_sockaddr_numeric_v6().

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle c 
)
static

Setup communicator and launch network interactions.

Parameters
clsNULL (always)
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL!)
cconfiguration

Definition at line 3529 of file gnunet-communicator-tcp.c.

3533 {
3534  char *bindto;
3535  struct sockaddr *in;
3536  socklen_t in_len;
3537  struct sockaddr_in v4;
3538  struct sockaddr_in6 v6;
3539  char *start;
3540  unsigned int port;
3541  char dummy[2];
3542  char *rest = NULL;
3543  struct PortOnlyIpv4Ipv6 *po;
3544  socklen_t addr_len_ipv4;
3545  socklen_t addr_len_ipv6;
3546 
3547  (void) cls;
3548  cfg = c;
3549  if (GNUNET_OK !=
3552  "BINDTO",
3553  &bindto))
3554  {
3557  "BINDTO");
3558  return;
3559  }
3560  if (GNUNET_OK !=
3563  "MAX_QUEUE_LENGTH",
3564  &max_queue_length))
3566  if (GNUNET_OK !=
3569  "REKEY_INTERVAL",
3570  &rekey_interval))
3572 
3574  if (NULL == peerstore)
3575  {
3576  GNUNET_free (bindto);
3577  GNUNET_break (0);
3579  return;
3580  }
3581 
3583 
3584  if (1 == sscanf (bindto, "%u%1s", &bind_port, dummy))
3585  {
3589  "address po %s\n",
3591  if (NULL != po->addr_ipv4)
3592  {
3594  }
3595  if (NULL != po->addr_ipv6)
3596  {
3599  }
3600  GNUNET_free (po);
3601  nat_register ();
3602  GNUNET_free (bindto);
3603  return;
3604  }
3605 
3606  start = extract_address (bindto);
3607  // FIXME: check for NULL == start...
3608  if (1 == inet_pton (AF_INET, start, &v4.sin_addr))
3609  {
3610  bind_port = extract_port (bindto);
3611 
3612  in = tcp_address_to_sockaddr_numeric_v4 (&in_len, v4, bind_port);
3613  init_socket (in, in_len);
3614  nat_register ();
3615  GNUNET_free (start);
3616  GNUNET_free (bindto);
3617  return;
3618  }
3619 
3620  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
3621  {
3622  bind_port = extract_port (bindto);
3623  in = tcp_address_to_sockaddr_numeric_v6 (&in_len, v6, bind_port);
3624  init_socket (in, in_len);
3625  nat_register ();
3626  GNUNET_free (start);
3627  GNUNET_free (bindto);
3628  return;
3629  }
3630 
3631  bind_port = extract_port (bindto);
3632  resolve_request_handle = GNUNET_RESOLVER_ip_get (strtok_r (bindto,
3633  ":",
3634  &rest),
3635  AF_UNSPEC,
3638  &port);
3639  GNUNET_free (bindto);
3640  GNUNET_free (start);
3641 }
static struct PortOnlyIpv4Ipv6 * tcp_address_to_sockaddr_port_only(const char *bindto, unsigned int *port)
Convert TCP bind specification to a struct PortOnlyIpv4Ipv6 *
static void do_shutdown(void *cls)
Shutdown the UNIX communicator.
static void init_socket_resolv(void *cls, const struct sockaddr *addr, socklen_t in_len)
This method is the callback called by the resolver API, and wraps method init_socket.
#define DEFAULT_REKEY_INTERVAL
How often do we rekey based on time (at least)
#define DEFAULT_MAX_QUEUE_LENGTH
How many messages do we keep at most in the queue to the transport service before we start to drop (d...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
struct GNUNET_RESOLVER_RequestHandle * GNUNET_RESOLVER_ip_get(const char *hostname, int af, struct GNUNET_TIME_Relative timeout, GNUNET_RESOLVER_AddressCallback callback, void *callback_cls)
Convert a string to one or more IP addresses.
Definition: resolver_api.c:939
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1316
#define GNUNET_TIME_UNIT_MINUTES
One minute.

References PortOnlyIpv4Ipv6::addr_ipv4, PortOnlyIpv4Ipv6::addr_ipv6, PortOnlyIpv4Ipv6::addr_len_ipv4, PortOnlyIpv4Ipv6::addr_len_ipv6, bind_port, cfg, COMMUNICATOR_CONFIG_SECTION, DEFAULT_MAX_QUEUE_LENGTH, DEFAULT_REKEY_INTERVAL, do_shutdown(), dummy, extract_address(), extract_port(), GNUNET_a2s(), GNUNET_break, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_OK, GNUNET_PEERSTORE_connect(), GNUNET_RESOLVER_ip_get(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_TIME_UNIT_MINUTES, init_socket(), init_socket_resolv(), max_queue_length, nat_register(), peerstore, port, rekey_interval, resolve_request_handle, start, tcp_address_to_sockaddr_numeric_v4(), tcp_address_to_sockaddr_numeric_v6(), and tcp_address_to_sockaddr_port_only().

Here is the call graph for this function:

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function for the UNIX communicator.

Parameters
argcnumber of arguments from the command line
argvcommand line arguments
Returns
0 ok, 1 on error

Definition at line 3652 of file gnunet-communicator-tcp.c.

3653 {
3654  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3656  };
3657  int ret;
3658 
3660  "transport",
3661  "Starting tcp communicator\n");
3662  if (GNUNET_OK !=
3663  GNUNET_STRINGS_get_utf8_args (argc, argv,
3664  &argc, &argv))
3665  return 2;
3666 
3667  ret = (GNUNET_OK ==
3668  GNUNET_PROGRAM_run (argc,
3669  argv,
3670  "gnunet-communicator-tcp",
3671  _ ("GNUnet TCP communicator"),
3672  options,
3673  &run,
3674  NULL))
3675  ? 0
3676  : 1;
3677  GNUNET_free_nz ((void *) argv);
3678  return ret;
3679 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:399
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1223
Definition of a command line option.

Variable Documentation

◆ max_queue_length

unsigned long long max_queue_length
static

Maximum queue length before we stop reading towards the transport service.

Definition at line 745 of file gnunet-communicator-tcp.c.

Referenced by queue_read(), and run().

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

◆ ch

◆ queue_map

struct GNUNET_CONTAINER_MultiPeerMap* queue_map
static

Queues (map from peer identity to struct Queue)

Definition at line 760 of file gnunet-communicator-tcp.c.

Referenced by boot_queue(), do_shutdown(), init_socket(), and queue_destroy().

◆ lt_map

struct GNUNET_CONTAINER_MultiHashMap* lt_map
static

ListenTasks (map from socket to struct ListenTask)

Definition at line 765 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), init_socket(), and queue_destroy().

◆ my_identity

struct GNUNET_PeerIdentity my_identity
static

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

The rekey interval.

Definition at line 765 of file gnunet-communicator-tcp.c.

Referenced by run(), and setup_out_cipher().

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

Our private key.

Definition at line 780 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), init_socket(), inject_rekey(), send_challenge(), setup_in_cipher(), and transmit_kx().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

◆ is

struct GNUNET_NT_InterfaceScanner* is
static

◆ nat

struct GNUNET_NAT_Handle* nat
static

Connection to NAT service.

Definition at line 795 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), and nat_register().

◆ proto_head

struct ProtoQueue* proto_head
static

Protoqueues DLL head.

Definition at line 800 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), free_proto_queue(), listen_cb(), and proto_read_kx().

◆ proto_tail

struct ProtoQueue* proto_tail
static

Protoqueues DLL tail.

Definition at line 805 of file gnunet-communicator-tcp.c.

Referenced by free_proto_queue(), listen_cb(), and proto_read_kx().

◆ resolve_request_handle

struct GNUNET_RESOLVER_RequestHandle* resolve_request_handle

Handle for DNS lookup of bindto address.

Definition at line 810 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), init_socket(), nat_register(), and run().

◆ addrs_head

struct Addresses* addrs_head

Head of DLL with addresses we like to register at NAT servcie.

Definition at line 815 of file gnunet-communicator-tcp.c.

Referenced by add_addr(), init_socket_resolv(), and nat_register().

◆ addrs_tail

struct Addresses* addrs_tail

Head of DLL with addresses we like to register at NAT servcie.

Definition at line 820 of file gnunet-communicator-tcp.c.

Referenced by add_addr().

◆ lts_head

struct ListenTask* lts_head

Head of DLL with ListenTasks.

Definition at line 825 of file gnunet-communicator-tcp.c.

◆ lts_tail

struct ListenTask* lts_tail

Head of DLL with ListenTask.

Definition at line 830 of file gnunet-communicator-tcp.c.

◆ addrs_lens

int addrs_lens

Number of addresses in the DLL for register at NAT service.

Definition at line 835 of file gnunet-communicator-tcp.c.

Referenced by add_addr(), and nat_register().

◆ unverified_size

size_t unverified_size

Size of data received without KX challenge played back.

Definition at line 841 of file gnunet-communicator-tcp.c.

Referenced by try_handle_plaintext().

◆ peerstore

struct GNUNET_PEERSTORE_Handle* peerstore
static

◆ shutdown_running

int shutdown_running = GNUNET_NO

A flag indicating we are already doing a shutdown.

Definition at line 851 of file gnunet-communicator-tcp.c.

Referenced by do_shutdown(), and queue_destroy().

◆ bind_port

unsigned int bind_port

The port the communicator should be assigned to.

Definition at line 856 of file gnunet-communicator-tcp.c.

Referenced by init_socket_resolv(), and run().