GNUnet  0.20.0
gnunet-communicator-quic.c File Reference

Transport plugin using QUIC. More...

#include "gnunet_common.h"
#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
#include "quiche.h"
#include "platform.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_constants.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_application_service.h"
#include "gnunet_transport_communication_service.h"
#include "gnunet_nt_lib.h"
#include "gnunet_nat_service.h"
#include "stdint.h"
#include "inttypes.h"
Include dependency graph for gnunet-communicator-quic.c:

Go to the source code of this file.

Data Structures

struct  PeerAddress
 Information we track per peer we have recently been in contact with. More...
 
struct  quic_conn
 QUIC connection object. More...
 
struct  QUIC_header
 QUIC_header is used to store information received from an incoming QUIC packet. More...
 

Macros

#define COMMUNICATOR_CONFIG_SECTION   "communicator-quic"
 
#define COMMUNICATOR_ADDRESS_PREFIX   "quic"
 
#define MAX_DATAGRAM_SIZE   1350
 
#define LOCAL_CONN_ID_LEN   20
 
#define MAX_TOKEN_LEN
 
#define CID_LEN   sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN
 
#define TOKEN_LEN   sizeof (uint8_t) * MAX_TOKEN_LEN
 
#define STREAMID_BI   4
 
#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS
 How long do we believe our addresses to remain up (before the other peer should revalidate). More...
 

Functions

static void recv_from_streams (struct PeerAddress *peer)
 Given a PeerAddress, receive data from streams after doing connection logic. More...
 
static void mint_token (const uint8_t *dcid, size_t dcid_len, struct sockaddr_storage *addr, socklen_t addr_len, uint8_t *token, size_t *token_len)
 FIXME: review token generation, assure tokens are generated properly. More...
 
static enum GNUNET_GenericReturnValue validate_token (const uint8_t *token, size_t token_len, struct sockaddr_storage *addr, socklen_t addr_len, uint8_t *odcid, size_t *odcid_len)
 
static struct quic_conncreate_conn (uint8_t *scid, size_t scid_len, uint8_t *odcid, size_t odcid_len, struct sockaddr *local_addr, socklen_t local_addr_len, struct sockaddr_storage *peer_addr, socklen_t peer_addr_len)
 
static void flush_egress (struct quic_conn *conn)
 
static void reschedule_peer_timeout (struct PeerAddress *peer)
 Increment receiver timeout due to activity. More...
 
static void peer_destroy (struct PeerAddress *peer)
 Destroys a receiving state due to timeout or shutdown. More...
 
static int get_peer_delete_it (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over all peers to clean up. More...
 
static void mq_send_d (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_d (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 struct sockaddr * udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr * More...
 
static void setup_peer_mq (struct PeerAddress *peer)
 Setup the MQ for the peer. More...
 
static char * sockaddr_to_udpaddr_string (const struct sockaddr *address, socklen_t address_len)
 Taken from: UDP communicator Converts address to the address string format used by this communicator in HELLOs. More...
 
static void notify_cb (void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
 Function called when the transport service has received a backchannel message for this communicator (!) via a different return path. More...
 
static void check_timeouts (void *cls)
 Task run to check #receiver_heap and #sender_heap for timeouts. More...
 
static int mq_init (void *cls, const struct GNUNET_PeerIdentity *peer_id, const char *address)
 Function called by the transport service to initialize a message queue given address information about another peer. More...
 
static void try_connection_reversal (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 
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 do_shutdown (void *cls)
 Shutdown the QUIC communicator. More...
 
static void sock_read (void *cls)
 
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)
 

Variables

struct GNUNET_CONTAINER_MultiHashMapconn_map
 Map of DCID (uint8_t) -> quic_conn for quickly retrieving connections to other peers. More...
 
struct GNUNET_CONTAINER_MultiHashMapaddr_map
 Map of sockaddr -> struct PeerAddress. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Handle to the config. More...
 
static struct GNUNET_TIME_Relative rekey_interval
 FIXME undocumented. More...
 
static struct GNUNET_NETWORK_Handleudp_sock
 FIXME undocumented. More...
 
static struct GNUNET_SCHEDULER_Taskread_task
 FIXME undocumented. More...
 
static struct GNUNET_TRANSPORT_CommunicatorHandlech
 FIXME undocumented. More...
 
static struct GNUNET_TRANSPORT_ApplicationHandleah
 FIXME undocumented. More...
 
static int have_v6_socket
 FIXME undocumented. More...
 
static uint16_t my_port
 FIXME undocumented. More...
 
static unsigned long long rekey_max_bytes
 FIXME undocumented. More...
 
static quiche_config * config = NULL
 FIXME undocumented. More...
 
struct GNUNET_PeerIdentity my_identity
 Our peer identity. More...
 
static struct GNUNET_CRYPTO_EddsaPrivateKeymy_private_key
 Our private key. More...
 
static struct GNUNET_NAT_Handlenat
 Connection to NAT service. More...
 
static struct GNUNET_SCHEDULER_Tasktimeout_task
 ID of timeout task. More...
 
static struct GNUNET_NT_InterfaceScanneris
 Network scanner to determine network types. More...
 
static struct GNUNET_STATISTICS_Handlestats
 For logging statistics. More...
 

Detailed Description

Transport plugin using QUIC.

Author
Marshall Stone
Martin Schanzenbach

TODO:

  • Automatically generate self-signed x509 certificates and load from config
  • Figure out MTU and how we have to handle fragmentation in Quiche.
  • Mandate timeouts
  • Setup stats handler properly
  • Doxygen documentation of methods
  • Refactor code shared with UDP and TCP communicator
  • Performance testing
  • Check for memory leaks with coverity/valgrind

Definition in file gnunet-communicator-quic.c.

Macro Definition Documentation

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-quic"

Definition at line 53 of file gnunet-communicator-quic.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "quic"

Definition at line 54 of file gnunet-communicator-quic.c.

◆ MAX_DATAGRAM_SIZE

#define MAX_DATAGRAM_SIZE   1350

Definition at line 55 of file gnunet-communicator-quic.c.

◆ LOCAL_CONN_ID_LEN

#define LOCAL_CONN_ID_LEN   20

Definition at line 60 of file gnunet-communicator-quic.c.

◆ MAX_TOKEN_LEN

#define MAX_TOKEN_LEN
Value:
sizeof("quiche") - 1 \
+ sizeof(struct sockaddr_storage) \
+ QUICHE_MAX_CONN_ID_LEN

Definition at line 61 of file gnunet-communicator-quic.c.

◆ CID_LEN

#define CID_LEN   sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN

Definition at line 65 of file gnunet-communicator-quic.c.

◆ TOKEN_LEN

#define TOKEN_LEN   sizeof (uint8_t) * MAX_TOKEN_LEN

Definition at line 66 of file gnunet-communicator-quic.c.

◆ STREAMID_BI

#define STREAMID_BI   4

Definition at line 71 of file gnunet-communicator-quic.c.

◆ ADDRESS_VALIDITY_PERIOD

#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS

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

Definition at line 77 of file gnunet-communicator-quic.c.

Function Documentation

◆ recv_from_streams()

static void recv_from_streams ( struct PeerAddress peer)
static

Given a PeerAddress, receive data from streams after doing connection logic.

ASSUMES: connection is established to peer

FIXME: Do not use implicit booleans. Use GNUNET_YES, GNUNET_NO, GNUNET_SYSERR and check for that.

Initial packet should contain peerid if they are the initiator

Parse messages to pass to communicator

Check for leftover bytes

FIXME: comment useless fin

Definition at line 303 of file gnunet-communicator-quic.c.

304 {
305  char stream_buf[UINT16_MAX];
306  size_t buf_size = UINT16_MAX;
307  char *buf_ptr = stream_buf;
308  struct GNUNET_MessageHeader *hdr;
309 
310  uint64_t s = 0;
311  quiche_stream_iter *readable;
312  bool fin;
313  ssize_t recv_len;
314 
315  readable = quiche_conn_readable (peer->conn->conn);
316  while (quiche_stream_iter_next (readable, &s))
317  {
318  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "stream %" PRIu64 " is readable\n",
319  s);
320  fin = false;
321  recv_len = quiche_conn_stream_recv (peer->conn->conn, s,
322  (uint8_t *) stream_buf, buf_size,
323  &fin);
324  if (recv_len < 0)
325  {
327  "error while receiving data from stream %" PRIu64 "\n", s);
328  break;
329  }
336  if (! peer->is_receiver && GNUNET_NO == peer->id_rcvd)
337  {
338  if (recv_len < sizeof(struct GNUNET_PeerIdentity))
339  {
341  "message recv len of %zd less than length of peer identity\n",
342  recv_len);
343  return;
344  }
346  "received peer identity\n");
347  struct GNUNET_PeerIdentity *pid = (struct
348  GNUNET_PeerIdentity *) stream_buf;
349  peer->target = *pid;
350  peer->id_rcvd = GNUNET_YES;
351  buf_ptr += sizeof(struct GNUNET_PeerIdentity);
352  recv_len -= sizeof(struct GNUNET_PeerIdentity);
353  }
357  while (recv_len >= sizeof(struct GNUNET_MessageHeader))
358  {
359  hdr = (struct GNUNET_MessageHeader *) buf_ptr;
360  if (ntohs (hdr->size) > recv_len)
361  {
363  "message size stated (%d) is greater than length of rcvd data (%zd)!\n",
364  ntohs (hdr->size), recv_len);
365  return;
366  }
367  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "passing %zd bytes to core\n",
368  recv_len);
371  NULL);
372  recv_len -= ntohs (hdr->size);
373  buf_ptr += ntohs (hdr->size);
374  }
378  if (0 != recv_len)
379  {
381  "message recv len of %zd less than length of message header\n",
382  recv_len);
383  }
388  if (fin)
389  {
391  "fin received, closing connection\n");
392  if (0 > quiche_conn_close (peer->conn->conn, true, 0, NULL, 0))
393  {
395  "quiche failed to close connection to peer\n");
396  }
397  }
398  }
399  quiche_stream_iter_free (readable);
400 }
#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
FIXME undocumented.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
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.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.

