GNUnet 0.22.2
gnunet-communicator-quic.c File Reference

Transport plugin using QUIC. More...

#include "gnunet_common.h"
#include "gnunet_util_lib.h"
#include "quiche.h"
#include "platform.h"
#include "gnunet_constants.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_application_service.h"
#include "gnunet_transport_communication_service.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 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_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 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 49 of file gnunet-communicator-quic.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "quic"

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

◆ MAX_DATAGRAM_SIZE

#define MAX_DATAGRAM_SIZE   1350

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

◆ LOCAL_CONN_ID_LEN

#define LOCAL_CONN_ID_LEN   20

Definition at line 56 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 57 of file gnunet-communicator-quic.c.

◆ CID_LEN

#define CID_LEN   sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN

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

◆ TOKEN_LEN

#define TOKEN_LEN   sizeof (uint8_t) * MAX_TOKEN_LEN

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

◆ STREAMID_BI

#define STREAMID_BI   4

Definition at line 67 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 73 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 289 of file gnunet-communicator-quic.c.

290{
291 char stream_buf[UINT16_MAX];
292 size_t buf_size = UINT16_MAX;
293 char *buf_ptr = stream_buf;
294 struct GNUNET_MessageHeader *hdr;
295
296 uint64_t s = 0;
297 quiche_stream_iter *readable;
298 bool fin;
299 uint64_t err_code;
300 ssize_t recv_len;
301
302 readable = quiche_conn_readable (peer->conn->conn);
303 while (quiche_stream_iter_next (readable, &s))
304 {
305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "stream %" PRIu64 " is readable\n",
306 s);
307 fin = false;
308 recv_len = quiche_conn_stream_recv (peer->conn->conn, s,
309 (uint8_t *) stream_buf, buf_size,
310 &fin, &err_code);
311 if (recv_len < 0)
312 {
314 "error while receiving data from stream %" PRIu64
315 "; error_code %" PRIu64 "\n",
316 s, err_code);
317 break;
318 }
325 if (! peer->is_receiver && GNUNET_NO == peer->id_rcvd)
326 {
327 if (recv_len < sizeof(struct GNUNET_PeerIdentity))
328 {
330 "message recv len of %zd less than length of peer identity\n",
331 recv_len);
332 return;
333 }
335 "received peer identity\n");
336 struct GNUNET_PeerIdentity *pid = (struct
337 GNUNET_PeerIdentity *) stream_buf;
338 peer->target = *pid;
339 peer->id_rcvd = GNUNET_YES;
340 buf_ptr += sizeof(struct GNUNET_PeerIdentity);
341 recv_len -= sizeof(struct GNUNET_PeerIdentity);
342 }
346 while (recv_len >= sizeof(struct GNUNET_MessageHeader))
347 {
348 hdr = (struct GNUNET_MessageHeader *) buf_ptr;
349 if (ntohs (hdr->size) > recv_len)
350 {
352 "message size stated (%d) is greater than length of rcvd data (%zd)!\n",
353 ntohs (hdr->size), recv_len);
354 return;
355 }
356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "passing %zd bytes to core\n",
357 recv_len);
360 NULL);
361 recv_len -= ntohs (hdr->size);
362 buf_ptr += ntohs (hdr->size);
363 }
367 if (0 != recv_len)
368 {
370 "message recv len of %zd less than length of message header\n",
371 recv_len);
372 }
377 if (fin)
378 {
380 "fin received, closing connection\n");
381 if (0 > quiche_conn_close (peer->conn->conn, true, 0, NULL, 0))
382 {
384 "quiche failed to close connection to peer\n");
385 }
386 }
387 }
388 quiche_stream_iter_free (readable);
389}
#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,...)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
Header for all communications.
The identity of the host (wraps the signing key of the peer).
int id_rcvd
Flag to indicate whether we know the PeerIdentity (target) yet.
struct GNUNET_PeerIdentity target
To whom are we talking to.
struct quic_conn * conn
The QUIC connection associated with this peer.
int is_receiver
Flag to indicate if we are the initiator of the connection.
quiche_conn * conn

References ADDRESS_VALIDITY_PERIOD, ch, PeerAddress::conn, quic_conn::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_TRANSPORT_communicator_receive(), GNUNET_YES, PeerAddress::id_rcvd, PeerAddress::is_receiver, pid, GNUNET_MessageHeader::size, and PeerAddress::target.

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

399{
400 GNUNET_memcpy (token, "quiche", sizeof("quiche") - 1);
401 GNUNET_memcpy (token + sizeof("quiche") - 1, addr, addr_len);
402 GNUNET_memcpy (token + sizeof("quiche") - 1 + addr_len, dcid, dcid_len);
403
404 *token_len = sizeof("quiche") - 1 + addr_len + dcid_len;
405}
#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 409 of file gnunet-communicator-quic.c.