References ADDRESS_VALIDITY_PERIOD, ch, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_TRANSPORT_communicator_receive(), GNUNET_YES, peer, pid, and GNUNET_MessageHeader::size.

Referenced by sock_read().

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

◆ mint_token()

static void mint_token ( const uint8_t *  dcid,
size_t  dcid_len,
struct sockaddr_storage *  addr,
socklen_t  addr_len,
uint8_t *  token,
size_t *  token_len 
)
static

FIXME: review token generation, assure tokens are generated properly.

doxygen

Definition at line 407 of file gnunet-communicator-quic.c.

410 {
411  GNUNET_memcpy (token, "quiche", sizeof("quiche") - 1);
412  GNUNET_memcpy (token + sizeof("quiche") - 1, addr, addr_len);
413  GNUNET_memcpy (token + sizeof("quiche") - 1 + addr_len, dcid, dcid_len);
414 
415  *token_len = sizeof("quiche") - 1 + addr_len + dcid_len;
416 }
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.

References GNUNET_memcpy.

Referenced by sock_read().

Here is the caller graph for this function:

◆ validate_token()

static enum GNUNET_GenericReturnValue validate_token ( const uint8_t *  token,
size_t  token_len,
struct sockaddr_storage *  addr,
socklen_t  addr_len,
uint8_t *  odcid,
size_t *  odcid_len 
)
static

Definition at line 407 of file gnunet-communicator-quic.c.

423 {
424  if ((token_len < sizeof("quiche") - 1) ||
425  memcmp (token, "quiche", sizeof("quiche") - 1))
426  {
427  return GNUNET_NO;
428  }
429 
430  token += sizeof("quiche") - 1;
431  token_len -= sizeof("quiche") - 1;
432 
433  if ((token_len < addr_len) || memcmp (token, addr, addr_len))
434  {
435  return GNUNET_NO;
436  }
437 
438  token += addr_len;
439  token_len -= addr_len;
440 
441  if (*odcid_len < token_len)
442  {
443  return GNUNET_NO;
444  }
445 
446  memcpy (odcid, token, token_len);
447  *odcid_len = token_len;
448 
449  return GNUNET_OK;
450 }
@ GNUNET_OK

Referenced by sock_read().

Here is the caller graph for this function:

◆ create_conn()

static struct quic_conn* create_conn ( uint8_t *  scid,
size_t  scid_len,
uint8_t *  odcid,
size_t  odcid_len,
struct sockaddr *  local_addr,
socklen_t  local_addr_len,
struct sockaddr_storage *  peer_addr,
socklen_t  peer_addr_len 
)
static

Definition at line 454 of file gnunet-communicator-quic.c.

460 {
461  struct quic_conn *conn;
462  quiche_conn *q_conn;
463  conn = GNUNET_new (struct quic_conn);
464  if (scid_len != LOCAL_CONN_ID_LEN)
465  {
467  "error while creating connection, scid length too short: %zu\n",
468  scid_len);
469  return NULL;
470  }
471 
472  GNUNET_memcpy (conn->cid, scid, LOCAL_CONN_ID_LEN);
473  q_conn = quiche_accept (conn->cid, LOCAL_CONN_ID_LEN,
474  odcid, odcid_len,
475  local_addr,
476  local_addr_len,
477  (struct sockaddr *) peer_addr,
478  peer_addr_len,
479  config);
480  if (NULL == q_conn)
481  {
483  "quiche failed to create connection after call to quiche_accept\n");
484  return NULL;
485  }
486  conn->conn = q_conn;
487  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new quic connection created\n");
488  return conn;
489 }
#define LOCAL_CONN_ID_LEN
static quiche_config * config
FIXME undocumented.
static char * local_addr
Local address to use for connection reversal request.
Definition: gnunet-nat.c:65
#define GNUNET_new(type)
Allocate a struct or union of the given type.
QUIC connection object.
quiche_conn * conn

References config, quic_conn::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_memcpy, GNUNET_new, local_addr, and LOCAL_CONN_ID_LEN.

Referenced by sock_read().

Here is the caller graph for this function:

◆ flush_egress()

static void flush_egress ( struct quic_conn conn)
static

Definition at line 493 of file gnunet-communicator-quic.c.

494 {
495  static uint8_t out[MAX_DATAGRAM_SIZE];
496  quiche_send_info send_info;
497 
498  ssize_t written;
499  ssize_t sent;
500 
501  while (1)
502  {
503  written = quiche_conn_send (conn->conn, out, sizeof(out), &send_info);
504  if (QUICHE_ERR_DONE == written)
505  {
506  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done writing quic packets\n");
507  break;
508  }
509  if (0 > written)
510  {
512  "quiche failed to create packet. quiche error: %zd\n",
513  written);
514  return;
515  }
516  sent = GNUNET_NETWORK_socket_sendto (udp_sock, out, written,
517  (struct sockaddr *) &send_info.to,
518  send_info.to_len);
519  if (sent != written)
520  {
522  "quiche failed to send data to peer\n");
523  return;
524  }
525  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
526  }
527 }
static struct GNUNET_NETWORK_Handle * udp_sock
FIXME undocumented.
#define MAX_DATAGRAM_SIZE
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772

References quic_conn::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NETWORK_socket_sendto(), MAX_DATAGRAM_SIZE, and udp_sock.

Referenced by mq_init(), mq_send_d(), and sock_read().

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

◆ reschedule_peer_timeout()

static void reschedule_peer_timeout ( struct PeerAddress peer)
static

Increment receiver timeout due to activity.

Parameters
receiveraddress for which the timeout should be rescheduled

Definition at line 536 of file gnunet-communicator-quic.c.

537 {
538  peer->timeout =
540  // GNUNET_CONTAINER_heap_update_cost (peer->hn,
541  // peer->timeout.abs_value_us);
542 }
#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?
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:316

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_TIME_relative_to_absolute(), and peer.

Referenced by mq_send_d().

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

◆ peer_destroy()

static void peer_destroy ( struct PeerAddress peer)
static

Destroys a receiving state due to timeout or shutdown.

Parameters
receiverentity to close down

Remove peer from hashmap

Definition at line 551 of file gnunet-communicator-quic.c.

552 {
553  struct GNUNET_HashCode addr_key;
554 
555  peer->peer_destroy_called = GNUNET_YES;
557  "Disconnecting peer for peer `%s'\n",
558  GNUNET_i2s (&peer->target));
559  if (NULL != peer->d_qh)
560  {
562  peer->d_qh = NULL;
563  }
564  // GNUNET_assert (peer == GNUNET_CONTAINER_heap_remove_node (peer->hn));
568  GNUNET_CRYPTO_hash (peer->address, peer->address_len, &addr_key);
570  peer))
571  {
573  "tried to remove non-existent peer from addr map\n");
574  return;
575  }
577  "# peers active",
579  GNUNET_NO);
580  quiche_conn_free (peer->conn->conn);
581  GNUNET_free (peer->address);
582  GNUNET_free (peer->foreign_addr);
583  GNUNET_free (peer->conn);
584  GNUNET_free (peer);
585 }
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
struct GNUNET_CONTAINER_MultiHashMap * addr_map
Map of sockaddr -> struct PeerAddress.
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.
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
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *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).
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
A 512-bit hashcode.

References addr_map, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_TRANSPORT_communicator_mq_del(), GNUNET_YES, peer, and stats.

Referenced by get_peer_delete_it(), mq_destroy_d(), mq_error(), mq_send_d(), and sock_read().

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

◆ get_peer_delete_it()

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

Iterator over all peers to clean up.

Parameters
clsNULL
keypeer->address
valuethe peer to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 597 of file gnunet-communicator-quic.c.

600 {
601  struct PeerAddress *peer = value;
602  (void) cls;
603  (void) key;
604  peer_destroy (peer);
605  return GNUNET_OK;
606 }
static void peer_destroy(struct PeerAddress *peer)
Destroys a receiving state due to timeout or shutdown.
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
Information we track per peer we have recently been in contact with.

References GNUNET_OK, key, peer, peer_destroy(), and value.

Referenced by do_shutdown().

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

◆ mq_send_d()

static void mq_send_d ( 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 PeerAddress

Definition at line 618 of file gnunet-communicator-quic.c.

621 {
622  struct PeerAddress *peer = impl_state;
623  uint16_t msize = ntohs (msg->size);
624  ssize_t send_len;
625 
626  if (NULL == peer->conn->conn)
627  {
629  "peer never established quic connection\n");
630  return;
631  }
632 
633  GNUNET_assert (mq == peer->d_mq);
634  if (msize > peer->d_mtu)
635  {
637  "msize: %u, mtu: %lu\n",
638  msize,
639  peer->d_mtu);
640  GNUNET_break (0);
641  if (GNUNET_YES != peer->peer_destroy_called)
642  {
644  "peer destroy called, destroying peer\n");
645  peer_destroy (peer);
646  }
647  return;
648  }
650 
651  send_len = quiche_conn_stream_send (peer->conn->conn, 4, (uint8_t *) msg,
652  msize, false);
653  if (send_len != msize)
654  {
656  "tried to send message and quiche returned %zd", send_len);
657  return;
658  }
659  flush_egress (peer->conn);
661  "sent a message of %zd bytes\n", send_len);
663 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void flush_egress(struct quic_conn *conn)
static void reschedule_peer_timeout(struct PeerAddress *peer)
Increment receiver timeout due to activity.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
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:421

References flush_egress(), GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_MQ_impl_send_continue(), GNUNET_YES, mq, msg, peer, peer_destroy(), reschedule_peer_timeout(), and GNUNET_MessageHeader::size.

Referenced by setup_peer_mq().

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

◆ mq_destroy_d()

static void mq_destroy_d ( 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 PeerAddress

Definition at line 675 of file gnunet-communicator-quic.c.

676 {
677  struct PeerAddress *peer = impl_state;
679  "Default MQ destroyed\n");
680  if (mq == peer->d_mq)
681  {
682  peer->d_mq = NULL;
683  if (GNUNET_YES != peer->peer_destroy_called)
684  peer_destroy (peer);
685  }
686 }

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, mq, peer, and peer_destroy().

Referenced by setup_peer_mq().

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 PeerAddress

Definition at line 696 of file gnunet-communicator-quic.c.

697 {
698  /* Cancellation is impossible with QUIC; bail */
699  GNUNET_assert (0);
700 }

References GNUNET_assert.

Referenced by setup_peer_mq().

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 ReceiverAddress
errorerror code

Definition at line 713 of file gnunet-communicator-quic.c.

714 {
715  struct PeerAddress *peer = cls;
716 
718  "MQ error in queue to %s: %d\n",
719  GNUNET_i2s (&peer->target),
720  (int) error);
721  peer_destroy (peer);
722 }

References GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, peer, and peer_destroy().

Referenced by setup_peer_mq().

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

◆ udp_address_to_sockaddr()

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

Convert UDP 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 733 of file gnunet-communicator-quic.c.