412{
413 if ((token_len < sizeof("quiche") - 1) ||
414 memcmp (token, "quiche", sizeof("quiche") - 1))
415 {
416 return GNUNET_NO;
417 }
418
419 token += sizeof("quiche") - 1;
420 token_len -= sizeof("quiche") - 1;
421
422 if ((token_len < addr_len) || memcmp (token, addr, addr_len))
423 {
424 return GNUNET_NO;
425 }
426
427 token += addr_len;
428 token_len -= addr_len;
429
430 if (*odcid_len < token_len)
431 {
432 return GNUNET_NO;
433 }
434
435 memcpy (odcid, token, token_len);
436 *odcid_len = token_len;
437
438 return GNUNET_OK;
439}
@ GNUNET_OK

References GNUNET_NO, and 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 443 of file gnunet-communicator-quic.c.

449{
450 struct quic_conn *conn;
451 quiche_conn *q_conn;
452 conn = GNUNET_new (struct quic_conn);
453 if (scid_len != LOCAL_CONN_ID_LEN)
454 {
456 "error while creating connection, scid length too short: %zu\n",
457 scid_len);
458 return NULL;
459 }
460
462 q_conn = quiche_accept (conn->cid, LOCAL_CONN_ID_LEN,
463 odcid, odcid_len,
465 local_addr_len,
466 (struct sockaddr *) peer_addr,
467 peer_addr_len,
468 config);
469 if (NULL == q_conn)
470 {
472 "quiche failed to create connection after call to quiche_accept\n");
473 return NULL;
474 }
475 conn->conn = q_conn;
476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new quic connection created\n");
477 return conn;
478}
#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.

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

483{
484 static uint8_t out[MAX_DATAGRAM_SIZE];
485 quiche_send_info send_info;
486
487 ssize_t written;
488 ssize_t sent;
489
490 while (1)
491 {
492 written = quiche_conn_send (conn->conn, out, sizeof(out), &send_info);
493 if (QUICHE_ERR_DONE == written)
494 {
495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done writing quic packets\n");
496 break;
497 }
498 if (0 > written)
499 {
501 "quiche failed to create packet. quiche error: %zd\n",
502 written);
503 return;
504 }
505 sent = GNUNET_NETWORK_socket_sendto (udp_sock, out, written,
506 (struct sockaddr *) &send_info.to,
507 send_info.to_len);
508 if (sent != written)
509 {
511 "quiche failed to send data to peer\n");
512 return;
513 }
514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
515 }
516}
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 525 of file gnunet-communicator-quic.c.

526{
527 peer->timeout =
529 // GNUNET_CONTAINER_heap_update_cost (peer->hn,
530 // peer->timeout.abs_value_us);
531}
#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
struct GNUNET_TIME_Absolute timeout
Timeout for this peer address.

References GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_TIME_relative_to_absolute(), and PeerAddress::timeout.

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

541{
542 struct GNUNET_HashCode addr_key;
543
546 "Disconnecting peer for peer `%s'\n",
547 GNUNET_i2s (&peer->target));
548 if (NULL != peer->d_qh)
549 {
551 peer->d_qh = NULL;
552 }
553 // GNUNET_assert (peer == GNUNET_CONTAINER_heap_remove_node (peer->hn));
557 GNUNET_CRYPTO_hash (peer->address, peer->address_len, &addr_key);
559 peer))
560 {
562 "tried to remove non-existent peer from addr map\n");
563 return;
564 }
566 "# peers active",
568 GNUNET_NO);
569 quiche_conn_free (peer->conn->conn);
570 GNUNET_free (peer->address);
572 GNUNET_free (peer->conn);
573 GNUNET_free (peer);
574}
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.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct sockaddr * address
Address of the other peer.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
int peer_destroy_called
receiver_destroy already called on receiver.
socklen_t address_len
Length of the address.

References addr_map, PeerAddress::address, PeerAddress::address_len, PeerAddress::conn, quic_conn::conn, PeerAddress::d_qh, PeerAddress::foreign_addr, 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, PeerAddress::peer_destroy_called, stats, and PeerAddress::target.

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

589{
590 struct PeerAddress *peer = value;
591 (void) cls;
592 (void) key;
593 peer_destroy (peer);
594 return GNUNET_OK;
595}
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_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 607 of file gnunet-communicator-quic.c.

610{
611 struct PeerAddress *peer = impl_state;
612 uint16_t msize = ntohs (msg->size);
613 ssize_t send_len;
614 uint64_t err_code;
615
616 if (NULL == peer->conn->conn)
617 {
619 "peer never established quic connection\n");
620 return;
621 }
622
623 GNUNET_assert (mq == peer->d_mq);
624 if (msize > peer->d_mtu)
625 {
627 "msize: %u, mtu: %lu\n",
628 msize,
629 peer->d_mtu);
630 GNUNET_break (0);
631 if (GNUNET_YES != peer->peer_destroy_called)
632 {
634 "peer destroy called, destroying peer\n");
635 peer_destroy (peer);
636 }
637 return;
638 }
640
641 send_len = quiche_conn_stream_send (peer->conn->conn, 4, (uint8_t *) msg,
642 msize, false, &err_code);
643 if (send_len != msize)
644 {
646 "tried to send message and quiche returned %zd; error_code %"
647 PRIu64,
648 send_len, err_code);
649 return;
650 }
651 flush_egress (peer->conn);
653 "sent a message of %zd bytes\n", send_len);
655}
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:437
size_t d_mtu
MTU we allowed transport for this peer's default queue.
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.

References PeerAddress::conn, quic_conn::conn, PeerAddress::d_mq, PeerAddress::d_mtu, 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_destroy(), PeerAddress::peer_destroy_called, 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 667 of file gnunet-communicator-quic.c.

668{
669 struct PeerAddress *peer = impl_state;
671 "Default MQ destroyed\n");
672 if (mq == peer->d_mq)
673 {
674 peer->d_mq = NULL;
675 if (GNUNET_YES != peer->peer_destroy_called)
676 peer_destroy (peer);
677 }
678}

References PeerAddress::d_mq, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, mq, peer_destroy(), and PeerAddress::peer_destroy_called.

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

689{
690 /* Cancellation is impossible with QUIC; bail */
691 GNUNET_assert (0);
692}

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

706{
707 struct PeerAddress *peer = cls;
708
710 "MQ error in queue to %s: %d\n",
711 GNUNET_i2s (&peer->target),
712 (int) error);
713 peer_destroy (peer);
714}

References GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, peer_destroy(), and PeerAddress::target.

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

726{
727 struct sockaddr *in;
728 unsigned int port;
729 char dummy[2];
730 char *colon;
731 char *cp;
732
733 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
734 {
735 /* interpreting value as just a PORT number */
736 if (port > UINT16_MAX)
737 {
739 "BINDTO specification `%s' invalid: value too large for port\n",
740 bindto);
741 return NULL;
742 }
743 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
744 (GNUNET_YES ==
747 "DISABLE_V6")))
748 {
749 struct sockaddr_in *i4;
750
751 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
752 i4->sin_family = AF_INET;
753 i4->sin_port = htons ((uint16_t) port);
754 *sock_len = sizeof(struct sockaddr_in);
755 in = (struct sockaddr *) i4;
756 }
757 else
758 {
759 struct sockaddr_in6 *i6;
760
761 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
762 i6->sin6_family = AF_INET6;
763 i6->sin6_port = htons ((uint16_t) port);
764 *sock_len = sizeof(struct sockaddr_in6);
765 in = (struct sockaddr *) i6;
766 }
767 return in;
768 }
769 cp = GNUNET_strdup (bindto);
770 colon = strrchr (cp, ':');
771 if (NULL != colon)
772 {
773 /* interpret value after colon as port */
774 *colon = '\0';
775 colon++;
776 if (1 == sscanf (colon, "%u%1s", &port, dummy))
777 {
778 /* interpreting value as just a PORT number */
779 if (port > UINT16_MAX)
780 {
782 "BINDTO specification `%s' invalid: value too large for port\n",
783 bindto);
784 GNUNET_free (cp);
785 return NULL;
786 }
787 }
788 else
789 {
790 GNUNET_log (
792 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
793 bindto);
794 GNUNET_free (cp);
795 return NULL;
796 }
797 }
798 else
799 {
800 /* interpret missing port as 0, aka pick any free one */
801 port = 0;
802 }
803 {
804 /* try IPv4 */
805 struct sockaddr_in v4;
806
807 memset (&v4, 0, sizeof(v4));
808 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
809 {
810 v4.sin_family = AF_INET;
811 v4.sin_port = htons ((uint16_t) port);
812#if HAVE_SOCKADDR_IN_SIN_LEN
813 v4.sin_len = sizeof(struct sockaddr_in);
814#endif
815 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
816 *sock_len = sizeof(struct sockaddr_in);
817 GNUNET_free (cp);
818 return in;
819 }
820 }
821 {
822 /* try IPv6 */
823 struct sockaddr_in6 v6;
824 const char *start;
825
826 memset (&v6, 0, sizeof(v6));
827 start = cp;
828 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
829 {
830 start++; /* skip over '[' */
831 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
832 }
833 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
834 {
835 v6.sin6_family = AF_INET6;
836 v6.sin6_port = htons ((uint16_t) port);
837#if HAVE_SOCKADDR_IN_SIN_LEN
838 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
839#endif
840 in = GNUNET_memdup (&v6, sizeof(v6));
841 *sock_len = sizeof(v6);
842 GNUNET_free (cp);
843 return in;
844 }
845 }
846 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
847 GNUNET_free (cp);
848 return NULL;
849}
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
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:79

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