734 {
735  struct sockaddr *in;
736  unsigned int port;
737  char dummy[2];
738  char *colon;
739  char *cp;
740 
741  if (1 == sscanf (bindto, "%u%1s", &port, dummy))
742  {
743  /* interpreting value as just a PORT number */
744  if (port > UINT16_MAX)
745  {
747  "BINDTO specification `%s' invalid: value too large for port\n",
748  bindto);
749  return NULL;
750  }
751  if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
752  (GNUNET_YES ==
755  "DISABLE_V6")))
756  {
757  struct sockaddr_in *i4;
758 
759  i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
760  i4->sin_family = AF_INET;
761  i4->sin_port = htons ((uint16_t) port);
762  *sock_len = sizeof(struct sockaddr_in);
763  in = (struct sockaddr *) i4;
764  }
765  else
766  {
767  struct sockaddr_in6 *i6;
768 
769  i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
770  i6->sin6_family = AF_INET6;
771  i6->sin6_port = htons ((uint16_t) port);
772  *sock_len = sizeof(struct sockaddr_in6);
773  in = (struct sockaddr *) i6;
774  }
775  return in;
776  }
777  cp = GNUNET_strdup (bindto);
778  colon = strrchr (cp, ':');
779  if (NULL != colon)
780  {
781  /* interpret value after colon as port */
782  *colon = '\0';
783  colon++;
784  if (1 == sscanf (colon, "%u%1s", &port, dummy))
785  {
786  /* interpreting value as just a PORT number */
787  if (port > UINT16_MAX)
788  {
790  "BINDTO specification `%s' invalid: value too large for port\n",
791  bindto);
792  GNUNET_free (cp);
793  return NULL;
794  }
795  }
796  else
797  {
798  GNUNET_log (
800  "BINDTO specification `%s' invalid: last ':' not followed by number\n",
801  bindto);
802  GNUNET_free (cp);
803  return NULL;
804  }
805  }
806  else
807  {
808  /* interpret missing port as 0, aka pick any free one */
809  port = 0;
810  }
811  {
812  /* try IPv4 */
813  struct sockaddr_in v4;
814 
815  memset (&v4, 0, sizeof(v4));
816  if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
817  {
818  v4.sin_family = AF_INET;
819  v4.sin_port = htons ((uint16_t) port);
820 #if HAVE_SOCKADDR_IN_SIN_LEN
821  v4.sin_len = sizeof(struct sockaddr_in);
822 #endif
823  in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
824  *sock_len = sizeof(struct sockaddr_in);
825  GNUNET_free (cp);
826  return in;
827  }
828  }
829  {
830  /* try IPv6 */
831  struct sockaddr_in6 v6;
832  const char *start;
833 
834  memset (&v6, 0, sizeof(v6));
835  start = cp;
836  if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
837  {
838  start++; /* skip over '[' */
839  cp[strlen (cp) - 1] = '\0'; /* eat ']' */
840  }
841  if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
842  {
843  v6.sin6_family = AF_INET6;
844  v6.sin6_port = htons ((uint16_t) port);
845 #if HAVE_SOCKADDR_IN_SIN_LEN
846  v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
847 #endif
848  in = GNUNET_memdup (&v6, sizeof(v6));
849  *sock_len = sizeof(v6);
850  GNUNET_free (cp);
851  return in;
852  }
853  }
854  /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
855  GNUNET_free (cp);
856  return NULL;
857 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static const struct GNUNET_CONFIGURATION_Handle * cfg
Handle to the config.
#define COMMUNICATOR_CONFIG_SECTION
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
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_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition: network.c:80

References cfg, COMMUNICATOR_CONFIG_SECTION, dummy, GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memdup, GNUNET_NETWORK_test_pf(), GNUNET_NO, GNUNET_strdup, GNUNET_YES, port, and start.

Referenced by mq_init(), run(), and sock_read().

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

◆ setup_peer_mq()

static void setup_peer_mq ( struct PeerAddress peer)
static

Setup the MQ for the peer.

If a queue exists, the existing one is destroyed. Then the MTU is recalculated and a fresh queue is initialized.

Parameters
peerpeer to setup MQ for

Definition at line 868 of file gnunet-communicator-quic.c.

869 {
870  size_t base_mtu;
871 
872  switch (peer->address->sa_family)
873  {
874  case AF_INET:
875  base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
876  - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
877  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
878  break;
879 
880  case AF_INET6:
881  base_mtu = 1280 /* Minimum MTU required by IPv6 */
882  - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
883  - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
884  break;
885 
886  default:
887  GNUNET_assert (0);
888  break;
889  }
890  /* MTU == base_mtu */
891  peer->d_mtu = base_mtu;
892 
894  "Setting up MQs and QHs\n");
895  /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
896  1404 (IPv4 + Box) bytes, depending on circumstances... */
897 
898  if (NULL == peer->d_mq)
900  &mq_destroy_d,
901  &mq_cancel,
902  peer,
903  NULL,
904  &mq_error,
905  peer);
906  peer->d_qh =
908  &peer->target,
909  peer->foreign_addr,
910  1000,
912  0, /* Priority */
913  peer->nt,
915  peer->d_mq);
916 }
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static void mq_send_d(struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state)
Signature of functions implementing the sending functionality of a message queue.
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...
#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_OUTBOUND
this is an outbound connection (transport initiated)
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:465
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.

References ch, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MQ_queue_for_callbacks(), GNUNET_TRANSPORT_communicator_mq_add(), GNUNET_TRANSPORT_CS_OUTBOUND, GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, mq_cancel(), mq_destroy_d(), mq_error(), mq_send_d(), and peer.

Referenced by sock_read().

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

◆ sockaddr_to_udpaddr_string()

static char* sockaddr_to_udpaddr_string ( const struct sockaddr *  address,
socklen_t  address_len 
)
static

Taken from: UDP communicator Converts address to the address string format used by this communicator in HELLOs.

Parameters
addressthe address to convert, must be AF_INET or AF_INET6.
address_lennumber of bytes in address
Returns
string representation of address

Definition at line 929 of file gnunet-communicator-quic.c.

931 {
932  char *ret;
933 
934  switch (address->sa_family)
935  {
936  case AF_INET:
938  "%s-%s",
940  GNUNET_a2s (address, address_len));
941  break;
942 
943  case AF_INET6:
945  "%s-%s",
947  GNUNET_a2s (address, address_len));
948  break;
949 
950  default:
951  GNUNET_assert (0);
952  }
953  return ret;
954 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define COMMUNICATOR_ADDRESS_PREFIX
static char * address
GNS address for this phone.
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.

References address, COMMUNICATOR_ADDRESS_PREFIX, GNUNET_a2s(), GNUNET_asprintf(), GNUNET_assert, and ret.

Referenced by mq_init(), and sock_read().

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

◆ notify_cb()

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

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

Should be an acknowledgement.

Parameters
clsclosure, NULL
senderwhich peer sent the notification
msgpayload

Definition at line 967 of file gnunet-communicator-quic.c.

970 {
971  // const struct UDPAck *ack;
972 
973  // (void) cls;
974  // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
975  // "Storing UDPAck received from backchannel from %s\n",
976  // GNUNET_i2s_full (sender));
977  // if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
978  // (ntohs (msg->size) != sizeof(struct UDPAck)))
979  // {
980  // GNUNET_break_op (0);
981  // return;
982  // }
983  // ack = (const struct UDPAck *) msg;
984  // GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
985  // sender,
986  // &handle_ack,
987  // (void *) ack);
988 }

Referenced by GNUNET_TRANSPORT_communicator_connect(), run(), and sampler_notify_on_update().

Here is the caller graph for this function:

◆ check_timeouts()

static void check_timeouts ( void *  cls)
static

Task run to check #receiver_heap and #sender_heap for timeouts.

Parameters
clsunused, NULL

Definition at line 997 of file gnunet-communicator-quic.c.

998 {
999  // struct GNUNET_TIME_Relative st;
1000  // struct GNUNET_TIME_Relative rt;
1001  // struct GNUNET_TIME_Relative delay;
1002  // struct ReceiverAddress *receiver;
1003  // struct SenderAddress *sender;
1004 
1005  // (void) cls;
1006  // timeout_task = NULL;
1007  // rt = GNUNET_TIME_UNIT_FOREVER_REL;
1008  // while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1009  // {
1010  // /* if (GNUNET_YES != receiver->receiver_destroy_called) */
1011  // /* { */
1012  // rt = GNUNET_TIME_absolute_get_remaining (receiver->timeout);
1013  // if (0 != rt.rel_value_us)
1014  // break;
1015  // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016  // "Receiver timed out\n");
1017  // receiver_destroy (receiver);
1018  // // }
1019  // }
1020  // st = GNUNET_TIME_UNIT_FOREVER_REL;
1021  // while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1022  // {
1023  // if (GNUNET_YES != sender->sender_destroy_called)
1024  // {
1025  // st = GNUNET_TIME_absolute_get_remaining (sender->timeout);
1026  // if (0 != st.rel_value_us)
1027  // break;
1028  // sender_destroy (sender);
1029  // }
1030  // }
1031  // delay = GNUNET_TIME_relative_min (rt, st);
1032  // if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1033  // timeout_task = GNUNET_SCHEDULER_add_delayed (delay, &check_timeouts, NULL);
1034 }

◆ mq_init()

static int mq_init ( void *  cls,
const struct GNUNET_PeerIdentity peer_id,
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

If we already have a queue with this peer, ignore

Insert peer into hashmap

Before setting up peer mq, initiate a quic connection to the target (perform handshake w/ quiche)

TODO: handle this

Definition at line 1056 of file gnunet-communicator-quic.c.

1058 {
1059  struct PeerAddress *peer;
1060  const char *path;
1061  struct sockaddr *in;
1062  socklen_t in_len;
1063  struct GNUNET_HashCode addr_key;
1064  uint8_t scid[LOCAL_CONN_ID_LEN];
1065 
1066  struct quic_conn *q_conn;
1067  char *bindto;
1068  socklen_t local_in_len;
1069  struct sockaddr *local_addr;
1070 
1071  if (GNUNET_OK !=
1074  "BINDTO",
1075  &bindto))
1076  {
1079  "BINDTO");
1080  return GNUNET_SYSERR;
1081  }
1082  local_addr = udp_address_to_sockaddr (bindto, &local_in_len);
1083 
1084  if (0 != strncmp (address,
1086  strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1087  {
1088  GNUNET_break_op (0);
1089  return GNUNET_SYSERR;
1090  }
1091  path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1092  in = udp_address_to_sockaddr (path, &in_len);
1093  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mq_init in_len length before: %d\n",
1094  in_len);
1098  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address string in mq_init: %s\n",
1099  address);
1100  GNUNET_CRYPTO_hash (address, strlen (address), &addr_key);
1102  if (NULL != peer)
1103  {
1105  "ignoring transport service mq request, we already have an mq with this peer (address)\n");
1106  return GNUNET_SYSERR;
1107  }
1108  peer = GNUNET_new (struct PeerAddress);
1109  peer->address = in;
1110  peer->address_len = in_len;
1111  peer->target = *peer_id;
1112  peer->id_rcvd = GNUNET_YES;
1113  peer->is_receiver = GNUNET_YES;
1114  peer->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
1115  peer->timeout =
1118  "# peers active",
1120  GNUNET_NO);
1121  peer->foreign_addr =
1122  sockaddr_to_udpaddr_string (peer->address, peer->address_len);
1127  peer,
1130  "mq_init added new peer to the addr map\n");
1136  q_conn = GNUNET_new (struct quic_conn);
1137  GNUNET_memcpy (q_conn->cid, scid, LOCAL_CONN_ID_LEN);
1138  peer->conn = q_conn;
1140  "attempting to perform QUIC handshake with peer\n");
1141  q_conn->conn = quiche_connect (peer->foreign_addr, scid, LOCAL_CONN_ID_LEN,
1142  local_addr,
1143  local_in_len, peer->address, peer->address_len,
1144  config);
1145  flush_egress (peer->conn);
1147  return GNUNET_OK;
1151  // if (NULL == timeout_task)
1152  // timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL);
1153 }
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
static char * sockaddr_to_udpaddr_string(const struct sockaddr *address, socklen_t address_len)
Taken from: UDP communicator Converts address to the address string format used by this communicator ...
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_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
enum GNUNET_GenericReturnValue 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.
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.
@ 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...
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
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:308

References addr_map, address, cfg, quic_conn::cid, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, config, quic_conn::conn, flush_egress(), GNUNET_break_op, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_block(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_memcpy, GNUNET_new, GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_OK, GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_relative_to_absolute(), GNUNET_YES, is, local_addr, LOCAL_CONN_ID_LEN, peer, peer_id, sockaddr_to_udpaddr_string(), stats, and udp_address_to_sockaddr().

Referenced by GNUNET_TRANSPORT_communicator_connect(), and run().

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

◆ try_connection_reversal()

static void try_connection_reversal ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Definition at line 1157 of file gnunet-communicator-quic.c.

1160 {
1161  /* FIXME: support reversal: #5529 */
1163  "No connection reversal implemented!");
1164 }
@ GNUNET_ERROR_TYPE_INFO

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log.

Referenced by run().

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 1181 of file gnunet-communicator-quic.c.

1187 {
1188  char *my_addr;
1190 
1191  if (GNUNET_YES == add_remove)
1192  {
1193  enum GNUNET_NetworkType nt;
1194 
1195  GNUNET_asprintf (&my_addr,
1196  "%s-%s",
1198  GNUNET_a2s (addr, addrlen));
1199  nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
1200  ai =
1202  my_addr,
1203  nt,
1205  GNUNET_free (my_addr);
1206  *app_ctx = ai;
1207  }
1208  else
1209  {
1210  ai = *app_ctx;
1212  *app_ctx = NULL;
1213  }
1214 }
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.
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.
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
Definition: gnunet_nt_lib.h:39
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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_free, 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 run().

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 QUIC communicator.

Parameters
clsNULL (always)

Definition at line 1223 of file gnunet-communicator-quic.c.

1224 {
1226  "do_shutdown\n");
1229  quiche_config_free (config);
1230 
1231  if (NULL != timeout_task)
1232  {
1234  timeout_task = NULL;
1235  }
1236  if (NULL != read_task)
1237  {
1239  read_task = NULL;
1240  }
1241  if (NULL != udp_sock)
1242  {
1245  udp_sock = NULL;
1246  }
1247  if (NULL != ch)
1248  {
1250  ch = NULL;
1251  }
1252  if (NULL != ah)
1253  {
1255  ah = NULL;
1256  }
1257  if (NULL != my_private_key)
1258  {
1260  my_private_key = NULL;
1261  }
1263  "do_shutdown finished\n");
1264 }
static struct GNUNET_SCHEDULER_Task * read_task
FIXME undocumented.
static int get_peer_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all peers to clean up.
static struct GNUNET_TRANSPORT_ApplicationHandle * ah
FIXME undocumented.
static struct GNUNET_SCHEDULER_Task * timeout_task
ID of timeout task.
static struct GNUNET_CRYPTO_EddsaPrivateKey * my_private_key
Our private key.
void GNUNET_TRANSPORT_application_done(struct GNUNET_TRANSPORT_ApplicationHandle *ch)
Shutdown TRANSPORT application client.
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:509
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