861{
862 size_t base_mtu;
863
864 switch (peer->address->sa_family)
865 {
866 case AF_INET:
867 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
868 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
869 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
870 break;
871
872 case AF_INET6:
873 base_mtu = 1280 /* Minimum MTU required by IPv6 */
874 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
875 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
876 break;
877
878 default:
879 GNUNET_assert (0);
880 break;
881 }
882 /* MTU == base_mtu */
883 peer->d_mtu = base_mtu;
884
886 "Setting up MQs and QHs\n");
887 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
888 1404 (IPv4 + Box) bytes, depending on circumstances... */
889
890 if (NULL == peer->d_mq)
893 &mq_cancel,
894 peer,
895 NULL,
896 &mq_error,
897 peer);
898 peer->d_qh =
900 &peer->target,
901 peer->foreign_addr,
902 1000,
904 0, /* Priority */
905 peer->nt,
907 peer->d_mq);
908}
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:482
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.
enum GNUNET_NetworkType nt
Which network type does this queue use?

References PeerAddress::address, ch, PeerAddress::d_mq, PeerAddress::d_mtu, PeerAddress::d_qh, PeerAddress::foreign_addr, 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(), PeerAddress::nt, and PeerAddress::target.

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

923{
924 char *ret;
925
926 switch (address->sa_family)
927 {
928 case AF_INET:
930 "%s-%s",
932 GNUNET_a2s (address, address_len));
933 break;
934
935 case AF_INET6:
937 "%s-%s",
939 GNUNET_a2s (address, address_len));
940 break;
941
942 default:
943 GNUNET_assert (0);
944 }
945 return ret;
946}
static int ret
Final status code.
Definition: gnunet-arm.c:93
#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 959 of file gnunet-communicator-quic.c.

962{
963 // const struct UDPAck *ack;
964
965 // (void) cls;
966 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
967 // "Storing UDPAck received from backchannel from %s\n",
968 // GNUNET_i2s_full (sender));
969 // if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
970 // (ntohs (msg->size) != sizeof(struct UDPAck)))
971 // {
972 // GNUNET_break_op (0);
973 // return;
974 // }
975 // ack = (const struct UDPAck *) msg;
976 // GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
977 // sender,
978 // &handle_ack,
979 // (void *) ack);
980}

Referenced by run().

Here is the caller graph for this function:

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

1004{
1005 struct PeerAddress *peer;
1006 const char *path;
1007 struct sockaddr *in;
1008 socklen_t in_len;
1009 struct GNUNET_HashCode addr_key;
1010 uint8_t scid[LOCAL_CONN_ID_LEN];
1011
1012 struct quic_conn *q_conn;
1013 char *bindto;
1014 socklen_t local_in_len;
1015 struct sockaddr *local_addr;
1016
1017 if (GNUNET_OK !=
1020 "BINDTO",
1021 &bindto))
1022 {
1025 "BINDTO");
1026 return GNUNET_SYSERR;
1027 }
1028 local_addr = udp_address_to_sockaddr (bindto, &local_in_len);
1029
1030 if (0 != strncmp (address,
1032 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1033 {
1034 GNUNET_break_op (0);
1035 return GNUNET_SYSERR;
1036 }
1037 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1038 in = udp_address_to_sockaddr (path, &in_len);
1039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mq_init in_len length before: %d\n",
1040 in_len);
1044 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address string in mq_init: %s\n",
1045 address);
1046 GNUNET_CRYPTO_hash (address, strlen (address), &addr_key);
1047 peer = GNUNET_CONTAINER_multihashmap_get (addr_map, &addr_key);
1048 if (NULL != peer)
1049 {
1051 "ignoring transport service mq request, we already have an mq with this peer (address)\n");
1052 return GNUNET_SYSERR;
1053 }
1054 peer = GNUNET_new (struct PeerAddress);
1055 peer->address = in;
1056 peer->address_len = in_len;
1057 peer->target = *peer_id;
1058 peer->id_rcvd = GNUNET_YES;
1059 peer->is_receiver = GNUNET_YES;
1060 peer->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
1061 peer->timeout =
1064 "# peers active",
1066 GNUNET_NO);
1067 peer->foreign_addr =
1073 peer,
1076 "mq_init added new peer to the addr map\n");
1082 q_conn = GNUNET_new (struct quic_conn);
1083 GNUNET_memcpy (q_conn->cid, scid, LOCAL_CONN_ID_LEN);
1084 peer->conn = q_conn;
1086 "attempting to perform QUIC handshake with peer\n");
1087 q_conn->conn = quiche_connect (peer->foreign_addr, scid, LOCAL_CONN_ID_LEN,
1088 local_addr,
1089 local_in_len, peer->address, peer->address_len,
1090 config);
1091 flush_egress (peer->conn);
1093 return GNUNET_OK;
1097 // if (NULL == timeout_task)
1098 // timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL);
1099}
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.
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.
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.
@ 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:309