References addr_map, ah, ch, config, get_peer_delete_it(), GNUNET_break, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NETWORK_socket_close(), GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_TRANSPORT_application_done(), GNUNET_TRANSPORT_communicator_disconnect(), my_private_key, read_task, timeout_task, and udp_sock.

Referenced by run().

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

◆ sock_read()

static void sock_read ( void *  cls)
static

Get local_addr, in_len for quiche

FIXME: hashing address string vs ip/port. It is not ideal that we hash the string, instead of the binary representation, but for now it is certainly less code. Note that simply hashing the sockaddr does NOT work because the the struct is not portable.

Create new PeerAddress (receiver) with id_rcvd = false

TODO: after connection established

Parse QUIC info

New QUIC connection with peer

FIXME variables are redeclared often. Refactor either to declare variables once in the beginning or refactor into method.

Write a version negotiation packet to "out"

Send our PeerIdentity if the connection is established now

After this, we should be all good to send/recv data

TODO: Should we use a list instead of hashmap? Overhead for hashing function, O(1) retrieval vs O(n) iteration with n=30?

TODO: Is iteration necessary as in the quiche server example?

Definition at line 1268 of file gnunet-communicator-quic.c.

1269 {
1270  struct sockaddr_storage sa;
1271  struct sockaddr_in *addr_verify;
1272  socklen_t salen = sizeof(sa);
1273  uint8_t buf[UINT16_MAX];
1274  uint8_t out[MAX_DATAGRAM_SIZE];
1275  ssize_t rcvd;
1276 
1277  ssize_t process_pkt;
1278  struct QUIC_header quic_header;
1279  uint8_t new_cid[LOCAL_CONN_ID_LEN];
1280 
1281  struct PeerAddress *peer;
1282  struct GNUNET_HashCode addr_key;
1283 
1284  (void) cls;
1285  quic_header.scid_len = sizeof(quic_header.scid);
1286  quic_header.dcid_len = sizeof(quic_header.dcid);
1287  quic_header.odcid_len = sizeof(quic_header.odcid);
1288  quic_header.token_len = sizeof(quic_header.token);
1292  char *bindto;
1293  socklen_t in_len;
1294  if (GNUNET_OK !=
1297  "BINDTO",
1298  &bindto))
1299  {
1302  "BINDTO");
1303  return;
1304  }
1305  struct sockaddr *local_addr = udp_address_to_sockaddr (bindto, &in_len);
1306 
1308  udp_sock,
1309  &sock_read,
1310  NULL);
1311  while (1)
1312  {
1314  buf,
1315  sizeof(buf),
1316  (struct sockaddr *) &sa,
1317  &salen);
1318  if (-1 == rcvd)
1319  {
1320  if (EAGAIN == errno)
1321  break; // We are done reading data
1323  return;
1324  }
1325 
1327  "Read %lu bytes\n", rcvd);
1328 
1329  if (-1 == rcvd)
1330  {
1332  return;
1333  }
1341  const char *addr_string = sockaddr_to_udpaddr_string ((const struct
1342  sockaddr *) &sa,
1343  salen);
1344  GNUNET_CRYPTO_hash (addr_string, strlen (addr_string),
1345  &addr_key);
1346  GNUNET_free (addr_string);
1348 
1349  if (NULL == peer)
1350  {
1354  peer = GNUNET_new (struct PeerAddress);
1355  peer->address = GNUNET_memdup (&sa, salen);
1356  peer->address_len = salen;
1357  peer->id_rcvd = GNUNET_NO;
1358  peer->id_sent = GNUNET_NO;
1359  peer->is_receiver = GNUNET_NO;
1360  peer->conn = NULL;
1361  peer->foreign_addr = sockaddr_to_udpaddr_string (peer->address,
1362  peer->address_len);
1366  // setup_peer_mq (peer);
1368  &addr_key,
1369  peer,
1371  {
1373  "tried to add duplicate address into address map\n");
1374  return;
1375  }
1377  "sock_read added new peer to address map\n");
1378  }
1379 
1383  int rc = quiche_header_info (buf, rcvd, LOCAL_CONN_ID_LEN,
1384  &quic_header.version,
1385  &quic_header.type, quic_header.scid,
1386  &quic_header.scid_len, quic_header.dcid,
1387  &quic_header.dcid_len,
1388  quic_header.token, &quic_header.token_len);
1389  if (0 > rc)
1390  {
1392  "failed to parse quic header: %d\n",
1393  rc);
1394  return;
1395  }
1396 
1400  if (NULL == peer->conn)
1401  {
1403  "attempting to create new connection\n");
1404  if (0 == quiche_version_is_supported (quic_header.version))
1405  {
1407  "quic version negotiation initiated\n");
1415  ssize_t written = quiche_negotiate_version (quic_header.scid,
1416  quic_header.scid_len,
1417  quic_header.dcid,
1418  quic_header.dcid_len,
1419  out, sizeof(out));
1420  if (0 > written)
1421  {
1423  "quiche failed to generate version negotiation packet\n");
1424  return;
1425  }
1426  ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1427  out,
1428  written,
1429  (struct sockaddr*) &sa,
1430  salen);
1431  if (sent != written)
1432  {
1434  "failed to send version negotiation packet to peer\n");
1435  return;
1436  }
1438  "sent %zd bytes to peer during version negotiation\n",
1439  sent);
1440  return;
1441  }
1442 
1443  if (0 == quic_header.token_len)
1444  {
1445  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "quic stateless retry\n");
1446  mint_token (quic_header.dcid, quic_header.dcid_len, &sa, salen,
1447  quic_header.token, &quic_header.token_len);
1448 
1449  uint8_t new_cid[LOCAL_CONN_ID_LEN];
1452 
1453  ssize_t written = quiche_retry (quic_header.scid, quic_header.scid_len,
1454  quic_header.dcid, quic_header.dcid_len,
1455  new_cid, LOCAL_CONN_ID_LEN,
1456  quic_header.token,
1457  quic_header.token_len,
1458  quic_header.version, out, sizeof(out));
1459  if (0 > written)
1460  {
1462  "quiche failed to write retry packet\n");
1463  return;
1464  }
1465  ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1466  out,
1467  written,
1468  (struct sockaddr*) &sa,
1469  salen);
1470  if (written != sent)
1471  {
1472  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "failed to send retry packet\n");
1473  return;
1474  }
1475 
1476  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
1477  continue;
1478  }
1479 
1480  if (GNUNET_OK != validate_token (quic_header.token, quic_header.token_len,
1481  &sa, salen,
1482  quic_header.odcid,
1483  &quic_header.odcid_len))
1484  {
1486  "invalid address validation token created\n");
1487  return;
1488  }
1489  peer->conn = create_conn (quic_header.dcid, quic_header.dcid_len,
1490  quic_header.odcid, quic_header.odcid_len,
1491  local_addr, in_len,
1492  &sa, salen);
1493  if (NULL == peer->conn)
1494  {
1496  "failed to create quic connection with peer\n");
1497  return;
1498  }
1499  } // null connection
1500 
1501  quiche_recv_info recv_info = {
1502  (struct sockaddr *) &sa,
1503  salen,
1504 
1505  local_addr,
1506  in_len,
1507  };
1511  if (quiche_conn_is_established (peer->conn->conn) && ! peer->id_sent &&
1512  peer->is_receiver)
1513  {
1514  ssize_t send_len;
1515 
1517  "handshake established with peer, sending our peer id\n");
1518  send_len = quiche_conn_stream_send (peer->conn->conn, STREAMID_BI,
1519  (const uint8_t *) &my_identity,
1520  sizeof(my_identity),
1521  false);
1522  if (0 > send_len)
1523  {
1525  "failed to write peer identity packet. quiche error: %zd\n",
1526  send_len);
1527  return;
1528  }
1529  flush_egress (peer->conn);
1530  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer identity sent to peer\n");
1531  peer->id_sent = GNUNET_YES;
1532  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "setting up peer mq\n");
1533  setup_peer_mq (peer);
1537  }
1538  process_pkt = quiche_conn_recv (peer->conn->conn, buf, rcvd, &recv_info);
1539  if (0 > process_pkt)
1540  {
1542  "quiche failed to process received packet: %zd\n",
1543  process_pkt);
1544  return;
1545  }
1547  "quiche processed %zd bytes\n", process_pkt);
1548  // Check for data on all available streams if the connection is established
1549  if (GNUNET_YES == quiche_conn_is_established (peer->conn->conn))
1550  {
1552  }
1559  quiche_stats stats;
1560  quiche_path_stats path_stats;
1561 
1562  flush_egress (peer->conn);
1563 
1564  if (quiche_conn_is_closed (peer->conn->conn))
1565  {
1566  quiche_conn_stats (peer->conn->conn, &stats);
1567  quiche_conn_path_stats (peer->conn->conn, 0, &path_stats);
1568 
1570  "connection closed. quiche stats: sent=%zu, recv=%zu\n",
1571  stats.sent, stats.recv);
1572  peer_destroy (peer);
1573  }
1574  }
1576 }
struct GNUNET_PeerIdentity my_identity
Our peer identity.
static struct quic_conn * create_conn(uint8_t *scid, size_t scid_len, uint8_t *odcid, size_t odcid_len, struct sockaddr *local_addr, socklen_t local_addr_len, struct sockaddr_storage *peer_addr, socklen_t peer_addr_len)
static enum GNUNET_GenericReturnValue validate_token(const uint8_t *token, size_t token_len, struct sockaddr_storage *addr, socklen_t addr_len, uint8_t *odcid, size_t *odcid_len)
static void mint_token(const uint8_t *dcid, size_t dcid_len, struct sockaddr_storage *addr, socklen_t addr_len, uint8_t *token, size_t *token_len)
FIXME: review token generation, assure tokens are generated properly.
static void sock_read(void *cls)
#define STREAMID_BI
static void recv_from_streams(struct PeerAddress *peer)
Given a PeerAddress, receive data from streams after doing connection logic.
static void setup_peer_mq(struct PeerAddress *peer)
Setup the MQ for the peer.
static char buf[2048]
#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...
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:688
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:1506
QUIC_header is used to store information received from an incoming QUIC packet.

References addr_map, buf, cfg, COMMUNICATOR_CONFIG_SECTION, create_conn(), QUIC_header::dcid, QUIC_header::dcid_len, flush_egress(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_block(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_strerror, GNUNET_memdup, GNUNET_NETWORK_socket_recvfrom(), GNUNET_NETWORK_socket_sendto(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, local_addr, LOCAL_CONN_ID_LEN, MAX_DATAGRAM_SIZE, mint_token(), my_identity, QUIC_header::odcid, QUIC_header::odcid_len, peer, peer_destroy(), read_task, recv_from_streams(), QUIC_header::scid, QUIC_header::scid_len, setup_peer_mq(), sockaddr_to_udpaddr_string(), stats, STREAMID_BI, QUIC_header::token, QUIC_header::token_len, QUIC_header::type, udp_address_to_sockaddr(), udp_sock, validate_token(), and QUIC_header::version.

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

Setup QUICHE configuration

TODO: configure TLS cert

Get our public key for initial packet

Definition at line 1588 of file gnunet-communicator-quic.c.

1592 {
1593  char *bindto;
1594  struct sockaddr *in;
1595  socklen_t in_len;
1596  struct sockaddr_storage in_sto;
1597  socklen_t sto_len;
1598 
1599  (void) cls;
1600  cfg = c;
1601 
1602  if (GNUNET_OK !=
1605  "BINDTO",
1606  &bindto))
1607  {
1610  "BINDTO");
1611  return;
1612  }
1613 
1614  in = udp_address_to_sockaddr (bindto, &in_len);
1615 
1616  if (NULL == in)
1617  {
1619  "Failed to setup UDP socket address with path `%s'\n",
1620  bindto);
1621  GNUNET_free (bindto);
1622  return;
1623  }
1624  udp_sock =
1625  GNUNET_NETWORK_socket_create (in->sa_family,
1626  SOCK_DGRAM,
1627  IPPROTO_UDP);
1628  if (NULL == udp_sock)
1629  {
1631  GNUNET_free (in);
1632  GNUNET_free (bindto);
1633  return;
1634  }
1635  if (AF_INET6 == in->sa_family)
1637  if (GNUNET_OK !=
1639  in,
1640  in_len))
1641  {
1643  "bind",
1644  bindto);
1646  udp_sock = NULL;
1647  GNUNET_free (in);
1648  GNUNET_free (bindto);
1649  return;
1650  }
1651  sto_len = sizeof(in_sto);
1652  if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
1653  (struct sockaddr *) &in_sto,
1654  &sto_len))
1655  {
1656  memcpy (&in_sto, in, in_len);
1657  sto_len = in_len;
1658  }
1659  GNUNET_free (in);
1660  GNUNET_free (bindto);
1661  in = (struct sockaddr *) &in_sto;
1662  in_len = sto_len;
1664  "transport",
1665  "Bound to `%s'\n",
1666  GNUNET_a2s ((const struct sockaddr *) &in_sto,
1667  sto_len));
1668  switch (in->sa_family)
1669  {
1670  case AF_INET:
1671  my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
1672  break;
1673 
1674  case AF_INET6:
1675  my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
1676  break;
1677 
1678  default:
1679  GNUNET_break (0);
1680  my_port = 0;
1681  }
1686  config = quiche_config_new (QUICHE_PROTOCOL_VERSION);
1687  quiche_config_verify_peer (config, false);
1691  quiche_config_load_cert_chain_from_pem_file (config, "./cert.crt");
1692  quiche_config_load_priv_key_from_pem_file (config, "./cert.key");
1693  quiche_config_set_application_protos (config,
1694  (uint8_t *)
1695  "\x0ahq-interop\x05hq-29\x05hq-28\x05hq-27\x08http/0.9",
1696  38);
1697  quiche_config_set_max_idle_timeout (config, 5000);
1698  quiche_config_set_max_recv_udp_payload_size (config, 1200);
1699  quiche_config_set_max_send_udp_payload_size (config, 1200);
1700  quiche_config_set_initial_max_data (config, 10000000);
1701  quiche_config_set_initial_max_stream_data_bidi_local (config, 1000000);
1702  quiche_config_set_initial_max_stream_data_bidi_remote (config, 1000000);
1703  quiche_config_set_initial_max_stream_data_uni (config, 1000000);
1704  quiche_config_set_initial_max_streams_bidi (config, 100);
1705  quiche_config_set_initial_max_streams_uni (config, 100);
1706  quiche_config_set_cc_algorithm (config, QUICHE_CC_RENO);
1707  quiche_config_set_disable_active_migration (config, true);
1713  if (NULL == my_private_key)
1714  {
1715  GNUNET_log (
1717  _ (
1718  "Transport service is lacking key configuration settings. Exiting.\n"));
1720  return;
1721  }
1723  /* start reading */
1725  udp_sock,
1726  &sock_read,
1727  NULL);
1732  &mq_init,
1733  NULL,
1734  &notify_cb,
1735  NULL);
1739  IPPROTO_UDP,
1740  1 /* one address */,
1741  (const struct sockaddr **) &in,
1742  &in_len,
1743  &nat_address_cb,
1745  NULL /* closure */);
1746  if (NULL == ch)
1747  {
1748  GNUNET_break (0);
1750  return;
1751  }
1753  if (NULL == ah)
1754  {
1755  GNUNET_break (0);
1757  return;
1758  }
1759 
1760  /* start broadcasting */
1761  // if (GNUNET_YES !=
1762  // GNUNET_CONFIGURATION_get_value_yesno (cfg,
1763  // COMMUNICATOR_CONFIG_SECTION,
1764  // "DISABLE_BROADCAST"))
1765  // {
1766  // broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast, NULL);
1767  // }
1768 }
static void notify_cb(void *cls, const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg)
Function called when the transport service has received a backchannel message for this communicator (...
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
static int mq_init(void *cls, const struct GNUNET_PeerIdentity *peer_id, const char *address)
Function called by the transport service to initialize a message queue given address information abou...
static void do_shutdown(void *cls)
Shutdown the QUIC communicator.
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 ...
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static int have_v6_socket
FIXME undocumented.
static uint16_t my_port
FIXME undocumented.
struct GNUNET_TRANSPORT_ApplicationHandle * GNUNET_TRANSPORT_application_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the TRANSPORT application client handle.
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.
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:198
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
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:366
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1001
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
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:440
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:406
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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:1334
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
struct GNUNET_CRYPTO_EddsaPublicKey public_key

References _, addr_map, ah, cfg, ch, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, config, do_shutdown(), GNUNET_a2s(), GNUNET_break, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_CRYPTO_eddsa_key_create_from_configuration(), GNUNET_CRYPTO_eddsa_key_get_public(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_from_nocheck(), GNUNET_log_strerror, GNUNET_log_strerror_file, GNUNET_NAT_register(), GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NO, GNUNET_NT_scanner_init(), GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_application_init(), GNUNET_TRANSPORT_CC_RELIABLE, GNUNET_TRANSPORT_communicator_connect(), GNUNET_YES, have_v6_socket, is, mq_init(), my_identity, my_port, my_private_key, nat, nat_address_cb(), notify_cb(), GNUNET_PeerIdentity::public_key, read_task, sock_read(), try_connection_reversal(), udp_address_to_sockaddr(), and udp_sock.

Here is the call graph for this function:

◆ main()

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

Definition at line 1772 of file gnunet-communicator-quic.c.

1773 {
1774  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1776  };
1777  int ret;
1778 
1780  "transport",
1781  "Starting quic communicator\n");
1782  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1783  return 2;
1784 
1785  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1786  argv,
1787  "gnunet-communicator-quic",
1788  _ ("GNUnet QUIC communicator"),
1789  options,
1790  &run,
1791  NULL))
1792  ? 0
1793  : 1;
1794  GNUNET_free_nz ((void *) argv);
1795  return ret;
1796 }
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:400
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:1222
Definition of a command line option.