References addr_map, address, PeerAddress::address, PeerAddress::address_len, cfg, quic_conn::cid, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, config, PeerAddress::conn, quic_conn::conn, flush_egress(), PeerAddress::foreign_addr, 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, PeerAddress::id_rcvd, is, PeerAddress::is_receiver, local_addr, LOCAL_CONN_ID_LEN, PeerAddress::nt, peer_id, sockaddr_to_udpaddr_string(), stats, PeerAddress::target, PeerAddress::timeout, and udp_address_to_sockaddr().

Referenced by 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 1103 of file gnunet-communicator-quic.c.

1106{
1107 /* FIXME: support reversal: #5529 */
1109 "No connection reversal implemented!");
1110}
@ 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 1127 of file gnunet-communicator-quic.c.

1133{
1134 char *my_addr;
1136
1137 if (GNUNET_YES == add_remove)
1138 {
1140
1141 GNUNET_asprintf (&my_addr,
1142 "%s-%s",
1144 GNUNET_a2s (addr, addrlen));
1145 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
1146 ai =
1148 my_addr,
1149 nt,
1151 GNUNET_free (my_addr);
1152 *app_ctx = ai;
1153 }
1154 else
1155 {
1156 ai = *app_ctx;
1158 *app_ctx = NULL;
1159 }
1160}
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:44
#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 1169 of file gnunet-communicator-quic.c.

1170{
1172 "do_shutdown\n");
1175 quiche_config_free (config);
1176
1177 if (NULL != timeout_task)
1178 {
1180 timeout_task = NULL;
1181 }
1182 if (NULL != read_task)
1183 {
1185 read_task = NULL;
1186 }
1187 if (NULL != udp_sock)
1188 {
1191 udp_sock = NULL;
1192 }
1193 if (NULL != ch)
1194 {
1196 ch = NULL;
1197 }
1198 if (NULL != ah)
1199 {
1201 ah = NULL;
1202 }
1203 if (NULL != my_private_key)
1204 {
1206 my_private_key = NULL;
1207 }
1209 "do_shutdown finished\n");
1210}
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980

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

1215{
1216 struct sockaddr_storage sa;
1217 socklen_t salen = sizeof(sa);
1218 uint8_t buf[UINT16_MAX];
1219 uint8_t out[MAX_DATAGRAM_SIZE];
1220 ssize_t rcvd;
1221
1222 ssize_t process_pkt;
1223 struct QUIC_header quic_header;
1224
1225 struct PeerAddress *peer;
1226 struct GNUNET_HashCode addr_key;
1227
1228 (void) cls;
1229 quic_header.scid_len = sizeof(quic_header.scid);
1230 quic_header.dcid_len = sizeof(quic_header.dcid);
1231 quic_header.odcid_len = sizeof(quic_header.odcid);
1232 quic_header.token_len = sizeof(quic_header.token);
1236 char *bindto;
1237 socklen_t in_len;
1238 if (GNUNET_OK !=
1241 "BINDTO",
1242 &bindto))
1243 {
1246 "BINDTO");
1247 return;
1248 }
1249 struct sockaddr *local_addr = udp_address_to_sockaddr (bindto, &in_len);
1250
1252 udp_sock,
1253 &sock_read,
1254 NULL);
1255 while (1)
1256 {
1258 buf,
1259 sizeof(buf),
1260 (struct sockaddr *) &sa,
1261 &salen);
1262 if (-1 == rcvd)
1263 {
1264 if (EAGAIN == errno)
1265 break; // We are done reading data
1267 return;
1268 }
1269
1271 "Read %lu bytes\n", rcvd);
1272
1273 if (-1 == rcvd)
1274 {
1276 return;
1277 }
1285 char *addr_string = sockaddr_to_udpaddr_string ((const struct
1286 sockaddr *) &sa,
1287 salen);
1288 GNUNET_CRYPTO_hash (addr_string, strlen (addr_string),
1289 &addr_key);
1290 GNUNET_free (addr_string);
1291 peer = GNUNET_CONTAINER_multihashmap_get (addr_map, &addr_key);
1292
1293 if (NULL == peer)
1294 {
1298 peer = GNUNET_new (struct PeerAddress);
1299 peer->address = GNUNET_memdup (&sa, salen);
1300 peer->address_len = salen;
1301 peer->id_rcvd = GNUNET_NO;
1302 peer->id_sent = GNUNET_NO;
1303 peer->is_receiver = GNUNET_NO;
1304 peer->conn = NULL;
1306 peer->address_len);
1310 // setup_peer_mq (peer);
1312 &addr_key,
1313 peer,
1315 {
1317 "tried to add duplicate address into address map\n");
1318 return;
1319 }
1321 "sock_read added new peer to address map\n");
1322 }
1323
1327 int rc = quiche_header_info (buf, rcvd, LOCAL_CONN_ID_LEN,
1328 &quic_header.version,
1329 &quic_header.type, quic_header.scid,
1330 &quic_header.scid_len, quic_header.dcid,
1331 &quic_header.dcid_len,
1332 quic_header.token, &quic_header.token_len);
1333 if (0 > rc)
1334 {
1336 "failed to parse quic header: %d\n",
1337 rc);
1338 return;
1339 }
1340
1344 if (NULL == peer->conn)
1345 {
1347 "attempting to create new connection\n");
1348 if (0 == quiche_version_is_supported (quic_header.version))
1349 {
1351 "quic version negotiation initiated\n");
1359 ssize_t written = quiche_negotiate_version (quic_header.scid,
1360 quic_header.scid_len,
1361 quic_header.dcid,
1362 quic_header.dcid_len,
1363 out, sizeof(out));
1364 if (0 > written)
1365 {
1367 "quiche failed to generate version negotiation packet\n");
1368 return;
1369 }
1370 ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1371 out,
1372 written,
1373 (struct sockaddr*) &sa,
1374 salen);
1375 if (sent != written)
1376 {
1378 "failed to send version negotiation packet to peer\n");
1379 return;
1380 }
1382 "sent %zd bytes to peer during version negotiation\n",
1383 sent);
1384 return;
1385 }
1386
1387 if (0 == quic_header.token_len)
1388 {
1389 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "quic stateless retry\n");
1390 mint_token (quic_header.dcid, quic_header.dcid_len, &sa, salen,
1391 quic_header.token, &quic_header.token_len);
1392
1393 uint8_t new_cid[LOCAL_CONN_ID_LEN];
1396
1397 ssize_t written = quiche_retry (quic_header.scid, quic_header.scid_len,
1398 quic_header.dcid, quic_header.dcid_len,
1399 new_cid, LOCAL_CONN_ID_LEN,
1400 quic_header.token,
1401 quic_header.token_len,
1402 quic_header.version, out, sizeof(out));
1403 if (0 > written)
1404 {
1406 "quiche failed to write retry packet\n");
1407 return;
1408 }
1409 ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1410 out,
1411 written,
1412 (struct sockaddr*) &sa,
1413 salen);
1414 if (written != sent)
1415 {
1416 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "failed to send retry packet\n");
1417 return;
1418 }
1419
1420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
1421 continue;
1422 }
1423
1424 if (GNUNET_OK != validate_token (quic_header.token, quic_header.token_len,
1425 &sa, salen,
1426 quic_header.odcid,
1427 &quic_header.odcid_len))
1428 {
1430 "invalid address validation token created\n");
1431 return;
1432 }
1433 peer->conn = create_conn (quic_header.dcid, quic_header.dcid_len,
1434 quic_header.odcid, quic_header.odcid_len,
1435 local_addr, in_len,
1436 &sa, salen);
1437 if (NULL == peer->conn)
1438 {
1440 "failed to create quic connection with peer\n");
1441 return;
1442 }
1443 } // null connection
1444
1445 quiche_recv_info recv_info = {
1446 (struct sockaddr *) &sa,
1447 salen,
1448
1449 local_addr,
1450 in_len,
1451 };
1455 if (quiche_conn_is_established (peer->conn->conn) && ! peer->id_sent &&
1456 peer->is_receiver)
1457 {
1458 ssize_t send_len;
1459 uint64_t err_code;
1460
1462 "handshake established with peer, sending our peer id\n");
1463 send_len = quiche_conn_stream_send (peer->conn->conn, STREAMID_BI,
1464 (const uint8_t *) &my_identity,
1465 sizeof(my_identity),
1466 false, &err_code);
1467 if (0 > send_len)
1468 {
1470 "failed to write peer identity packet. quiche error: %"
1471 PRIu64 "; len=%zd\n",
1472 err_code,
1473 send_len);
1474 return;
1475 }
1476 flush_egress (peer->conn);
1477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer identity sent to peer\n");
1478 peer->id_sent = GNUNET_YES;
1479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "setting up peer mq\n");
1480 setup_peer_mq (peer);
1484 }
1485 process_pkt = quiche_conn_recv (peer->conn->conn, buf, rcvd, &recv_info);
1486 if (0 > process_pkt)
1487 {
1489 "quiche failed to process received packet: %zd\n",
1490 process_pkt);
1491 return;
1492 }
1494 "quiche processed %zd bytes\n", process_pkt);
1495 // Check for data on all available streams if the connection is established
1496 if (GNUNET_YES == quiche_conn_is_established (peer->conn->conn))
1497 {
1498 recv_from_streams (peer);
1499 }
1506 quiche_stats stats;
1507 quiche_path_stats path_stats;
1508
1509 flush_egress (peer->conn);
1510
1511 if (quiche_conn_is_closed (peer->conn->conn))
1512 {
1513 quiche_conn_stats (peer->conn->conn, &stats);
1514 quiche_conn_path_stats (peer->conn->conn, 0, &path_stats);
1515
1517 "connection closed. quiche stats: sent=%zu, recv=%zu\n",
1518 stats.sent, stats.recv);
1519 peer_destroy (peer);
1520 }
1521 }
1523}
struct GNUNET_PeerIdentity my_identity
Our peer identity.
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 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)
#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:1511
int id_sent
Flag to indicate whether we have sent OUR PeerIdentity to this peer.
QUIC_header is used to store information received from an incoming QUIC packet.