Variable Documentation

◆ conn_map

Map of DCID (uint8_t) -> quic_conn for quickly retrieving connections to other peers.

Definition at line 82 of file gnunet-communicator-quic.c.

◆ addr_map

Map of sockaddr -> struct PeerAddress.

Definition at line 87 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), mq_init(), peer_destroy(), run(), and sock_read().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Handle to the config.

Definition at line 92 of file gnunet-communicator-quic.c.

Referenced by mq_init(), run(), sock_read(), and udp_address_to_sockaddr().

◆ rekey_interval

struct GNUNET_TIME_Relative rekey_interval
static

FIXME undocumented.

Definition at line 92 of file gnunet-communicator-quic.c.

◆ udp_sock

struct GNUNET_NETWORK_Handle* udp_sock
static

FIXME undocumented.

Definition at line 102 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), flush_egress(), run(), and sock_read().

◆ read_task

struct GNUNET_SCHEDULER_Task* read_task
static

FIXME undocumented.

Definition at line 107 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), run(), and sock_read().

◆ ch

FIXME undocumented.

Definition at line 112 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), nat_address_cb(), recv_from_streams(), run(), and setup_peer_mq().

◆ ah

FIXME undocumented.

Definition at line 117 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), and run().

◆ have_v6_socket

int have_v6_socket
static

FIXME undocumented.

Definition at line 122 of file gnunet-communicator-quic.c.

Referenced by run().

◆ my_port

uint16_t my_port
static

FIXME undocumented.

Definition at line 127 of file gnunet-communicator-quic.c.

Referenced by run().

◆ rekey_max_bytes

unsigned long long rekey_max_bytes
static

FIXME undocumented.

Definition at line 132 of file gnunet-communicator-quic.c.

◆ config

quiche_config* config = NULL
static

FIXME undocumented.

Definition at line 137 of file gnunet-communicator-quic.c.

Referenced by create_conn(), do_shutdown(), mq_init(), and run().

◆ my_identity

◆ my_private_key

struct GNUNET_CRYPTO_EddsaPrivateKey* my_private_key
static

Our private key.

Definition at line 147 of file gnunet-communicator-quic.c.

Referenced by do_shutdown(), and run().

◆ nat

struct GNUNET_NAT_Handle* nat
static

Connection to NAT service.

Definition at line 152 of file gnunet-communicator-quic.c.

Referenced by run().

◆ timeout_task

struct GNUNET_SCHEDULER_Task* timeout_task
static

ID of timeout task.

Definition at line 252 of file gnunet-communicator-quic.c.

Referenced by do_shutdown().

◆ is

struct GNUNET_NT_InterfaceScanner* is
static

Network scanner to determine network types.

Definition at line 257 of file gnunet-communicator-quic.c.

Referenced by mq_init(), nat_address_cb(), and run().

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

For logging statistics.

Definition at line 262 of file gnunet-communicator-quic.c.

Referenced by mq_init(), peer_destroy(), and sock_read().