References addr_map, PeerAddress::address, PeerAddress::address_len, cfg, COMMUNICATOR_CONFIG_SECTION, PeerAddress::conn, quic_conn::conn, create_conn(), QUIC_header::dcid, QUIC_header::dcid_len, flush_egress(), PeerAddress::foreign_addr, 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, PeerAddress::id_rcvd, PeerAddress::id_sent, PeerAddress::is_receiver, local_addr, LOCAL_CONN_ID_LEN, MAX_DATAGRAM_SIZE, mint_token(), my_identity, QUIC_header::odcid, QUIC_header::odcid_len, peer_destroy(), read_task, recv_from_streams(), QUIC_header::scid, QUIC_header::scid_len, setup_peer_mq(), sock_read(), 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(), and sock_read().

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

1539{
1540 char *bindto;
1541 struct sockaddr *in;
1542 socklen_t in_len;
1543 struct sockaddr_storage in_sto;
1544 socklen_t sto_len;
1545
1546 (void) cls;
1547 cfg = c;
1548
1549 if (GNUNET_OK !=
1552 "BINDTO",
1553 &bindto))
1554 {
1557 "BINDTO");
1558 return;
1559 }
1560
1561 in = udp_address_to_sockaddr (bindto, &in_len);
1562
1563 if (NULL == in)
1564 {
1566 "Failed to setup UDP socket address with path `%s'\n",
1567 bindto);
1568 GNUNET_free (bindto);
1569 return;
1570 }
1571 udp_sock =
1572 GNUNET_NETWORK_socket_create (in->sa_family,
1573 SOCK_DGRAM,
1574 IPPROTO_UDP);
1575 if (NULL == udp_sock)
1576 {
1578 GNUNET_free (in);
1579 GNUNET_free (bindto);
1580 return;
1581 }
1582 if (AF_INET6 == in->sa_family)
1584 if (GNUNET_OK !=
1586 in,
1587 in_len))
1588 {
1590 "bind",
1591 bindto);
1593 udp_sock = NULL;
1594 GNUNET_free (in);
1595 GNUNET_free (bindto);
1596 return;
1597 }
1598 sto_len = sizeof(in_sto);
1599 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
1600 (struct sockaddr *) &in_sto,
1601 &sto_len))
1602 {
1603 memcpy (&in_sto, in, in_len);
1604 sto_len = in_len;
1605 }
1606 GNUNET_free (in);
1607 GNUNET_free (bindto);
1608 in = (struct sockaddr *) &in_sto;
1609 in_len = sto_len;
1611 "transport",
1612 "Bound to `%s'\n",
1613 GNUNET_a2s ((const struct sockaddr *) &in_sto,
1614 sto_len));
1615 switch (in->sa_family)
1616 {
1617 case AF_INET:
1618 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
1619 break;
1620
1621 case AF_INET6:
1622 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
1623 break;
1624
1625 default:
1626 GNUNET_break (0);
1627 my_port = 0;
1628 }
1633 config = quiche_config_new (QUICHE_PROTOCOL_VERSION);
1634 quiche_config_verify_peer (config, false);
1638 quiche_config_load_cert_chain_from_pem_file (config, "./cert.crt");
1639 quiche_config_load_priv_key_from_pem_file (config, "./cert.key");
1640 quiche_config_set_application_protos (config,
1641 (uint8_t *)
1642 "\x0ahq-interop\x05hq-29\x05hq-28\x05hq-27\x08http/0.9",
1643 38);
1644 quiche_config_set_max_idle_timeout (config, 5000);
1645 quiche_config_set_max_recv_udp_payload_size (config, 1200);
1646 quiche_config_set_max_send_udp_payload_size (config, 1200);
1647 quiche_config_set_initial_max_data (config, 10000000);
1648 quiche_config_set_initial_max_stream_data_bidi_local (config, 1000000);
1649 quiche_config_set_initial_max_stream_data_bidi_remote (config, 1000000);
1650 quiche_config_set_initial_max_stream_data_uni (config, 1000000);
1651 quiche_config_set_initial_max_streams_bidi (config, 100);
1652 quiche_config_set_initial_max_streams_uni (config, 100);
1653 quiche_config_set_cc_algorithm (config, QUICHE_CC_RENO);
1654 quiche_config_set_disable_active_migration (config, true);
1660 if (NULL == my_private_key)
1661 {
1662 GNUNET_log (
1664 _ (
1665 "Transport service is lacking key configuration settings. Exiting.\n"));
1667 return;
1668 }
1670 /* start reading */
1672 udp_sock,
1673 &sock_read,
1674 NULL);
1679 &mq_init,
1680 NULL,
1681 &notify_cb,
1682 NULL,
1683 NULL);
1687 IPPROTO_UDP,
1688 1 /* one address */,
1689 (const struct sockaddr **) &in,
1690 &in_len,
1693 NULL /* closure */);
1694 if (NULL == ch)
1695 {
1696 GNUNET_break (0);
1698 return;
1699 }
1701 if (NULL == ah)
1702 {
1703 GNUNET_break (0);
1705 return;
1706 }
1707
1708 /* start broadcasting */
1709 // if (GNUNET_YES !=
1710 // GNUNET_CONFIGURATION_get_value_yesno (cfg,
1711 // COMMUNICATOR_CONFIG_SECTION,
1712 // "DISABLE_BROADCAST"))
1713 // {
1714 // broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast, NULL);
1715 // }
1716}
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, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
@ GNUNET_TRANSPORT_CC_RELIABLE
Transmission is reliabile (with ACKs), e.g.
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:201
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.
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:439
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
Definition: nt.c:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
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:1339
#define _(String)
GNU gettext support macro.
Definition: platform.h:179
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.

Referenced by main().

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

◆ main()

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

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

1721{
1722 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1724 };
1725 int ret;
1726
1728 "transport",
1729 "Starting quic communicator\n");
1730 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1731 argv,
1732 "gnunet-communicator-quic",
1733 _ ("GNUnet QUIC communicator"),
1734 options,
1735 &run,
1736 NULL))
1737 ? 0
1738 : 1;
1739 return ret;
1740}
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.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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:407
Definition of a command line option.

References _, GNUNET_ERROR_TYPE_DEBUG, GNUNET_GETOPT_OPTION_END, GNUNET_log_from_nocheck(), GNUNET_OK, GNUNET_PROGRAM_run(), options, ret, and run().

Here is the call graph for this function:

Variable Documentation

◆ conn_map

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

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

◆ addr_map

Map of sockaddr -> struct PeerAddress.

Definition at line 83 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 88 of file gnunet-communicator-quic.c.

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

◆ udp_sock

struct GNUNET_NETWORK_Handle* udp_sock
static

FIXME undocumented.

Definition at line 93 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 98 of file gnunet-communicator-quic.c.

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

◆ ch

FIXME undocumented.

Definition at line 103 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 108 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 113 of file gnunet-communicator-quic.c.

Referenced by run().

◆ my_port

uint16_t my_port
static

FIXME undocumented.

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

Referenced by run().

◆ config

quiche_config* config = NULL
static

FIXME undocumented.

Definition at line 123 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 133 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 138 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 238 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 243 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 248 of file gnunet-communicator-quic.c.

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