GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-communicator-http3.c File Reference
#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_util_lib.h"
#include "gnunet_pils_service.h"
#include "gnunet_transport_application_service.h"
#include "gnunet_transport_communication_service.h"
#include "gnunet_nat_service.h"
#include "gnunet_core_service.h"
#include "gnunet_protocols.h"
#include "gnunet_signatures.h"
#include "gnunet_constants.h"
#include "gnunet_statistics_service.h"
#include "stdint.h"
#include "inttypes.h"
#include "stdlib.h"
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#include <ngtcp2/ngtcp2_crypto_gnutls.h>
#include <nghttp3/nghttp3.h>
#include <gnutls/crypto.h>
#include <gnutls/gnutls.h>
Include dependency graph for gnunet-communicator-http3.c:

Go to the source code of this file.

Data Structures

struct  Stream
 Information of a stream. More...
 
struct  HTTP_Message
 Message to send using http. More...
 
struct  Long_Poll_Request
 Long polling structure. More...
 
struct  Connection
 Used to keep track of context of peer. More...
 

Macros

#define COMMUNICATOR_CONFIG_SECTION   "communicator-http3"
 Configuration section used by the communicator.
 
#define COMMUNICATOR_ADDRESS_PREFIX   "http3"
 Address prefix used by the communicator.
 
#define PRIORITY
 the priorities to use on the ciphers, key exchange methods, and macs.
 
#define ADDRESS_VALIDITY_PERIOD   GNUNET_TIME_UNIT_HOURS
 How long do we believe our addresses to remain up (before the other peer should revalidate).
 
#define NUM_LONG_POLL   16
 Long polling requests' number.
 

Enumerations

enum  network_error {
  NETWORK_ERR_OK = 0 , NETWORK_ERR_FATAL = -10 , NETWORK_ERR_SEND_BLOCKED = -11 , NETWORK_ERR_CLOSE_WAIT = -12 ,
  NETWORK_ERR_RETRY = -13 , NETWORK_ERR_DROP_CONN = -14
}
 Defines some error types related to network errors. More...
 

Functions

static int connection_write (struct Connection *connection)
 Write the data in the stream into the packet and handle timer.
 
static uint64_t timestamp (void)
 Get current timestamp.
 
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.
 
static struct sockaddr * udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr *
 
static ngtcp2_conn * get_conn (ngtcp2_crypto_conn_ref *ref)
 The callback function for ngtcp2_crypto_conn_ref.
 
static void try_connection_reversal (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 
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.
 
static int send_packet (struct Connection *connection, const uint8_t *data, size_t datalen)
 Send the udp packet to remote.
 
static struct Streamcreate_stream (struct Connection *connection, int64_t stream_id)
 Create a new stream of connection with stream_id.
 
static void remove_stream (struct Connection *connection, int64_t stream_id)
 Remove the stream with the specified stream_id in connection.
 
static struct Streamfind_stream (struct Connection *connection, int64_t stream_id)
 Find the stream specified with stream_id in connection and return the pointer of the stream, otherwise return NULL if we can't find this stream.
 
static int client_gnutls_init (struct Connection *connection)
 As the client, initialize the corresponding connection.
 
static void reschedule_peer_timeout (struct Connection *connection)
 Increment connection timeout due to activity.
 
static int get_stream_delete_it (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over all streams to clean up.
 
static void connection_destroy (struct Connection *connection)
 Destroys a receiving state due to timeout or shutdown.
 
static nghttp3_nv make_nv (const char *name, const char *value, uint8_t flag)
 Make name/value pair for request headers.
 
static nghttp3_ssize read_data (nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec, size_t veccnt, uint32_t *pflags, void *user_data, void *stream_user_data)
 The callback function to generate body.
 
static int submit_post_request (struct Connection *connection, struct Stream *stream, const uint8_t *data, size_t datalen)
 Submit the post request, send our data.
 
static int submit_get_request (struct Connection *connection, struct Stream *stream)
 Client side submits the GET request, allow the server to send messages.
 
static void long_poll_timeoutcb (void *cls)
 Timeout callback function in the long polling struct.
 
static int stream_send_data (struct Stream *stream, uint8_t *data, size_t datalen)
 Send message through the specified stream.
 
static int stream_start_response (struct Connection *connection, struct Stream *stream)
 Make response to the request.
 
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_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
 Signature of functions implementing the destruction 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 creation of the message queue.
 
static void setup_connection_mq (struct Connection *connection)
 Setup the MQ for the connection.
 
static void http_consume (struct Connection *connection, int64_t stream_id, size_t consumed)
 Extend connection and stream offset.
 
static int http_stream_close_cb (nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *conn_user_data, void *stream_user_data)
 The callback of nghttp3_callback.stream_close.
 
static int http_recv_data_cb (nghttp3_conn *conn, int64_t stream_id, const uint8_t *data, size_t datalen, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.recv_data.
 
static int http_deferred_consume_cb (nghttp3_conn *conn, int64_t stream_id, size_t nconsumed, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.deferred_consume.
 
static int http_begin_headers_cb (nghttp3_conn *conn, int64_t stream_id, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.begin_headers.
 
static int http_recv_header_cb (nghttp3_conn *conn, int64_t stream_id, int32_t token, nghttp3_rcbuf *name, nghttp3_rcbuf *value, uint8_t flags, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.recv_header.
 
static int http_stop_sending_cb (nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.stop_sending.
 
static int http_end_stream_cb (nghttp3_conn *conn, int64_t stream_id, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.end_stream.
 
static int http_reset_stream_cb (nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
 The callback of nghttp3_callback.reset_stream.
 
static int setup_httpconn (struct Connection *connection)
 Setup the http3 connection.
 
static void rand_cb (uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx)
 The callback function for ngtcp2_callbacks.rand.
 
static int get_new_connection_id_cb (ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token, size_t cidlen, void *user_data)
 The callback function for ngtcp2_callbacks.get_new_connection_id.
 
static int recv_stream_data_cb (ngtcp2_conn *conn, uint32_t flags, int64_t stream_id, uint64_t offset, const uint8_t *data, size_t datalen, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.recv_stream_data.
 
static int stream_open_cb (ngtcp2_conn *conn, int64_t stream_id, void *user_data)
 The callback function for ngtcp2_callbacks.stream_open.
 
static int stream_close_cb (ngtcp2_conn *conn, uint32_t flags, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.stream_close.
 
static int acked_stream_data_offset_cb (ngtcp2_conn *conn, int64_t stream_id, uint64_t offset, uint64_t datalen, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.acked_stream_data_offset.
 
static int extend_max_stream_data_cb (ngtcp2_conn *conn, int64_t stream_id, uint64_t max_data, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.extend_max_stream_data.
 
static int stream_reset_cb (ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size, uint64_t app_error_code, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.stream_reset.
 
static int extend_max_remote_streams_bidi_cb (ngtcp2_conn *conn, uint64_t max_streams, void *user_data)
 The callback function for ngtcp2_callbacks.extend_max_remote_streams_bidi.
 
static int stream_stop_sending_cb (ngtcp2_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
 The callback function for ngtcp2_callbacks.stream_stop_sending.
 
static int recv_tx_key_cb (ngtcp2_conn *conn, ngtcp2_encryption_level level, void *user_data)
 The callback function for ngtcp2_callbacks.recv_tx_key.
 
static int recv_rx_key_cb (ngtcp2_conn *conn, ngtcp2_encryption_level level, void *user_data)
 The callback function for ngtcp2_callbacks.recv_rx_key.
 
static int client_quic_init (struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen)
 Create new ngtcp2_conn as client side.
 
static void close_waitcb (void *cls)
 The timeout callback function of closing/draining period.
 
static void start_draining_period (struct Connection *connection)
 Start the draining period, called after receiving CONNECTION_CLOSE.
 
static int start_closing_period (struct Connection *connection)
 Start the closing period and build the packet contains CONNECTION_CLOSE.
 
static int send_conn_close (struct Connection *connection)
 Send the packet in the conn_closebuf.
 
static int handle_error (struct Connection *connection)
 Handle errors.
 
static int handle_expiry (struct Connection *connection)
 Handles expired timer.
 
static void timeoutcb (void *cls)
 The timer callback function.
 
static void connection_update_timer (struct Connection *connection)
 Update the timer.
 
static int connection_write_streams (struct Connection *connection)
 Write HTTP stream data and send the packets.
 
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.
 
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.
 
static int get_connection_delete_it (void *cls, const struct GNUNET_HashCode *key, void *value)
 Iterator over all connection to clean up.
 
static void do_shutdown (void *cls)
 Shutdown the HTTP3 communicator.
 
static int connection_feed_data (struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
 Decrypt QUIC packet.
 
static int connection_on_read (struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
 Connection read the packet data.
 
static struct Connectionconnection_init (struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_cid *dcid, const ngtcp2_cid *scid, uint32_t version)
 Create a new connection.
 
static void server_read_pkt (struct Connection *connection, const struct GNUNET_HashCode *addr_key, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
 The server processes the newly received data packet.
 
static void sock_read (void *cls)
 Socket read task.
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Setup communicator and launch network interactions.
 
int main (int argc, char *const *argv)
 The main function for the UNIX communicator.
 

Variables

static struct GNUNET_CONTAINER_MultiHashMapaddr_map
 Map of sockaddr -> struct Connection.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration.
 
static struct GNUNET_PILS_Handlepils
 Handle to the pils service.
 
static int disable_v6
 IPv6 disabled or not.
 
static struct GNUNET_NETWORK_Handleudp_sock
 Our socket.
 
static struct GNUNET_SCHEDULER_Taskread_task
 ID of listen task.
 
static struct GNUNET_TRANSPORT_CommunicatorHandlech
 Our environment.
 
static struct GNUNET_NAT_Handlenat
 Connection to NAT service.
 
static int have_v6_socket
 GNUNET_YES if udp_sock supports IPv6.
 
static uint16_t my_port
 Port number to which we are actually bound.
 
static struct GNUNET_NT_InterfaceScanneris
 Network scanner to determine network types.
 
static struct GNUNET_STATISTICS_Handlestats
 For logging statistics.
 
static gnutls_certificate_credentials_t cred
 The credential.
 

Macro Definition Documentation

◆ COMMUNICATOR_CONFIG_SECTION

#define COMMUNICATOR_CONFIG_SECTION   "communicator-http3"

Configuration section used by the communicator.

Definition at line 29 of file gnunet-communicator-http3.c.

◆ COMMUNICATOR_ADDRESS_PREFIX

#define COMMUNICATOR_ADDRESS_PREFIX   "http3"

Address prefix used by the communicator.

Definition at line 34 of file gnunet-communicator-http3.c.

◆ PRIORITY

#define PRIORITY
Value:
"NORMAL:-VERS-ALL:+VERS-TLS1.3:" \
"-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:+CHACHA20-POLY1305:+AES-128-CCM:" \
"-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
"%DISABLE_TLS13_COMPAT_MODE"

the priorities to use on the ciphers, key exchange methods, and macs.

Definition at line 39 of file gnunet-communicator-http3.c.

39 :-VERS-ALL:+VERS-TLS1.3:" \
40 "-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:+CHACHA20-POLY1305:+AES-128-CCM:" \
41 "-GROUP-ALL:+GROUP-SECP256R1:+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \
42 "%DISABLE_TLS13_COMPAT_MODE"

◆ 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 48 of file gnunet-communicator-http3.c.

◆ NUM_LONG_POLL

#define NUM_LONG_POLL   16

Long polling requests' number.

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

Enumeration Type Documentation

◆ network_error

Defines some error types related to network errors.

Enumerator
NETWORK_ERR_OK 
NETWORK_ERR_FATAL 
NETWORK_ERR_SEND_BLOCKED 
NETWORK_ERR_CLOSE_WAIT 
NETWORK_ERR_RETRY 
NETWORK_ERR_DROP_CONN 

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

Function Documentation

◆ connection_write()

static int connection_write ( struct Connection connection)
static

Write the data in the stream into the packet and handle timer.

Parameters
connectionthe connection of the peer
Returns
GNUNET_NO on success, GNUNET_SYSERR if failed

Definition at line 2935 of file gnunet-communicator-http3.c.

2936{
2937 int rv;
2938
2939 if (GNUNET_NO == connection->is_initiator &&
2940 (ngtcp2_conn_in_closing_period (connection->conn) ||
2941 ngtcp2_conn_in_draining_period (connection->conn)))
2942 {
2943 return GNUNET_NO;
2944 }
2945
2946 rv = connection_write_streams (connection);
2947 if (GNUNET_NO != rv)
2948 {
2949 return rv;
2950 }
2951 connection_update_timer (connection);
2952
2953 return GNUNET_NO;
2954}
static int connection_write_streams(struct Connection *connection)
Write HTTP stream data and send the packets.
static void connection_update_timer(struct Connection *connection)
Update the timer.
@ GNUNET_NO
ngtcp2_conn * conn
The QUIC connection.
int is_initiator
Flag to indicate if we are the initiator of the connection.

References Connection::conn, connection_update_timer(), connection_write_streams(), GNUNET_NO, and Connection::is_initiator.

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

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

◆ timestamp()

static uint64_t timestamp ( void  )
static

Get current timestamp.

Returns
timestamp value

Definition at line 411 of file gnunet-communicator-http3.c.

412{
413 struct timespec tp;
414 clock_gettime (CLOCK_MONOTONIC, &tp);
415 return (uint64_t) tp.tv_sec * NGTCP2_SECONDS + (uint64_t) tp.tv_nsec;
416}

Referenced by cleanup_store_discourse_messages_before(), client_quic_init(), connection_feed_data(), connection_update_timer(), connection_write_streams(), create_subscription(), find_proof(), get_matching_bits(), get_message_timeout(), handle_estimate(), handle_expiry(), handle_message_subscribe(), has_subscription_of_timestamp(), iterate_flag_for_cleanup_discourse_message(), mq_send_d(), notify_srv_handle_message(), nse_callback(), nse_cb(), nse_cb(), read_start_time(), solve_srv_room_member_collisions(), start_closing_period(), start_operation(), transmit_task_cb(), update_subscription(), verify_tunnel_message(), and write_start_time().

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 429 of file gnunet-communicator-http3.c.

431{
432 char *ret;
433
434 switch (address->sa_family)
435 {
436 case AF_INET:
438 "%s-%s",
440 GNUNET_a2s (address, address_len));
441 break;
442
443 case AF_INET6:
445 "%s-%s",
447 GNUNET_a2s (address, address_len));
448 break;
449
450 default:
451 GNUNET_assert (0);
452 }
453 return ret;
454}
static int ret
Final status code.
Definition gnunet-arm.c:93
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static char * address
GNS address for this phone.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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 connection_init(), mq_init(), and sock_read().

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 465 of file gnunet-communicator-http3.c.

466{
467 struct sockaddr *in;
468 unsigned int port;
469 char dummy[2];
470 char *colon;
471 char *cp;
472
473 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
474 {
475 /* interpreting value as just a PORT number */
476 if (port > UINT16_MAX)
477 {
479 "BINDTO specification `%s' invalid: value too large for port\n",
480 bindto);
481 return NULL;
482 }
483 if (GNUNET_YES == disable_v6)
484 {
485 struct sockaddr_in *i4;
486
487 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
488 i4->sin_family = AF_INET;
489 i4->sin_port = htons ((uint16_t) port);
490 *sock_len = sizeof(struct sockaddr_in);
491 in = (struct sockaddr *) i4;
492 }
493 else
494 {
495 struct sockaddr_in6 *i6;
496
497 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
498 i6->sin6_family = AF_INET6;
499 i6->sin6_port = htons ((uint16_t) port);
500 *sock_len = sizeof(struct sockaddr_in6);
501 in = (struct sockaddr *) i6;
502 }
503 return in;
504 }
505 cp = GNUNET_strdup (bindto);
506 colon = strrchr (cp, ':');
507 if (NULL != colon)
508 {
509 /* interpret value after colon as port */
510 *colon = '\0';
511 colon++;
512 if (1 == sscanf (colon, "%u%1s", &port, dummy))
513 {
514 /* interpreting value as just a PORT number */
515 if (port > UINT16_MAX)
516 {
518 "BINDTO specification `%s' invalid: value too large for port\n",
519 bindto);
520 GNUNET_free (cp);
521 return NULL;
522 }
523 }
524 else
525 {
526 GNUNET_log (
528 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
529 bindto);
530 GNUNET_free (cp);
531 return NULL;
532 }
533 }
534 else
535 {
536 /* interpret missing port as 0, aka pick any free one */
537 port = 0;
538 }
539 {
540 /* try IPv4 */
541 struct sockaddr_in v4;
542
543 memset (&v4, 0, sizeof(v4));
544 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
545 {
546 v4.sin_family = AF_INET;
547 v4.sin_port = htons ((uint16_t) port);
548#if HAVE_SOCKADDR_IN_SIN_LEN
549 v4.sin_len = sizeof(struct sockaddr_in);
550#endif
551 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
552 *sock_len = sizeof(struct sockaddr_in);
553 GNUNET_free (cp);
554 return in;
555 }
556 }
557 {
558 /* try IPv6 */
559 struct sockaddr_in6 v6;
560 const char *start;
561
562 memset (&v6, 0, sizeof(v6));
563 start = cp;
564 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
565 {
566 start++; /* skip over '[' */
567 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
568 }
569 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
570 {
571 v6.sin6_family = AF_INET6;
572 v6.sin6_port = htons ((uint16_t) port);
573#if HAVE_SOCKADDR_IN_SIN_LEN
574 v6.sin6_len = sizeof(struct sockaddr_in6);
575#endif
576 in = GNUNET_memdup (&v6, sizeof(v6));
577 *sock_len = sizeof(v6);
578 GNUNET_free (cp);
579 return in;
580 }
581 }
582 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
583 GNUNET_free (cp);
584 return NULL;
585}
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 int disable_v6
IPv6 disabled or not.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.

References disable_v6, dummy, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_memdup, GNUNET_strdup, GNUNET_YES, port, and start.

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

Here is the caller graph for this function:

◆ get_conn()

static ngtcp2_conn * get_conn ( ngtcp2_crypto_conn_ref *  ref)
static

The callback function for ngtcp2_crypto_conn_ref.

Definition at line 592 of file gnunet-communicator-http3.c.

593{
594 return ((struct Connection*) (ref->user_data))->conn;
595}
Used to keep track of context of peer.

Referenced by client_quic_init(), and connection_init().

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 599 of file gnunet-communicator-http3.c.

602{
603 /* FIXME: support reversal: #5529 */
605 "No connection reversal implemented!\n");
606}
@ GNUNET_ERROR_TYPE_INFO

References GNUNET_ERROR_TYPE_INFO, and GNUNET_log.

Referenced by run().

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 619 of file gnunet-communicator-http3.c.

622{
623
624}

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

Here is the caller graph for this function:

◆ send_packet()

static int send_packet ( struct Connection connection,
const uint8_t *  data,
size_t  datalen 
)
static

Send the udp packet to remote.

Parameters
connectionconnection of the peer
datathe data we want to send
datalenthe length of data
Returns
GNUNET_NO on success, GNUNET_SYSERR if failed

Definition at line 637 of file gnunet-communicator-http3.c.

638{
639 int rv;
640
642 connection->address,
643 connection->address_len);
644 if (GNUNET_SYSERR == rv)
645 {
647 "send packet failed!\n");
648 return GNUNET_SYSERR;
649 }
650 return GNUNET_NO;
651}
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static char * data
The data to insert into the dht.
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_DEBUG
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:771
struct sockaddr * address
Address of the other peer.
socklen_t address_len
Length of the address.

References Connection::address, Connection::address_len, data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NETWORK_socket_sendto(), GNUNET_NO, GNUNET_SYSERR, and udp_sock.

Referenced by connection_write_streams(), send_conn_close(), and start_closing_period().

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

◆ create_stream()

static struct Stream * create_stream ( struct Connection connection,
int64_t  stream_id 
)
static

Create a new stream of connection with stream_id.

And return this stream.

Parameters
connectionthe connection.
stream_idthe ID of new stream.
Returns
the pointer to the new stream.

Definition at line 664 of file gnunet-communicator-http3.c.

665{
666 struct Stream *new_stream;
667 struct GNUNET_HashCode stream_key;
668
669 new_stream = GNUNET_new (struct Stream);
670 memset (new_stream, 0, sizeof (struct Stream));
671 new_stream->stream_id = stream_id;
672 new_stream->connection = connection;
673 GNUNET_CRYPTO_hash (&stream_id, sizeof (stream_id), &stream_key);
675 &stream_key,
676 new_stream,
678 return new_stream;
679}
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_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...
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_CONTAINER_MultiHashMap * streams
Information of the stream.
A 512-bit hashcode.
Information of a stream.
struct Connection * connection
The connection that stream belongs to.
int64_t stream_id
ID of this stream.

References Stream::connection, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_new, Stream::stream_id, and Connection::streams.

Referenced by http_end_stream_cb(), mq_send_d(), recv_rx_key_cb(), and stream_open_cb().

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

◆ remove_stream()

static void remove_stream ( struct Connection connection,
int64_t  stream_id 
)
static

Remove the stream with the specified stream_id in connection.

Parameters
connectionthe connection.
stream_idthe ID of the stream.

Definition at line 689 of file gnunet-communicator-http3.c.

690{
691 struct GNUNET_HashCode stream_key;
692 struct Stream *stream;
693 int rv;
694
695 GNUNET_CRYPTO_hash (&stream_id, sizeof (stream_id), &stream_key);
698 &stream_key,
699 stream);
700 if (GNUNET_NO == rv)
701 {
703 "can't remove non-exist pair in connection->streams, stream_id = %"
704 PRIi64 "\n",
705 stream_id);
706 return;
707 }
708
709 if (stream->uri)
710 {
711 GNUNET_free (stream->uri);
712 }
713 if (stream->method)
714 {
715 GNUNET_free (stream->method);
716 }
717 if (stream->authority)
718 {
719 GNUNET_free (stream->authority);
720 }
721 GNUNET_free (stream);
722}
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_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_ERROR_TYPE_WARNING
uint8_t * uri
The request uri.
uint8_t * method
The request method.
uint8_t * authority
The request authority.

References Stream::authority, Stream::connection, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, Stream::method, Stream::stream_id, Connection::streams, and Stream::uri.

Referenced by http_stream_close_cb().

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

◆ find_stream()

static struct Stream * find_stream ( struct Connection connection,
int64_t  stream_id 
)
static

Find the stream specified with stream_id in connection and return the pointer of the stream, otherwise return NULL if we can't find this stream.

Parameters
connectionthe connection.
stream_idthe ID of the stream.
Returns
the pointer of stream, or NULL.

Definition at line 736 of file gnunet-communicator-http3.c.

737{
738 struct GNUNET_HashCode stream_key;
739 struct Stream *stream;
740
741 GNUNET_CRYPTO_hash (&stream_id, sizeof (stream_id), &stream_key);
743 return stream;
744}

References Stream::connection, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), Stream::stream_id, and Connection::streams.

Referenced by http_begin_headers_cb().

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

◆ client_gnutls_init()

static int client_gnutls_init ( struct Connection connection)
static

As the client, initialize the corresponding connection.

Parameters
connectionCorresponding connection
Returns
GNUNET_NO on success, GNUNET_SYSERR if failed

TODO: Handle the situation when the remote host is an IP address. Numeric ip address are not permitted according to the document of GNUtls.

Definition at line 755 of file gnunet-communicator-http3.c.

756{
757 int rv;
758 gnutls_datum_t alpn = { (unsigned char *) "h3", sizeof("h3") - 1};
759 // rv = gnutls_certificate_allocate_credentials (&connection->cred);
760 // if (GNUNET_NO == rv)
761 // rv = gnutls_certificate_set_x509_system_trust (connection->cred);
762 // if (GNUNET_NO > rv)
763 // {
764 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
765 // "cred init failed: %s\n",
766 // gnutls_strerror (rv));
767 // return GNUNET_SYSERR;
768 // }
769 rv = gnutls_init (&connection->session,
770 GNUTLS_CLIENT
771 | GNUTLS_ENABLE_EARLY_DATA
772 | GNUTLS_NO_END_OF_EARLY_DATA);
773 if (GNUNET_NO != rv)
774 {
776 "gnutls_init error: %s\n",
777 gnutls_strerror (rv));
778 return GNUNET_SYSERR;
779 }
780 rv = ngtcp2_crypto_gnutls_configure_client_session (connection->session);
781 if (GNUNET_NO != rv)
782 {
784 "ngtcp2_crypto_gnutls_configure_client_session failed\n");
785 return GNUNET_SYSERR;
786 }
787 rv = gnutls_priority_set_direct (connection->session, PRIORITY, NULL);
788 if (GNUNET_NO != rv)
789 {
791 "gnutls_priority_set_direct: %s\n",
792 gnutls_strerror (rv));
793 return GNUNET_SYSERR;
794 }
795 gnutls_session_set_ptr (connection->session, &connection->conn_ref);
796 rv = gnutls_credentials_set (connection->session, GNUTLS_CRD_CERTIFICATE,
797 cred);
798 if (GNUNET_NO != rv)
799 {
801 "gnutls_credentials_set: %s\n",
802 gnutls_strerror (rv));
803 return GNUNET_SYSERR;
804 }
805 gnutls_alpn_set_protocols (connection->session, &alpn, 1,
806 GNUTLS_ALPN_MANDATORY);
807
812 // gnutls_server_name_set (connection->session, GNUTLS_NAME_DNS, "localhost",
813 // strlen ("localhost"));
814
815 return GNUNET_NO;
816}
#define PRIORITY
the priorities to use on the ciphers, key exchange methods, and macs.
static gnutls_certificate_credentials_t cred
The credential.
gnutls_session_t session
The gnutls session.
ngtcp2_crypto_conn_ref conn_ref
The structure to get a pointer to ngtcp2_conn.

References Connection::conn_ref, Stream::connection, cred, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, PRIORITY, and Connection::session.

Referenced by mq_init().

Here is the caller graph for this function:

◆ reschedule_peer_timeout()

static void reschedule_peer_timeout ( struct Connection connection)
static

Increment connection timeout due to activity.

Parameters
connectionaddress for which the timeout should be rescheduled

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

826{
827 connection->timeout =
829 // GNUNET_CONTAINER_heap_update_cost (peer->hn,
830 // peer->timeout.abs_value_us);
831}
#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 connection.

References Stream::connection, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_TIME_relative_to_absolute(), and Connection::timeout.

Referenced by mq_send_d().

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

◆ get_stream_delete_it()

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

Iterator over all streams to clean up.

Parameters
clsNULL
keystream->stream_id
valuethe stream to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 843 of file gnunet-communicator-http3.c.

846{
847 struct Stream *stream = value;
848 (void) cls;
849 (void) key;
850
851 if (stream->uri)
852 {
853 GNUNET_free (stream->uri);
854 }
855 if (stream->method)
856 {
857 GNUNET_free (stream->method);
858 }
859 if (stream->authority)
860 {
861 GNUNET_free (stream->authority);
862 }
863 GNUNET_free (stream);
864 return GNUNET_OK;
865}
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
@ GNUNET_OK

References Stream::authority, GNUNET_free, GNUNET_OK, key, Stream::method, Stream::uri, and value.

Referenced by connection_destroy().

Here is the caller graph for this function:

◆ connection_destroy()

static void connection_destroy ( struct Connection connection)
static

Destroys a receiving state due to timeout or shutdown.

Parameters
connectionentity to close down

Definition at line 874 of file gnunet-communicator-http3.c.

875{
876 struct GNUNET_HashCode addr_key;
877 struct HTTP_Message *msg_curr;
878 struct Long_Poll_Request *long_poll_curr;
879 struct Long_Poll_Request *long_poll_temp;
880 int rv;
882
883 msg_curr = connection->msg_queue_head;
884 connection->msg_queue_rear = NULL;
885 while (NULL != msg_curr)
886 {
887 msg_curr = msg_curr->next;
888 GNUNET_free (msg_curr->buf);
889 GNUNET_free (msg_curr);
890 }
891
892 msg_curr = connection->submitted_msg_queue_head;
893 while (NULL != msg_curr)
894 {
895 msg_curr = msg_curr->next;
896 GNUNET_free (msg_curr->buf);
897 GNUNET_free (msg_curr);
898 }
899
900 long_poll_curr = connection->long_poll_head;
901 connection->long_poll_rear = NULL;
902 while (NULL != long_poll_curr)
903 {
904 long_poll_temp = long_poll_curr;
905 long_poll_curr = long_poll_curr->next;
906 if (long_poll_temp->timer)
907 GNUNET_SCHEDULER_cancel (long_poll_temp->timer);
908 GNUNET_free (long_poll_temp);
909 }
910
911 if (NULL != connection->d_qh)
912 {
914 connection->d_qh = NULL;
915 }
916
917 GNUNET_CRYPTO_hash (connection->address,
918 connection->address_len,
919 &addr_key);
920 rv = GNUNET_CONTAINER_multihashmap_remove (addr_map, &addr_key, connection);
921 if (GNUNET_NO == rv)
922 {
924 "tried to remove non-existent connection from addr_map\n");
925 return;
926 }
928 "# connections active",
930 GNUNET_NO);
931
932 ngtcp2_conn_del (connection->conn);
933 if (connection->h3_conn)
934 {
935 nghttp3_conn_del (connection->h3_conn);
936 }
937 gnutls_deinit (connection->session);
938 GNUNET_free (connection->address);
939 GNUNET_free (connection->foreign_addr);
940 GNUNET_free (connection->conn_closebuf);
943 NULL);
945 GNUNET_free (connection);
946}
static int get_stream_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all streams to clean up.
static struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static struct GNUNET_CONTAINER_MultiHashMap * addr_map
Map of sockaddr -> struct Connection.
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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct Long_Poll_Request * long_poll_head
head pointer of long polling struct queue.
nghttp3_conn * h3_conn
The HTTP/3 connection.
struct Long_Poll_Request * long_poll_rear
rear pointer of long polling struct queue.
struct GNUNET_TRANSPORT_QueueHandle * d_qh
handle for default queue with the ch.
struct HTTP_Message * msg_queue_rear
rear pointer of message queue.
char * foreign_addr
Address of the receiver in the human-readable format with the COMMUNICATOR_ADDRESS_PREFIX.
uint8_t * conn_closebuf
conn_closebuf contains a packet which contains CONNECTION_CLOSE.
struct HTTP_Message * msg_queue_head
head pointer of message queue.
struct HTTP_Message * submitted_msg_queue_head
Messages that have been submitted will be put into this queue.
int connection_destroy_called
connection_destroy already called on connection.
Message to send using http.
char * buf
buffer containing data to send
struct HTTP_Message * next
next pointer for double linked list
Long polling structure.
struct Long_Poll_Request * next
Next structure.
struct GNUNET_SCHEDULER_Task * timer
Timeout timer for long polling stream.

References addr_map, Connection::address, Connection::address_len, HTTP_Message::buf, Connection::conn, Connection::conn_closebuf, Connection::connection_destroy_called, Connection::d_qh, Connection::foreign_addr, get_stream_delete_it(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_TRANSPORT_communicator_mq_del(), GNUNET_YES, Connection::h3_conn, Connection::long_poll_head, Connection::long_poll_rear, Connection::msg_queue_head, Connection::msg_queue_rear, HTTP_Message::next, Long_Poll_Request::next, Connection::session, stats, Connection::streams, Connection::submitted_msg_queue_head, and Long_Poll_Request::timer.

Referenced by close_waitcb(), get_connection_delete_it(), handle_error(), mq_destroy_d(), mq_error(), mq_send_d(), server_read_pkt(), and timeoutcb().

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

◆ make_nv()

static nghttp3_nv make_nv ( const char *  name,
const char *  value,
uint8_t  flag 
)
static

Make name/value pair for request headers.

Parameters
nameThe HTTP filed name.
valueThe HTTP filed value.
flagFlags for name/value pair.
Returns
A new nghttp3_nv.

Definition at line 959 of file gnunet-communicator-http3.c.

962{
963 nghttp3_nv nv;
964
965 nv.name = (const uint8_t *) name;
966 nv.namelen = strlen (name);
967 nv.value = (const uint8_t *) value;
968 nv.valuelen = strlen (value);
969 nv.flags = flag;
970
971 return nv;
972}
static char * name
Name (label) of the records to list.

References name, and value.

Referenced by long_poll_timeoutcb(), stream_send_data(), stream_start_response(), submit_get_request(), and submit_post_request().

Here is the caller graph for this function:

◆ read_data()

static nghttp3_ssize read_data ( nghttp3_conn *  conn,
int64_t  stream_id,
nghttp3_vec *  vec,
size_t  veccnt,
uint32_t *  pflags,
void *  user_data,
void *  stream_user_data 
)
static

The callback function to generate body.

Definition at line 979 of file gnunet-communicator-http3.c.

982{
983 struct Stream *stream = stream_user_data;
984
985 vec[0].base = stream->data;
986 vec[0].len = stream->datalen;
987 *pflags |= NGHTTP3_DATA_FLAG_EOF;
988
989 return 1;
990}
uint8_t * data
The stream data.
uint64_t datalen
The length of stream data.

References Stream::data, and Stream::datalen.

Referenced by stream_send_data(), and submit_post_request().

Here is the caller graph for this function:

◆ submit_post_request()

static int submit_post_request ( struct Connection connection,
struct Stream stream,
const uint8_t *  data,
size_t  datalen 
)
static

Submit the post request, send our data.

Parameters
connectionthe connection.
streamthe stream.
datathe data will be sent.
datalenthe length of data.
Returns
GNUNET_NO if success, #GNUENT_SYSERR if failed.

Definition at line 1004 of file gnunet-communicator-http3.c.

1008{
1009 nghttp3_nv nva[7];
1010 char contentlen[20];
1011 nghttp3_data_reader dr = {};
1012 int rv;
1013
1014 GNUNET_snprintf (contentlen, sizeof(contentlen), "%zu", datalen);
1015 stream->data = (uint8_t *) data;
1016 stream->datalen = datalen;
1017
1018 nva[0] = make_nv (":method", "POST",
1019 NGHTTP3_NV_FLAG_NO_COPY_NAME
1020 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1021 nva[1] = make_nv (":scheme", "https",
1022 NGHTTP3_NV_FLAG_NO_COPY_NAME
1023 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1024 nva[2] = make_nv (":authority",
1025 GNUNET_a2s (connection->address, connection->address_len),
1026 NGHTTP3_NV_FLAG_NO_COPY_NAME);
1027 nva[3] = make_nv (":path", "/",
1028 NGHTTP3_NV_FLAG_NO_COPY_NAME
1029 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1030 nva[4] = make_nv ("user-agent", "nghttp3/ngtcp2 client",
1031 NGHTTP3_NV_FLAG_NO_COPY_NAME
1032 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1033 nva[5] = make_nv ("content-type", "application/octet-stream",
1034 NGHTTP3_NV_FLAG_NO_COPY_NAME
1035 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1036 nva[6] = make_nv ("content-length", contentlen,
1037 NGHTTP3_NV_FLAG_NO_COPY_NAME);
1038
1039 dr.read_data = read_data;
1040 rv = nghttp3_conn_submit_request (connection->h3_conn,
1041 stream->stream_id,
1042 nva, 7, &dr, stream);
1043 if (0 != rv)
1044 {
1046 "nghttp3_conn_submit_request: %s\n",
1047 nghttp3_strerror (rv));
1048 return GNUNET_SYSERR;
1049 }
1050
1051 return GNUNET_NO;
1052}
static nghttp3_ssize read_data(nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec, size_t veccnt, uint32_t *pflags, void *user_data, void *stream_user_data)
The callback function to generate body.
static nghttp3_nv make_nv(const char *name, const char *value, uint8_t flag)
Make name/value pair for request headers.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.

References Connection::address, Connection::address_len, Stream::connection, data, Stream::data, Stream::datalen, GNUNET_a2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_snprintf(), GNUNET_SYSERR, Connection::h3_conn, make_nv(), read_data(), and Stream::stream_id.

Referenced by mq_send_d(), and recv_rx_key_cb().

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

◆ submit_get_request()

static int submit_get_request ( struct Connection connection,
struct Stream stream 
)
static

Client side submits the GET request, allow the server to send messages.

Parameters
connectionthe connection.
streamthe stream.
Returns
GNUNET_NO if success, #GNUENT_SYSERR if failed.

Definition at line 1065 of file gnunet-communicator-http3.c.

1067{
1068 nghttp3_nv nva[6];
1069 int rv;
1070
1072 "send get request\n");
1073 nva[0] = make_nv (":method", "GET",
1074 NGHTTP3_NV_FLAG_NO_COPY_NAME
1075 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1076 nva[1] = make_nv (":scheme", "https",
1077 NGHTTP3_NV_FLAG_NO_COPY_NAME
1078 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1079 nva[2] = make_nv (":authority",
1080 GNUNET_a2s (connection->address, connection->address_len),
1081 NGHTTP3_NV_FLAG_NO_COPY_NAME);
1082 nva[3] = make_nv (":path", "/",
1083 NGHTTP3_NV_FLAG_NO_COPY_NAME
1084 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1085 nva[4] = make_nv ("user-agent", "nghttp3/ngtcp2 client",
1086 NGHTTP3_NV_FLAG_NO_COPY_NAME
1087 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1088
1089 rv = nghttp3_conn_submit_request (connection->h3_conn,
1090 stream->stream_id,
1091 nva, 5, NULL, stream);
1092 if (0 != rv)
1093 {
1095 "nghttp3_conn_submit_request: %s\n",
1096 nghttp3_strerror (rv));
1097 return GNUNET_SYSERR;
1098 }
1099
1100 return GNUNET_NO;
1101}

References Connection::address, Connection::address_len, Stream::connection, GNUNET_a2s(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, Connection::h3_conn, make_nv(), and Stream::stream_id.

Referenced by http_end_stream_cb(), and recv_rx_key_cb().

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

◆ long_poll_timeoutcb()

static void long_poll_timeoutcb ( void *  cls)
static

Timeout callback function in the long polling struct.

Parameters
clsthe closure.

Definition at line 1110 of file gnunet-communicator-http3.c.

1111{
1112 struct Long_Poll_Request *long_poll = cls;
1113 nghttp3_nv nva[2];
1114 struct Stream *stream;
1115 struct Connection *connection;
1116 int rv;
1117
1118 long_poll->timer = NULL;
1120 "long_poll_timeoutcb called!\n");
1121 stream = long_poll->stream;
1122 connection = stream->connection;
1123 if (NULL != long_poll->prev)
1124 {
1125 long_poll->prev->next = long_poll->next;
1126 }
1127 if (NULL != long_poll->next)
1128 {
1129 long_poll->next->prev = long_poll->prev;
1130 }
1131 if (connection->long_poll_head == long_poll)
1132 {
1133 connection->long_poll_head = long_poll->next;
1134 }
1135 if (connection->long_poll_rear == long_poll)
1136 {
1137 connection->long_poll_rear = long_poll->prev;
1138 }
1139 GNUNET_free (long_poll);
1140
1141 nva[0] = make_nv (":status", "204",
1142 NGHTTP3_NV_FLAG_NO_COPY_NAME
1143 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1144 nva[1] = make_nv ("server", "nghttp3/ngtcp2 server",
1145 NGHTTP3_NV_FLAG_NO_COPY_NAME
1146 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1147 rv = nghttp3_conn_submit_response (connection->h3_conn,
1148 stream->stream_id, nva, 2, NULL);
1149 if (0 != rv)
1150 {
1152 "nghttp3_conn_submit_response: %s\n",
1153 nghttp3_strerror (rv));
1154 return;
1155 }
1156 ngtcp2_conn_shutdown_stream_read (connection->conn, 0,
1157 stream->stream_id,
1158 NGHTTP3_H3_NO_ERROR);
1159}
struct Long_Poll_Request * prev
Previous structure.
struct Stream * stream
The long polling stream.

References Connection::conn, Stream::connection, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, Connection::h3_conn, Connection::long_poll_head, Connection::long_poll_rear, make_nv(), Long_Poll_Request::next, Long_Poll_Request::prev, Long_Poll_Request::stream, Stream::stream_id, and Long_Poll_Request::timer.

Referenced by stream_start_response().

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

◆ stream_send_data()

static int stream_send_data ( struct Stream stream,
uint8_t *  data,
size_t  datalen 
)
static

Send message through the specified stream.

Mainly used to send data when the server responds.

Parameters
streamthe stream.
datathe data.
datalenthe length of data.
Returns
GNUNET_NO if success, #GNUENT_SYSERR if failed.

Definition at line 1173 of file gnunet-communicator-http3.c.

1175{
1176 nghttp3_nv nva[4];
1177 nghttp3_data_reader dr = {};
1178 char content_length_str[20];
1179 int rv;
1180
1181 GNUNET_snprintf (content_length_str, sizeof(content_length_str),
1182 "%zu", datalen);
1183 nva[0] = make_nv (":status", "200",
1184 NGHTTP3_NV_FLAG_NO_COPY_NAME
1185 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1186 nva[1] = make_nv ("server", "nghttp3/ngtcp2 server",
1187 NGHTTP3_NV_FLAG_NO_COPY_NAME
1188 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1189 nva[2] = make_nv ("content-type", "application/octet-stream",
1190 NGHTTP3_NV_FLAG_NO_COPY_NAME
1191 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1192 nva[3] = make_nv ("content-length", content_length_str,
1193 NGHTTP3_NV_FLAG_NO_COPY_NAME);
1194
1195 stream->data = data;
1196 stream->datalen = datalen;
1197 dr.read_data = read_data;
1198 rv = nghttp3_conn_submit_response (stream->connection->h3_conn,
1199 stream->stream_id,
1200 nva, 4, &dr);
1201 if (0 != rv)
1202 {
1204 "nghttp3_conn_submit_response: %s\n",
1205 nghttp3_strerror (rv));
1206 return GNUNET_SYSERR;
1207 }
1208 return GNUNET_NO;
1209}

References Stream::connection, data, Stream::data, Stream::datalen, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_snprintf(), GNUNET_SYSERR, Connection::h3_conn, make_nv(), read_data(), and Stream::stream_id.

Referenced by mq_send_d(), and stream_start_response().

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

◆ stream_start_response()

static int stream_start_response ( struct Connection connection,
struct Stream stream 
)
static

Make response to the request.

Parameters
h3_connthe HTTP/3 connection.
streamthe stream.
Returns
GNUNET_NO if success, #GNUENT_SYSERR if failed.

Definition at line 1221 of file gnunet-communicator-http3.c.

1222{
1223 nghttp3_nv nva[4];
1224 struct HTTP_Message *msg;
1225 struct Long_Poll_Request *long_poll;
1226 struct GNUNET_TIME_Relative delay;
1227 int rv;
1228
1229 nva[0] = make_nv (":status", "200",
1230 NGHTTP3_NV_FLAG_NO_COPY_NAME
1231 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1232 nva[1] = make_nv ("server", "nghttp3/ngtcp2 server",
1233 NGHTTP3_NV_FLAG_NO_COPY_NAME
1234 | NGHTTP3_NV_FLAG_NO_COPY_VALUE);
1235
1236 // method is POST
1237 if (4 == stream->methodlen)
1238 {
1239 if (NULL == connection->msg_queue_head)
1240 {
1241 rv = nghttp3_conn_submit_response (connection->h3_conn, stream->stream_id,
1242 nva, 2, NULL);
1243 if (0 != rv)
1244 {
1246 "nghttp3_conn_submit_response: %s\n",
1247 nghttp3_strerror (rv));
1248 return GNUNET_SYSERR;
1249 }
1250 }
1251 else
1252 {
1253 connection->msg_queue_len -= 1;
1255 "rm msg, len = %lu\n",
1256 connection->msg_queue_len);
1257 msg = connection->msg_queue_head;
1258 stream_send_data (stream, (uint8_t *) msg->buf, msg->size);
1259 connection->msg_queue_head = msg->next;
1260 msg->next = connection->submitted_msg_queue_head;
1261 connection->submitted_msg_queue_head = msg;
1262 }
1263 }
1264 // method is GET
1265 else
1266 {
1268 "server recv GET request\n");
1269 if (NULL != connection->msg_queue_head &&
1270 NULL == connection->long_poll_head)
1271 {
1272 msg = connection->msg_queue_head;
1273 stream_send_data (stream,
1274 (uint8_t *) msg->buf,
1275 msg->size);
1276 connection->msg_queue_head = msg->next;
1277 msg->next = connection->submitted_msg_queue_head;
1278 connection->submitted_msg_queue_head = msg;
1279 }
1280 else if (NULL == connection->msg_queue_head ||
1281 NULL != connection->long_poll_head)
1282 {
1283 connection->long_poll_len += 1;
1285 "add long_poll, len = %lu\n",
1286 connection->long_poll_len);
1287 long_poll = GNUNET_new (struct Long_Poll_Request);
1288 long_poll->stream = stream;
1289 long_poll->next = NULL;
1290 long_poll->prev = connection->long_poll_rear;
1291 long_poll->delay_time = 1ULL;
1292 if (NULL != connection->long_poll_rear)
1293 {
1294 connection->long_poll_rear->next = long_poll;
1295 long_poll->delay_time =
1296 (connection->long_poll_head->delay_time & (NUM_LONG_POLL - 1)) + 1ULL;
1297 }
1298 connection->long_poll_rear = long_poll;
1299 if (NULL == connection->long_poll_head)
1300 {
1301 connection->long_poll_head = long_poll;
1302 }
1304 long_poll->delay_time);
1305 long_poll->timer = GNUNET_SCHEDULER_add_delayed (delay,
1307 long_poll);
1308 }
1309 long_poll = connection->long_poll_head;
1310
1311 while (NULL != long_poll &&
1312 NULL != connection->msg_queue_head)
1313 {
1314 GNUNET_SCHEDULER_cancel (long_poll->timer);
1315 if (NULL != long_poll->next)
1316 {
1317 long_poll->next->prev = NULL;
1318 }
1319
1320 msg = connection->msg_queue_head;
1321 connection->msg_queue_head = msg->next;
1322 msg->next = connection->submitted_msg_queue_head;
1323 connection->submitted_msg_queue_head = msg;
1324 stream_send_data (long_poll->stream,
1325 (uint8_t *) msg->buf,
1326 msg->size);
1327 connection->long_poll_head = long_poll->next;
1328 if (NULL != long_poll->next)
1329 {
1330 long_poll->next->prev = NULL;
1331 }
1332 connection->long_poll_len -= 1;
1334 "rm long_poll, len = %lu\n",
1335 connection->long_poll_len);
1336 GNUNET_free (long_poll);
1337 long_poll = connection->long_poll_head;
1338 }
1339 }
1340 return GNUNET_NO;
1341}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static void long_poll_timeoutcb(void *cls)
Timeout callback function in the long polling struct.
#define NUM_LONG_POLL
Long polling requests' number.
static int stream_send_data(struct Stream *stream, uint8_t *data, size_t datalen)
Send message through the specified stream.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1283
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
size_t long_poll_len
length of long polling struct queue.
size_t msg_queue_len
length of message queue.
Time for relative time used by GNUnet, in microseconds.
uint64_t delay_time
Timeout value.
size_t methodlen
The length of request method.

References Long_Poll_Request::delay_time, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_SECONDS, Connection::h3_conn, Connection::long_poll_head, Connection::long_poll_len, Connection::long_poll_rear, long_poll_timeoutcb(), make_nv(), Stream::methodlen, msg, Connection::msg_queue_head, Connection::msg_queue_len, Long_Poll_Request::next, NUM_LONG_POLL, Long_Poll_Request::prev, GNUNET_MessageHeader::size, Long_Poll_Request::stream, Stream::stream_id, stream_send_data(), Connection::submitted_msg_queue_head, and Long_Poll_Request::timer.

Referenced by http_end_stream_cb().

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 1353 of file gnunet-communicator-http3.c.

1356{
1357 struct Connection *connection = impl_state;
1358 uint16_t msize = ntohs (msg->size);
1359 struct Stream *post_stream;
1360 struct HTTP_Message *send_buf;
1361 struct Long_Poll_Request *long_poll;
1362
1364 "mq_send_d: init = %d, msg->size = %u, time: %llu\n",
1365 connection->is_initiator, msize,
1366 (unsigned long long) timestamp () / NGTCP2_SECONDS);
1367 if (NULL == connection->conn)
1368 {
1370 "No quic connection has been established yet\n");
1371 return;
1372 }
1373
1374 GNUNET_assert (mq == connection->d_mq);
1375
1376 if (msize > connection->d_mtu)
1377 {
1379 "msize: %u, mtu: %lu\n",
1380 msize,
1381 connection->d_mtu);
1382 GNUNET_break (0);
1383 if (GNUNET_YES != connection->connection_destroy_called)
1384 {
1386 "connection destroy called, destroying connection\n");
1387 connection_destroy (connection);
1388 }
1389 return;
1390 }
1391 reschedule_peer_timeout (connection);
1392
1393 // If we are client side.
1394 if (GNUNET_YES == connection->is_initiator)
1395 {
1396 post_stream = create_stream (connection, -1);
1397 ngtcp2_conn_open_bidi_stream (connection->conn,
1398 &post_stream->stream_id,
1399 NULL);
1400 submit_post_request (connection, post_stream, (uint8_t *) msg, msize);
1401 connection_write (connection);
1402 }
1403 // If we are server side.
1404 else
1405 {
1406 if (NULL == connection->msg_queue_head &&
1407 NULL != connection->long_poll_head)
1408 {
1409 long_poll = connection->long_poll_head;
1410 GNUNET_SCHEDULER_cancel (long_poll->timer);
1411 stream_send_data (long_poll->stream, (uint8_t *) msg, msize);
1412 connection_write (connection);
1413 connection->long_poll_head = long_poll->next;
1414 if (NULL != long_poll->next)
1415 {
1416 long_poll->next->prev = NULL;
1417 }
1418 connection->long_poll_len -= 1;
1420 "rm long_poll, len = %lu\n",
1421 connection->long_poll_len);
1422 GNUNET_free (long_poll);
1423 }
1424 else if (NULL == connection->long_poll_head ||
1425 NULL != connection->msg_queue_head)
1426 {
1427 connection->msg_queue_len += 1;
1429 "add msg, len = %lu\n",
1430 connection->msg_queue_len);
1431 send_buf = GNUNET_new (struct HTTP_Message);
1432 send_buf->size = msize;
1433 send_buf->buf = GNUNET_memdup (msg, msize);
1434 send_buf->next = NULL;
1435 connection->msg_queue_rear = send_buf;
1436 if (NULL == connection->msg_queue_head)
1437 {
1438 connection->msg_queue_head = send_buf;
1439 }
1440 }
1441
1442 long_poll = connection->long_poll_head;
1443 while (NULL != long_poll &&
1444 NULL != connection->msg_queue_head)
1445 {
1446 GNUNET_SCHEDULER_cancel (long_poll->timer);
1447 if (NULL != long_poll->next)
1448 {
1449 long_poll->next->prev = NULL;
1450 }
1451
1452 send_buf = connection->msg_queue_head;
1453 connection->msg_queue_head = send_buf->next;
1454 send_buf->next = connection->submitted_msg_queue_head;
1455 connection->submitted_msg_queue_head = send_buf;
1456 stream_send_data (long_poll->stream,
1457 (uint8_t *) send_buf->buf,
1458 send_buf->size);
1459 connection->long_poll_head = long_poll->next;
1460 if (NULL != long_poll->next)
1461 {
1462 long_poll->next->prev = NULL;
1463 }
1464 connection->long_poll_len -= 1;
1466 "rm long_poll, len = %lu\n",
1467 connection->long_poll_len);
1468 GNUNET_free (long_poll);
1469 long_poll = connection->long_poll_head;
1470 }
1471 }
1473}
static int connection_write(struct Connection *connection)
Write the data in the stream into the packet and handle timer.
static uint64_t timestamp(void)
Get current timestamp.
static void connection_destroy(struct Connection *connection)
Destroys a receiving state due to timeout or shutdown.
static void reschedule_peer_timeout(struct Connection *connection)
Increment connection timeout due to activity.
static int submit_post_request(struct Connection *connection, struct Stream *stream, const uint8_t *data, size_t datalen)
Submit the post request, send our data.
static struct Stream * create_stream(struct Connection *connection, int64_t stream_id)
Create a new stream of connection with stream_id.
#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
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
size_t size
buffer length

References HTTP_Message::buf, Connection::conn, connection_destroy(), Connection::connection_destroy_called, connection_write(), create_stream(), Connection::d_mq, Connection::d_mtu, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_memdup, GNUNET_MQ_impl_send_continue(), GNUNET_new, GNUNET_SCHEDULER_cancel(), GNUNET_YES, Connection::is_initiator, Connection::long_poll_head, Connection::long_poll_len, mq, msg, Connection::msg_queue_head, Connection::msg_queue_len, Connection::msg_queue_rear, HTTP_Message::next, Long_Poll_Request::next, Long_Poll_Request::prev, reschedule_peer_timeout(), GNUNET_MessageHeader::size, HTTP_Message::size, Long_Poll_Request::stream, Stream::stream_id, stream_send_data(), submit_post_request(), Connection::submitted_msg_queue_head, Long_Poll_Request::timer, and timestamp().

Referenced by setup_connection_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 1485 of file gnunet-communicator-http3.c.

1486{
1487 struct Connection *connection = impl_state;
1489 "Default MQ destroyed\n");
1490 if (mq == connection->d_mq)
1491 {
1492 connection->d_mq = NULL;
1493 if (GNUNET_YES != connection->connection_destroy_called)
1494 connection_destroy (connection);
1495 }
1496}

References connection_destroy(), Connection::connection_destroy_called, Connection::d_mq, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, and mq.

Referenced by setup_connection_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 1506 of file gnunet-communicator-http3.c.

1507{
1508 /* Cancellation is impossible with QUIC; bail */
1509 GNUNET_assert (0);
1510}

References GNUNET_assert.

Referenced by setup_connection_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 1523 of file gnunet-communicator-http3.c.

1524{
1525 struct Connection *connection = cls;
1527 "MQ error in queue to %s: %d\n",
1528 GNUNET_i2s (&connection->target),
1529 (int) error);
1530 connection_destroy (connection);
1531}
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_PeerIdentity target
To whom are we talking to.

References connection_destroy(), GNUNET_ERROR_TYPE_ERROR, GNUNET_i2s(), GNUNET_log, and Connection::target.

Referenced by setup_connection_mq().

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

◆ setup_connection_mq()

static void setup_connection_mq ( struct Connection connection)
static

Setup the MQ for the connection.

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

Parameters
connectionconnection to setup MQ for

Definition at line 1542 of file gnunet-communicator-http3.c.

1543{
1544 size_t base_mtu;
1545
1547 "setup_connection_mq: init = %u\n",
1548 connection->is_initiator);
1549 switch (connection->address->sa_family)
1550 {
1551 case AF_INET:
1552 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
1553 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
1554 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
1555 break;
1556 case AF_INET6:
1557 base_mtu = 1280 /* Minimum MTU required by IPv6 */
1558 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
1559 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
1560 break;
1561 default:
1562 GNUNET_assert (0);
1563 break;
1564 }
1565 /* MTU == base_mtu */
1566 connection->d_mtu = base_mtu;
1567
1568 if (NULL == connection->d_mq)
1570 &mq_destroy_d,
1571 &mq_cancel,
1572 connection,
1573 NULL,
1574 &mq_error,
1575 connection);
1576 connection->d_qh =
1578 &connection->target,
1579 connection->foreign_addr,
1580 1080,
1582 0, /* Priority */
1583 connection->nt,
1585 connection->d_mq);
1586}
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 struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
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
enum GNUNET_NetworkType nt
Which network type does this queue use?
Standard IPv4 header.
Standard IPv6 header.
UDP packet header.

References Connection::address, ch, Connection::d_mq, Connection::d_mtu, Connection::d_qh, Connection::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, Connection::is_initiator, mq_cancel(), mq_destroy_d(), mq_error(), mq_send_d(), Connection::nt, and Connection::target.

Referenced by http_recv_data_cb(), and recv_rx_key_cb().

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

◆ http_consume()

static void http_consume ( struct Connection connection,
int64_t  stream_id,
size_t  consumed 
)
static

Extend connection and stream offset.

Definition at line 1593 of file gnunet-communicator-http3.c.

1594{
1595 ngtcp2_conn_extend_max_stream_offset (connection->conn,
1596 stream_id,
1597 consumed);
1598 ngtcp2_conn_extend_max_offset (connection->conn,
1599 consumed);
1600}

References Connection::conn.

Referenced by http_deferred_consume_cb(), http_recv_data_cb(), and recv_stream_data_cb().

Here is the caller graph for this function:

◆ http_stream_close_cb()

static int http_stream_close_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
uint64_t  app_error_code,
void *  conn_user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.stream_close.

Definition at line 1607 of file gnunet-communicator-http3.c.

1610{
1611 struct Connection *connection = conn_user_data;
1612
1613 remove_stream (connection, stream_id);
1615 "HTTP stream %lu closed\n",
1616 (unsigned long) stream_id);
1617 if (GNUNET_NO == connection->is_initiator &&
1618 ngtcp2_is_bidi_stream (stream_id))
1619 {
1620 ngtcp2_conn_extend_max_streams_bidi (connection->conn, 1);
1621 }
1622 else if (GNUNET_YES == connection->is_initiator &&
1623 ! ngtcp2_is_bidi_stream (stream_id))
1624 {
1625 ngtcp2_conn_extend_max_streams_uni (connection->conn, 1);
1626 }
1627
1628 return 0;
1629}
static void remove_stream(struct Connection *connection, int64_t stream_id)
Remove the stream with the specified stream_id in connection.

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_YES, Connection::is_initiator, and remove_stream().

Referenced by setup_httpconn().

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

◆ http_recv_data_cb()

static int http_recv_data_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
const uint8_t *  data,
size_t  datalen,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.recv_data.

Definition at line 1636 of file gnunet-communicator-http3.c.

1642{
1643 struct Connection *connection = user_data;
1644 struct GNUNET_PeerIdentity *pid;
1645 struct GNUNET_MessageHeader *hdr;
1646 int rv;
1647
1649 "http_recv_data_cb\n");
1650 http_consume (connection, stream_id, datalen);
1651
1652 if (GNUNET_NO == connection->is_initiator &&
1653 GNUNET_NO == connection->id_rcvd)
1654 {
1655 if (datalen < sizeof (struct GNUNET_PeerIdentity))
1656 {
1658 "message recv len of %zd less than length of peer identity\n",
1659 datalen);
1660 return NGHTTP3_ERR_CALLBACK_FAILURE;
1661 }
1662 pid = (struct GNUNET_PeerIdentity *) data;
1663 connection->target = *pid;
1664 connection->id_rcvd = GNUNET_YES;
1665 setup_connection_mq (connection);
1666
1667 return GNUNET_NO;
1668 }
1669
1670 hdr = (struct GNUNET_MessageHeader *) data;
1672 &connection->target,
1673 hdr,
1675 NULL,
1676 NULL);
1677 if (GNUNET_SYSERR == rv)
1678 {
1680 "GNUNET_TRANSPORT_communicator_receive:%d, hdr->len = %u, datalen = %lu, init = %d\n",
1681 rv, ntohs (hdr->size), datalen, connection->is_initiator);
1682 return NGHTTP3_ERR_CALLBACK_FAILURE;
1683 }
1685 "GNUNET_TRANSPORT_communicator_receive:%d, hdr->len = %u, datalen = %lu, init = %d\n",
1686 rv, ntohs (hdr->size), datalen, connection->is_initiator);
1687 return 0;
1688}
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
static void http_consume(struct Connection *connection, int64_t stream_id, size_t consumed)
Extend connection and stream offset.
static void setup_connection_mq(struct Connection *connection)
Setup the MQ for the connection.
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.
int id_rcvd
Flag to indicate whether we know the PeerIdentity (target) yet.
Header for all communications.
The identity of the host (wraps the signing key of the peer).

References ADDRESS_VALIDITY_PERIOD, ch, data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, GNUNET_TRANSPORT_communicator_receive(), GNUNET_YES, http_consume(), Connection::id_rcvd, Connection::is_initiator, pid, setup_connection_mq(), GNUNET_MessageHeader::size, and Connection::target.

Referenced by setup_httpconn().

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

◆ http_deferred_consume_cb()

static int http_deferred_consume_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
size_t  nconsumed,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.deferred_consume.

Definition at line 1695 of file gnunet-communicator-http3.c.

1700{
1701 struct Connection *connection = user_data;
1702
1703 http_consume (connection,
1704 stream_id,
1705 nconsumed);
1706 return 0;
1707}

References http_consume().

Referenced by setup_httpconn().

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

◆ http_begin_headers_cb()

static int http_begin_headers_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.begin_headers.

Definition at line 1714 of file gnunet-communicator-http3.c.

1716{
1717 struct Connection *connection = user_data;
1718 struct Stream *stream;
1719
1720 stream = find_stream (connection, stream_id);
1721 if (NULL == stream)
1722 {
1723 return NGHTTP3_ERR_CALLBACK_FAILURE;
1724 }
1725 nghttp3_conn_set_stream_user_data (connection->h3_conn, stream_id, stream);
1726
1727 return 0;
1728}
static struct Stream * find_stream(struct Connection *connection, int64_t stream_id)
Find the stream specified with stream_id in connection and return the pointer of the stream,...

References Stream::connection, find_stream(), Connection::h3_conn, and Stream::stream_id.

Referenced by setup_httpconn().

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

◆ http_recv_header_cb()

static int http_recv_header_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
int32_t  token,
nghttp3_rcbuf *  name,
nghttp3_rcbuf *  value,
uint8_t  flags,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.recv_header.

Definition at line 1735 of file gnunet-communicator-http3.c.

1738{
1739 nghttp3_vec namebuf = nghttp3_rcbuf_get_buf (name);
1740 nghttp3_vec valbuf = nghttp3_rcbuf_get_buf (value);
1741 struct Connection *connection = user_data;
1742
1743 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "http header: [%.*s: %.*s]\n",
1744 (int) namebuf.len, namebuf.base,
1745 (int) valbuf.len, valbuf.base);
1746
1747 if (GNUNET_NO == connection->is_initiator)
1748 {
1749 struct Stream *stream = stream_user_data;
1750 switch (token)
1751 {
1752 case NGHTTP3_QPACK_TOKEN__PATH:
1753 stream->urilen = valbuf.len;
1754 stream->uri = (uint8_t *) malloc (valbuf.len);
1755 memcpy (stream->uri, valbuf.base, valbuf.len);
1756 break;
1757 case NGHTTP3_QPACK_TOKEN__METHOD:
1758 stream->methodlen = valbuf.len;
1759 stream->method = (uint8_t *) malloc (valbuf.len);
1760 memcpy (stream->method, valbuf.base, valbuf.len);
1761 break;
1762 case NGHTTP3_QPACK_TOKEN__AUTHORITY:
1763 stream->authoritylen = valbuf.len;
1764 stream->authority = (uint8_t *) malloc (valbuf.len);
1765 memcpy (stream->authority, valbuf.base, valbuf.len);
1766 break;
1767 }
1768 }
1769 return 0;
1770}
size_t urilen
The length of request uri.
size_t authoritylen
The length of request authority.

References Stream::authority, Stream::authoritylen, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, Connection::is_initiator, Stream::method, Stream::methodlen, name, Stream::uri, Stream::urilen, and value.

Referenced by setup_httpconn().

Here is the caller graph for this function:

◆ http_stop_sending_cb()

static int http_stop_sending_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
uint64_t  app_error_code,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.stop_sending.

Definition at line 1777 of file gnunet-communicator-http3.c.

1780{
1781 struct Connection *connection = user_data;
1782 int rv;
1783
1784 rv = ngtcp2_conn_shutdown_stream_read (connection->conn,
1785 0,
1786 stream_id,
1787 app_error_code);
1788 if (0 != rv)
1789 {
1791 "ngtcp2_conn_shutdown_stream_read: %s\n",
1792 ngtcp2_strerror (rv));
1793 return NGHTTP3_ERR_CALLBACK_FAILURE;
1794 }
1795 return 0;
1796}

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by setup_httpconn().

Here is the caller graph for this function:

◆ http_end_stream_cb()

static int http_end_stream_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.end_stream.

When the client side receives the response to Long polling, it sends a new GET request again.

Definition at line 1803 of file gnunet-communicator-http3.c.

1805{
1806 struct Connection *connection = user_data;
1807 struct Stream *stream = stream_user_data;
1808 struct Long_Poll_Request *long_poll;
1809 int rv;
1810
1811 if (GNUNET_NO == connection->is_initiator)
1812 {
1813 // Send response
1814 rv = stream_start_response (connection, stream);
1815 if (0 != rv)
1816 {
1817 return NGHTTP3_ERR_CALLBACK_FAILURE;
1818 }
1819 }
1820 else
1821 {
1826 long_poll = connection->long_poll_head;
1827 while (NULL != long_poll)
1828 {
1829 if (stream_id == long_poll->stream->stream_id)
1830 {
1832 "client side recv GET response\n");
1833 stream = create_stream (connection, -1);
1834 rv = ngtcp2_conn_open_bidi_stream (connection->conn,
1836 if (0 != rv)
1837 {
1839 "ngtcp2_conn_open_bidi_stream: %s\n",
1840 ngtcp2_strerror (rv));
1841 }
1842 submit_get_request (connection, stream);
1843 long_poll->stream = stream;
1844 break;
1845 }
1846 long_poll = long_poll->next;
1847 }
1848 }
1849 return 0;
1850}
static int stream_start_response(struct Connection *connection, struct Stream *stream)
Make response to the request.
static int submit_get_request(struct Connection *connection, struct Stream *stream)
Client side submits the GET request, allow the server to send messages.

References Connection::conn, create_stream(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, Connection::is_initiator, Connection::long_poll_head, Long_Poll_Request::next, Long_Poll_Request::stream, Stream::stream_id, stream_start_response(), and submit_get_request().

Referenced by setup_httpconn().

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

◆ http_reset_stream_cb()

static int http_reset_stream_cb ( nghttp3_conn *  conn,
int64_t  stream_id,
uint64_t  app_error_code,
void *  user_data,
void *  stream_user_data 
)
static

The callback of nghttp3_callback.reset_stream.

Definition at line 1857 of file gnunet-communicator-http3.c.

1860{
1861 struct Connection *connection = user_data;
1862 int rv;
1863
1864 rv = ngtcp2_conn_shutdown_stream_write (connection->conn,
1865 0,
1866 stream_id,
1867 app_error_code);
1868 if (0 != rv)
1869 {
1871 "ngtcp2_conn_shutdown_stream_write: %s\n",
1872 ngtcp2_strerror (rv));
1873 return NGHTTP3_ERR_CALLBACK_FAILURE;
1874 }
1875 return 0;
1876}

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by setup_httpconn().

Here is the caller graph for this function:

◆ setup_httpconn()

static int setup_httpconn ( struct Connection connection)
static

Setup the http3 connection.

Parameters
connectionthe connection
Returns
GNUNET_NO if success, GNUNET_SYSERR if failed

Definition at line 1887 of file gnunet-communicator-http3.c.

1888{
1889 nghttp3_settings settings;
1890 const nghttp3_mem *mem = nghttp3_mem_default ();
1891 int64_t ctrl_stream_id;
1892 int64_t enc_stream_id;
1893 int64_t dec_stream_id;
1894 nghttp3_callbacks callbacks = {
1895 .stream_close = http_stream_close_cb,
1896 .recv_data = http_recv_data_cb,
1897 .deferred_consume = http_deferred_consume_cb,
1898 .begin_headers = http_begin_headers_cb,
1899 .recv_header = http_recv_header_cb,
1900 .stop_sending = http_stop_sending_cb,
1901 .end_stream = http_end_stream_cb,
1902 .reset_stream = http_reset_stream_cb,
1903 };
1904 int rv;
1905
1906 if (NULL != connection->h3_conn)
1907 {
1908 return GNUNET_NO;
1909 }
1910
1911 if (ngtcp2_conn_get_streams_uni_left (connection->conn) < 3)
1912 {
1914 "uni stream left less than 3\n");
1915 return GNUNET_SYSERR;
1916 }
1917
1918 if (GNUNET_YES == connection->is_initiator)
1919 {
1920 callbacks.begin_headers = NULL;
1921 // callbacks.end_stream = NULL;
1922 }
1923
1924 nghttp3_settings_default (&settings);
1925 settings.qpack_blocked_streams = 100;
1926 settings.qpack_encoder_max_dtable_capacity = 4096;
1927
1928 if (GNUNET_NO == connection->is_initiator)
1929 {
1930 const ngtcp2_transport_params *params =
1931 ngtcp2_conn_get_local_transport_params (connection->conn);
1932
1933 rv = nghttp3_conn_server_new (&connection->h3_conn,
1934 &callbacks,
1935 &settings,
1936 mem,
1937 connection);
1938 nghttp3_conn_set_max_client_streams_bidi (connection->h3_conn,
1939 params->initial_max_streams_bidi);
1940 if (0 != rv)
1941 {
1943 "nghttp3_conn_server_new: %s\n",
1944 nghttp3_strerror (rv));
1945 return GNUNET_SYSERR;
1946 }
1947 }
1948 else
1949 {
1950 rv = nghttp3_conn_client_new (&connection->h3_conn,
1951 &callbacks,
1952 &settings,
1953 mem,
1954 connection);
1955 if (0 != rv)
1956 {
1958 "nghttp3_conn_client_new: %s\n",
1959 nghttp3_strerror (rv));
1960 return GNUNET_SYSERR;
1961 }
1962 }
1963
1964 rv = ngtcp2_conn_open_uni_stream (connection->conn, &ctrl_stream_id, NULL);
1965 if (0 != rv)
1966 {
1968 "ngtcp2_conn_open_uni_stream: %s\n",
1969 ngtcp2_strerror (rv));
1970 return GNUNET_SYSERR;
1971 }
1972
1973 rv = nghttp3_conn_bind_control_stream (connection->h3_conn, ctrl_stream_id);
1974 if (0 != rv)
1975 {
1977 "nghttp3_conn_bind_control_stream: %s\n",
1978 nghttp3_strerror (rv));
1979 return GNUNET_SYSERR;
1980 }
1981
1982 rv = ngtcp2_conn_open_uni_stream (connection->conn, &enc_stream_id, NULL);
1983 if (0 != rv)
1984 {
1986 "ngtcp2_conn_open_uni_stream: %s\n",
1987 ngtcp2_strerror (rv));
1988 return GNUNET_SYSERR;
1989 }
1990
1991 rv = ngtcp2_conn_open_uni_stream (connection->conn, &dec_stream_id, NULL);
1992 if (0 != rv)
1993 {
1995 "ngtcp2_conn_open_uni_stream: %s\n",
1996 ngtcp2_strerror (rv));
1997 return GNUNET_SYSERR;
1998 }
1999
2000 rv = nghttp3_conn_bind_qpack_streams (connection->h3_conn,
2001 enc_stream_id, dec_stream_id);
2002 if (0 != rv)
2003 {
2005 "nghttp3_conn_bind_qpack_streams: %s\n",
2006 nghttp3_strerror (rv));
2007 return GNUNET_SYSERR;
2008 }
2009
2011 "Bind control stream: %" PRIi64 ", enc stream: %" PRIi64
2012 ", dec stream: %" PRIi64 "\n",
2013 ctrl_stream_id, enc_stream_id, dec_stream_id);
2014 return GNUNET_NO;
2015}
static int http_reset_stream_cb(nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.reset_stream.
static int http_stop_sending_cb(nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.stop_sending.
static int http_end_stream_cb(nghttp3_conn *conn, int64_t stream_id, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.end_stream.
static int http_recv_data_cb(nghttp3_conn *conn, int64_t stream_id, const uint8_t *data, size_t datalen, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.recv_data.
static int http_begin_headers_cb(nghttp3_conn *conn, int64_t stream_id, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.begin_headers.
static int http_deferred_consume_cb(nghttp3_conn *conn, int64_t stream_id, size_t nconsumed, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.deferred_consume.
static int http_stream_close_cb(nghttp3_conn *conn, int64_t stream_id, uint64_t app_error_code, void *conn_user_data, void *stream_user_data)
The callback of nghttp3_callback.stream_close.
static int http_recv_header_cb(nghttp3_conn *conn, int64_t stream_id, int32_t token, nghttp3_rcbuf *name, nghttp3_rcbuf *value, uint8_t flags, void *user_data, void *stream_user_data)
The callback of nghttp3_callback.recv_header.

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, Connection::h3_conn, http_begin_headers_cb(), http_deferred_consume_cb(), http_end_stream_cb(), http_recv_data_cb(), http_recv_header_cb(), http_reset_stream_cb(), http_stop_sending_cb(), http_stream_close_cb(), and Connection::is_initiator.

Referenced by recv_rx_key_cb(), and recv_tx_key_cb().

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

◆ rand_cb()

static void rand_cb ( uint8_t *  dest,
size_t  destlen,
const ngtcp2_rand_ctx *  rand_ctx 
)
static

The callback function for ngtcp2_callbacks.rand.

Definition at line 2022 of file gnunet-communicator-http3.c.

2025{
2026 (void) rand_ctx;
2028 dest,
2029 destlen);
2030}
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.

References GNUNET_CRYPTO_QUALITY_STRONG, and GNUNET_CRYPTO_random_block().

Referenced by client_quic_init(), and connection_init().

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

◆ get_new_connection_id_cb()

static int get_new_connection_id_cb ( ngtcp2_conn *  conn,
ngtcp2_cid *  cid,
uint8_t *  token,
size_t  cidlen,
void *  user_data 
)
static

The callback function for ngtcp2_callbacks.get_new_connection_id.

Definition at line 2037 of file gnunet-communicator-http3.c.

2040{
2041 (void) conn;
2042 (void) user_data;
2043
2045 cid->data,
2046 cidlen);
2047 cid->datalen = cidlen;
2049 token,
2050 NGTCP2_STATELESS_RESET_TOKENLEN);
2051 return GNUNET_NO;
2052}

References Connection::conn, GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_block(), and GNUNET_NO.

Referenced by client_quic_init(), and connection_init().

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

◆ recv_stream_data_cb()

static int recv_stream_data_cb ( ngtcp2_conn *  conn,
uint32_t  flags,
int64_t  stream_id,
uint64_t  offset,
const uint8_t *  data,
size_t  datalen,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.recv_stream_data.

Definition at line 2059 of file gnunet-communicator-http3.c.

2063{
2064 struct Connection *connection = user_data;
2065 nghttp3_ssize nconsumed;
2066
2067 if (NULL == connection->h3_conn)
2068 {
2069 return 0;
2070 }
2071 nconsumed = nghttp3_conn_read_stream (connection->h3_conn, stream_id,
2072 data, datalen,
2073 flags & NGTCP2_STREAM_DATA_FLAG_FIN);
2074 if (nconsumed < 0)
2075 {
2077 "nghttp3_conn_read_stream: %s, init = %d\n",
2078 nghttp3_strerror (nconsumed), connection->is_initiator);
2079 ngtcp2_ccerr_set_application_error (
2080 &connection->last_error,
2081 nghttp3_err_infer_quic_app_error_code (nconsumed),
2082 NULL, 0);
2083 return NGTCP2_ERR_CALLBACK_FAILURE;
2084 }
2085 http_consume (connection, stream_id, nconsumed);
2086 return 0;
2087}
ngtcp2_ccerr last_error
The connection error.

References data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, Connection::h3_conn, http_consume(), Connection::is_initiator, and Connection::last_error.

Referenced by client_quic_init(), and connection_init().

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

◆ stream_open_cb()

static int stream_open_cb ( ngtcp2_conn *  conn,
int64_t  stream_id,
void *  user_data 
)
static

The callback function for ngtcp2_callbacks.stream_open.

Definition at line 2094 of file gnunet-communicator-http3.c.

2097{
2098 struct Connection *connection = user_data;
2099 if (! ngtcp2_is_bidi_stream (stream_id))
2100 {
2101 return 0;
2102 }
2103 create_stream (connection, stream_id);
2104 return 0;
2105}

References create_stream().

Referenced by connection_init().

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

◆ stream_close_cb()

static int stream_close_cb ( ngtcp2_conn *  conn,
uint32_t  flags,
int64_t  stream_id,
uint64_t  app_error_code,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.stream_close.

Returns
GNUNET_NO on success, #NGTCP2_ERR_CALLBACK_FAILURE if failed

Definition at line 2114 of file gnunet-communicator-http3.c.

2117{
2118 struct Connection *connection = user_data;
2119 int rv;
2120
2122 "stream_close id = %" PRIi64 "\n",
2123 stream_id);
2124 if (! (flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET))
2125 {
2126 app_error_code = NGHTTP3_H3_NO_ERROR;
2127 }
2128
2129 if (connection->h3_conn)
2130 {
2131 if (0 == app_error_code)
2132 {
2133 app_error_code = NGHTTP3_H3_NO_ERROR;
2134 }
2135
2136 rv = nghttp3_conn_close_stream (connection->h3_conn,
2137 stream_id,
2138 app_error_code);
2139 switch (rv)
2140 {
2141 case 0:
2142 break;
2143 case NGHTTP3_ERR_STREAM_NOT_FOUND:
2144 if (GNUNET_NO == connection->is_initiator &&
2145 ngtcp2_is_bidi_stream (stream_id))
2146 {
2147 ngtcp2_conn_extend_max_streams_bidi (connection->conn, 1);
2148 }
2149 else if (GNUNET_YES == connection->is_initiator &&
2150 ! ngtcp2_is_bidi_stream (stream_id))
2151 {
2152 ngtcp2_conn_extend_max_streams_uni (connection->conn, 1);
2153 }
2154 break;
2155 default:
2157 "nghttp3_conn_close_stream: %s\n",
2158 nghttp3_strerror (rv));
2159 ngtcp2_ccerr_set_application_error (
2160 &connection->last_error,
2161 nghttp3_err_infer_quic_app_error_code (rv),
2162 NULL, 0);
2163 return NGTCP2_ERR_CALLBACK_FAILURE;
2164 }
2165 }
2166 return 0;
2167}

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_YES, Connection::h3_conn, Connection::is_initiator, and Connection::last_error.

Referenced by client_quic_init(), and connection_init().

Here is the caller graph for this function:

◆ acked_stream_data_offset_cb()

static int acked_stream_data_offset_cb ( ngtcp2_conn *  conn,
int64_t  stream_id,
uint64_t  offset,
uint64_t  datalen,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.acked_stream_data_offset.

Definition at line 2174 of file gnunet-communicator-http3.c.

2177{
2178 struct Connection *connection = user_data;
2179 int rv;
2180
2181 if (NULL == connection->h3_conn)
2182 {
2183 return 0;
2184 }
2185
2186 rv = nghttp3_conn_add_ack_offset (connection->h3_conn, stream_id, datalen);
2187 if (0 != rv)
2188 {
2190 "nghttp3_conn_add_ack_offset: %s\n",
2191 nghttp3_strerror (rv));
2192 return NGTCP2_ERR_CALLBACK_FAILURE;
2193 }
2194 return 0;
2195}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and Connection::h3_conn.

Referenced by client_quic_init(), and connection_init().

Here is the caller graph for this function:

◆ extend_max_stream_data_cb()

static int extend_max_stream_data_cb ( ngtcp2_conn *  conn,
int64_t  stream_id,
uint64_t  max_data,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.extend_max_stream_data.

Definition at line 2202 of file gnunet-communicator-http3.c.

2205{
2206 struct Connection *connection = user_data;
2207 int rv;
2208
2209 rv = nghttp3_conn_unblock_stream (connection->h3_conn, stream_id);
2210 if (0 != rv)
2211 {
2213 "nghttp3_conn_unblock_stream: %s\n",
2214 nghttp3_strerror (rv));
2215 return NGTCP2_ERR_CALLBACK_FAILURE;
2216 }
2217 return 0;
2218}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and Connection::h3_conn.

Referenced by client_quic_init(), and connection_init().

Here is the caller graph for this function:

◆ stream_reset_cb()

static int stream_reset_cb ( ngtcp2_conn *  conn,
int64_t  stream_id,
uint64_t  final_size,
uint64_t  app_error_code,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.stream_reset.

Definition at line 2225 of file gnunet-communicator-http3.c.

2228{
2229 struct Connection *connection = user_data;
2230 int rv;
2231
2232 if (connection->h3_conn)
2233 {
2234 rv = nghttp3_conn_shutdown_stream_read (connection->h3_conn, stream_id);
2235 if (0 != rv)
2236 {
2238 "nghttp3_conn_shutdown_stream_read: %s\n",
2239 nghttp3_strerror (rv));
2240 return NGTCP2_ERR_CALLBACK_FAILURE;
2241 }
2242 }
2243 return 0;
2244}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and Connection::h3_conn.

Referenced by client_quic_init().

Here is the caller graph for this function:

◆ extend_max_remote_streams_bidi_cb()

static int extend_max_remote_streams_bidi_cb ( ngtcp2_conn *  conn,
uint64_t  max_streams,
void *  user_data 
)
static

The callback function for ngtcp2_callbacks.extend_max_remote_streams_bidi.

Definition at line 2251 of file gnunet-communicator-http3.c.

2253{
2254 struct Connection *connection = user_data;
2255 if (NULL == connection->h3_conn)
2256 {
2257 return 0;
2258 }
2259 nghttp3_conn_set_max_client_streams_bidi (connection->h3_conn, max_streams);
2260 return 0;
2261}

References Connection::h3_conn.

Referenced by connection_init().

Here is the caller graph for this function:

◆ stream_stop_sending_cb()

static int stream_stop_sending_cb ( ngtcp2_conn *  conn,
int64_t  stream_id,
uint64_t  app_error_code,
void *  user_data,
void *  stream_user_data 
)
static

The callback function for ngtcp2_callbacks.stream_stop_sending.

Definition at line 2268 of file gnunet-communicator-http3.c.

2271{
2272 struct Connection *connection = user_data;
2273 int rv;
2274
2275 if (connection->h3_conn)
2276 {
2277 rv = nghttp3_conn_shutdown_stream_read (connection->h3_conn, stream_id);
2278 if (0 != rv)
2279 {
2281 "nghttp3_conn_shutdown_stream_read: %s\n",
2282 nghttp3_strerror (rv));
2283 return NGTCP2_ERR_CALLBACK_FAILURE;
2284 }
2285 }
2286 return 0;
2287}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and Connection::h3_conn.

Referenced by client_quic_init(), and connection_init().

Here is the caller graph for this function:

◆ recv_tx_key_cb()

static int recv_tx_key_cb ( ngtcp2_conn *  conn,
ngtcp2_encryption_level  level,
void *  user_data 
)
static

The callback function for ngtcp2_callbacks.recv_tx_key.

Definition at line 2294 of file gnunet-communicator-http3.c.

2296{
2297 struct Connection *connection = user_data;
2298 int rv;
2299
2300 if (NGTCP2_ENCRYPTION_LEVEL_1RTT != level)
2301 {
2302 return 0;
2303 }
2304
2305 rv = setup_httpconn (connection);
2306 if (0 != rv)
2307 {
2308 return NGTCP2_ERR_CALLBACK_FAILURE;
2309 }
2310 return 0;
2311}
static int setup_httpconn(struct Connection *connection)
Setup the http3 connection.

References setup_httpconn().

Referenced by connection_init().

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

◆ recv_rx_key_cb()

static int recv_rx_key_cb ( ngtcp2_conn *  conn,
ngtcp2_encryption_level  level,
void *  user_data 
)
static

The callback function for ngtcp2_callbacks.recv_rx_key.

Definition at line 2318 of file gnunet-communicator-http3.c.

2320{
2321 struct Connection *connection = user_data;
2322 struct Stream *stream;
2323 struct Long_Poll_Request *long_poll;
2324 int i;
2325 int rv;
2326
2327 if (NGTCP2_ENCRYPTION_LEVEL_1RTT != level)
2328 {
2329 return 0;
2330 }
2331
2332 rv = setup_httpconn (connection);
2333 if (0 != rv)
2334 {
2335 return NGTCP2_ERR_CALLBACK_FAILURE;
2336 }
2337
2338 if (GNUNET_YES == connection->is_initiator &&
2339 GNUNET_NO == connection->id_sent)
2340 {
2341 const struct GNUNET_PeerIdentity *my_identity;
2342
2345
2346 stream = create_stream (connection, -1);
2347 rv = ngtcp2_conn_open_bidi_stream (conn, &stream->stream_id, NULL);
2348
2349 submit_post_request (connection, stream,
2350 (uint8_t *) my_identity,
2351 sizeof (*my_identity));
2352
2353 connection->id_sent = GNUNET_YES;
2354 setup_connection_mq (connection);
2355
2356 for (i = 0; i < NUM_LONG_POLL; i++)
2357 {
2358 stream = create_stream (connection, -1);
2359 rv = ngtcp2_conn_open_bidi_stream (conn, &stream->stream_id, NULL);
2360 submit_get_request (connection, stream);
2361 long_poll = GNUNET_new (struct Long_Poll_Request);
2362 long_poll->stream = stream;
2363 long_poll->next = NULL;
2364 long_poll->prev = connection->long_poll_rear;
2365 long_poll->timer = NULL;
2366 if (NULL != connection->long_poll_rear)
2367 {
2368 connection->long_poll_rear->next = long_poll;
2369 }
2370 connection->long_poll_rear = long_poll;
2371 if (NULL == connection->long_poll_head)
2372 {
2373 connection->long_poll_head = long_poll;
2374 }
2375 }
2376 }
2377 return 0;
2378}
static struct GNUNET_PILS_Handle * pils
Handle to the pils service.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
int id_sent
Flag to indicate whether we have sent OUR PeerIdentity to this peer.

References create_stream(), GNUNET_assert, GNUNET_new, GNUNET_NO, GNUNET_PILS_get_identity(), GNUNET_YES, Connection::id_sent, Connection::is_initiator, Connection::long_poll_head, Connection::long_poll_rear, my_identity, Long_Poll_Request::next, NUM_LONG_POLL, pils, Long_Poll_Request::prev, setup_connection_mq(), setup_httpconn(), Long_Poll_Request::stream, Stream::stream_id, submit_get_request(), submit_post_request(), and Long_Poll_Request::timer.

Referenced by client_quic_init().

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

◆ client_quic_init()

static int client_quic_init ( struct Connection connection,
struct sockaddr *  local_addr,
socklen_t  local_addrlen,
struct sockaddr *  remote_addr,
socklen_t  remote_addrlen 
)
static

Create new ngtcp2_conn as client side.

Parameters
connectionnew connection of the peer
local_addrlocal socket address
local_addrlenlocal socket address length
remote_addrremote(peer's) socket address
remote_addrlenremote socket address length
Returns
GNUNET_NO on success, GNUNET_SYSERR if failed to create new ngtcp2_conn as client

Definition at line 2394 of file gnunet-communicator-http3.c.

2399{
2400 int rv;
2401 ngtcp2_cid dcid;
2402 ngtcp2_cid scid;
2403 ngtcp2_settings settings;
2404 ngtcp2_transport_params params;
2405 ngtcp2_path path = {
2406 {local_addr, local_addrlen},
2407 {remote_addr, remote_addrlen},
2408 NULL,
2409 };
2410 ngtcp2_callbacks callbacks = {
2411 .client_initial = ngtcp2_crypto_client_initial_cb,
2412 .recv_crypto_data = ngtcp2_crypto_recv_crypto_data_cb,
2413 .encrypt = ngtcp2_crypto_encrypt_cb,
2414 .decrypt = ngtcp2_crypto_decrypt_cb,
2415 .hp_mask = ngtcp2_crypto_hp_mask_cb,
2416 .recv_retry = ngtcp2_crypto_recv_retry_cb,
2417 .update_key = ngtcp2_crypto_update_key_cb,
2418 .delete_crypto_aead_ctx = ngtcp2_crypto_delete_crypto_aead_ctx_cb,
2419 .delete_crypto_cipher_ctx = ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
2420 .get_path_challenge_data = ngtcp2_crypto_get_path_challenge_data_cb,
2421 .version_negotiation = ngtcp2_crypto_version_negotiation_cb,
2422 .rand = rand_cb,
2423 .get_new_connection_id = get_new_connection_id_cb,
2424 .recv_stream_data = recv_stream_data_cb,
2425 .stream_close = stream_close_cb,
2426 .acked_stream_data_offset = acked_stream_data_offset_cb,
2427 .extend_max_stream_data = extend_max_stream_data_cb,
2428 .stream_reset = stream_reset_cb,
2429 .stream_stop_sending = stream_stop_sending_cb,
2430 .recv_rx_key = recv_rx_key_cb,
2431 };
2432
2433
2434 scid.datalen = NGTCP2_MAX_CIDLEN;
2436 scid.data,
2437 scid.datalen);
2438 dcid.datalen = NGTCP2_MAX_CIDLEN;
2440 dcid.data,
2441 dcid.datalen);
2442 ngtcp2_settings_default (&settings);
2443 settings.initial_ts = timestamp ();
2444
2445 ngtcp2_transport_params_default (&params);
2446 params.initial_max_streams_uni = 100;
2447 params.initial_max_stream_data_bidi_local = 6291456;
2448 params.initial_max_data = 15728640;
2449 params.initial_max_stream_data_bidi_remote = 0;
2450 params.initial_max_stream_data_uni = 6291456;
2451 params.initial_max_streams_bidi = 0;
2452 params.max_idle_timeout = 30 * NGTCP2_SECONDS;
2453 params.active_connection_id_limit = 7;
2454 params.grease_quic_bit = 1;
2455 rv = ngtcp2_conn_client_new (&connection->conn,
2456 &dcid,
2457 &scid,
2458 &path,
2459 NGTCP2_PROTO_VER_V1,
2460 &callbacks,
2461 &settings,
2462 &params,
2463 NULL,
2464 connection);
2465 if (GNUNET_NO != rv)
2466 {
2468 "ngtcp2_conn_client_new: %s\n",
2469 ngtcp2_strerror (rv));
2470 return GNUNET_SYSERR;
2471 }
2472 ngtcp2_conn_set_tls_native_handle (connection->conn, connection->session);
2473 connection->conn_ref.user_data = connection;
2474 connection->conn_ref.get_conn = get_conn;
2475 return GNUNET_NO;
2476}
static int recv_stream_data_cb(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id, uint64_t offset, const uint8_t *data, size_t datalen, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.recv_stream_data.
static int extend_max_stream_data_cb(ngtcp2_conn *conn, int64_t stream_id, uint64_t max_data, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.extend_max_stream_data.
static void rand_cb(uint8_t *dest, size_t destlen, const ngtcp2_rand_ctx *rand_ctx)
The callback function for ngtcp2_callbacks.rand.
static int stream_stop_sending_cb(ngtcp2_conn *conn, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.stream_stop_sending.
static int get_new_connection_id_cb(ngtcp2_conn *conn, ngtcp2_cid *cid, uint8_t *token, size_t cidlen, void *user_data)
The callback function for ngtcp2_callbacks.get_new_connection_id.
static int acked_stream_data_offset_cb(ngtcp2_conn *conn, int64_t stream_id, uint64_t offset, uint64_t datalen, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.acked_stream_data_offset.
static int stream_reset_cb(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size, uint64_t app_error_code, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.stream_reset.
static ngtcp2_conn * get_conn(ngtcp2_crypto_conn_ref *ref)
The callback function for ngtcp2_crypto_conn_ref.
static int stream_close_cb(ngtcp2_conn *conn, uint32_t flags, int64_t stream_id, uint64_t app_error_code, void *user_data, void *stream_user_data)
The callback function for ngtcp2_callbacks.stream_close.
static int recv_rx_key_cb(ngtcp2_conn *conn, ngtcp2_encryption_level level, void *user_data)
The callback function for ngtcp2_callbacks.recv_rx_key.
static char * remote_addr
Remote address to use for connection reversal request.
Definition gnunet-nat.c:70
static char * local_addr
Local address to use for connection reversal request.
Definition gnunet-nat.c:65

References acked_stream_data_offset_cb(), Connection::conn, Connection::conn_ref, extend_max_stream_data_cb(), get_conn(), get_new_connection_id_cb(), GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_block(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SYSERR, local_addr, rand_cb(), recv_rx_key_cb(), recv_stream_data_cb(), remote_addr, Connection::session, stream_close_cb(), stream_reset_cb(), stream_stop_sending_cb(), and timestamp().

Referenced by mq_init().

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

◆ close_waitcb()

static void close_waitcb ( void *  cls)
static

The timeout callback function of closing/draining period.

Parameters
clsthe closure of Connection.

Definition at line 2485 of file gnunet-communicator-http3.c.

2486{
2487 struct Connection *connection = cls;
2488 connection->timer = NULL;
2489
2490 if (ngtcp2_conn_in_closing_period (connection->conn))
2491 {
2493 "Closing period over\n");
2494 connection_destroy (connection);
2495 return;
2496 }
2497 if (ngtcp2_conn_in_draining_period (connection->conn))
2498 {
2500 "Draining period over\n");
2501 connection_destroy (connection);
2502 return;
2503 }
2504}
struct GNUNET_SCHEDULER_Task * timer
The timer of this connection.

References Connection::conn, connection_destroy(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and Connection::timer.

Referenced by start_closing_period(), and start_draining_period().

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

◆ start_draining_period()

static void start_draining_period ( struct Connection connection)
static

Start the draining period, called after receiving CONNECTION_CLOSE.

Parameters
connectionThe connection

Definition at line 2513 of file gnunet-communicator-http3.c.

2514{
2515 ngtcp2_duration pto;
2516 struct GNUNET_TIME_Relative delay;
2517
2518 if (NULL != connection->timer)
2519 {
2520 GNUNET_SCHEDULER_cancel (connection->timer);
2521 connection->timer = NULL;
2522 }
2523 pto = ngtcp2_conn_get_pto (connection->conn);
2525 pto / 1000ULL * 3);
2526 connection->timer = GNUNET_SCHEDULER_add_delayed (delay,
2528 connection);
2530 "Start draining period\n");
2531}
static void close_waitcb(void *cls)
The timeout callback function of closing/draining period.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.

References close_waitcb(), Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MICROSECONDS, and Connection::timer.

Referenced by connection_feed_data().

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

◆ start_closing_period()

static int start_closing_period ( struct Connection connection)
static

Start the closing period and build the packet contains CONNECTION_CLOSE.

If we are server side, the function will set the close_waitcb and write the packet to the conn_closebuf. If we are client side, send the CONNECTION_CLOSE packet directly, and won't wait close.

Parameters
connectionthe connection
Returns
GNUNET_NO if success, GNUNET_SYSERR if failed.

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

2546{
2547 ngtcp2_path_storage ps;
2548 ngtcp2_pkt_info pi;
2549 ngtcp2_ssize nwrite;
2550 ngtcp2_duration pto;
2551 struct GNUNET_TIME_Relative delay;
2552
2553 if (NULL == connection->conn ||
2554 ngtcp2_conn_in_closing_period (connection->conn) ||
2555 ngtcp2_conn_in_draining_period (connection->conn))
2556 {
2557 return GNUNET_NO;
2558 }
2559
2561 "Start closing period\n");
2562
2563 if (GNUNET_NO == connection->is_initiator)
2564 {
2565 if (NULL != connection->timer)
2566 {
2567 GNUNET_SCHEDULER_cancel (connection->timer);
2568 connection->timer = NULL;
2569 }
2570 pto = ngtcp2_conn_get_pto (connection->conn);
2572 pto / 1000ULL * 3);
2573 connection->timer = GNUNET_SCHEDULER_add_delayed (delay,
2575 connection);
2576 }
2577
2578 connection->conn_closebuf =
2579 GNUNET_new_array (NGTCP2_MAX_UDP_PAYLOAD_SIZE, uint8_t);
2580
2581 ngtcp2_path_storage_zero (&ps);
2582 nwrite = ngtcp2_conn_write_connection_close (connection->conn,
2583 &ps.path,
2584 &pi,
2585 connection->conn_closebuf,
2586 NGTCP2_MAX_UDP_PAYLOAD_SIZE,
2587 &connection->last_error,
2588 timestamp ());
2589 if (nwrite < 0)
2590 {
2592 "ngtcp2_conn_write_connection_close: %s\n",
2593 ngtcp2_strerror (nwrite));
2594 return GNUNET_SYSERR;
2595 }
2596 if (0 == nwrite)
2597 {
2598 return GNUNET_NO;
2599 }
2600 connection->conn_closebuflen = nwrite;
2601 if (GNUNET_YES == connection->is_initiator)
2602 {
2603 return send_packet (connection,
2604 connection->conn_closebuf,
2605 connection->conn_closebuflen);
2606 }
2607 return GNUNET_NO;
2608}
static int send_packet(struct Connection *connection, const uint8_t *data, size_t datalen)
Send the udp packet to remote.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
ngtcp2_ssize conn_closebuflen
The length of conn_closebuf;.

References close_waitcb(), Connection::conn, Connection::conn_closebuf, Connection::conn_closebuflen, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new_array, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MICROSECONDS, GNUNET_YES, Connection::is_initiator, Connection::last_error, ps, send_packet(), Connection::timer, and timestamp().

Referenced by handle_error().

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

◆ send_conn_close()

static int send_conn_close ( struct Connection connection)
static

Send the packet in the conn_closebuf.

Parameters
connectionthe connection
Returns
GNUNET_NO if success, GNUNET_SYSERR if failed.

Definition at line 2618 of file gnunet-communicator-http3.c.

2619{
2620 int rv;
2621
2623 "Closing period, send CONNECTION_CLOSE\n");
2624 rv = send_packet (connection,
2625 connection->conn_closebuf,
2626 connection->conn_closebuflen);
2627 return rv;
2628}

References Connection::conn_closebuf, Connection::conn_closebuflen, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and send_packet().

Referenced by handle_error(), and server_read_pkt().

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

◆ handle_error()

static int handle_error ( struct Connection connection)
static

Handle errors.

Both server and client will use this function.

Parameters
connectionthe connection.
Returns
GNUNET_NO if success, GNUNET_SYSERR if failed or we are client side, NETWORK_ERR_CLOSE_WAIT if need to wait for close.

Definition at line 2639 of file gnunet-communicator-http3.c.

2640{
2641 int rv;
2642
2643 /* if we are the client side */
2644 if (GNUNET_YES == connection->is_initiator)
2645 {
2646 /* this will send CONNECTION_CLOSE immediately and don't wait */
2647 start_closing_period (connection);
2648 connection_destroy (connection);
2649 return GNUNET_SYSERR;
2650 }
2651
2652 if (NGTCP2_CCERR_TYPE_IDLE_CLOSE == connection->last_error.type)
2653 {
2654 return GNUNET_SYSERR;
2655 }
2656
2657 if (GNUNET_NO != start_closing_period (connection))
2658 {
2659 return GNUNET_SYSERR;
2660 }
2661
2662 if (ngtcp2_conn_in_draining_period (connection->conn))
2663 {
2665 }
2666
2667 rv = send_conn_close (connection);
2668 if (NETWORK_ERR_OK != rv)
2669 {
2670 return rv;
2671 }
2672
2674}
static int send_conn_close(struct Connection *connection)
Send the packet in the conn_closebuf.
static int start_closing_period(struct Connection *connection)
Start the closing period and build the packet contains CONNECTION_CLOSE.

References Connection::conn, connection_destroy(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, Connection::is_initiator, Connection::last_error, NETWORK_ERR_CLOSE_WAIT, NETWORK_ERR_OK, send_conn_close(), and start_closing_period().

Referenced by connection_feed_data(), connection_write_streams(), get_connection_delete_it(), and handle_expiry().

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

◆ handle_expiry()

static int handle_expiry ( struct Connection connection)
static

Handles expired timer.

Parameters
connectionthe connection
Returns
GNUNET_NO if success, else return handle_error.

Definition at line 2684 of file gnunet-communicator-http3.c.

2685{
2686 int rv;
2687
2688 rv = ngtcp2_conn_handle_expiry (connection->conn, timestamp ());
2689 if (0 != rv)
2690 {
2692 "ngtcp2_conn_handle_expiry: %s\n",
2693 ngtcp2_strerror (rv));
2694 ngtcp2_ccerr_set_liberr (&connection->last_error, rv, NULL, 0);
2695 return handle_error (connection);
2696 }
2697 return GNUNET_NO;
2698}
static int handle_error(struct Connection *connection)
Handle errors.

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, handle_error(), Connection::last_error, and timestamp().

Referenced by timeoutcb().

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

◆ timeoutcb()

static void timeoutcb ( void *  cls)
static

The timer callback function.

Parameters
clsThe closure of struct Connection.

Definition at line 2707 of file gnunet-communicator-http3.c.

2708{
2709 struct Connection *connection = cls;
2710 int rv;
2711
2713 "timeoutcb func called!\n");
2714 connection->timer = NULL;
2715
2716 rv = handle_expiry (connection);
2717 if (GNUNET_NO != rv)
2718 {
2719 if (GNUNET_YES == connection->is_initiator)
2720 {
2721 return;
2722 }
2723 switch (rv)
2724 {
2726 return;
2727 default:
2728 connection_destroy (connection);
2729 return;
2730 }
2731 }
2732
2733 rv = connection_write (connection);
2734 if (GNUNET_YES == connection->is_initiator)
2735 {
2736 return;
2737 }
2738 if (GNUNET_NO != rv)
2739 {
2740 switch (rv)
2741 {
2743 return;
2744 default:
2745 connection_destroy (connection);
2746 return;
2747 }
2748
2749 }
2750}
static int handle_expiry(struct Connection *connection)
Handles expired timer.

References connection_destroy(), connection_write(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_YES, handle_expiry(), Connection::is_initiator, NETWORK_ERR_CLOSE_WAIT, and Connection::timer.

Referenced by connection_update_timer().

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

◆ connection_update_timer()

static void connection_update_timer ( struct Connection connection)
static

Update the timer.

Parameters
connectionthe connection.

Definition at line 2759 of file gnunet-communicator-http3.c.

2760{
2761 ngtcp2_tstamp expiry;
2762 ngtcp2_tstamp now;
2763 struct GNUNET_TIME_Relative delay;
2764
2766 "update_timer!\n");
2767 expiry = ngtcp2_conn_get_expiry (connection->conn);
2768 now = timestamp ();
2769
2770 if (NULL != connection->timer)
2771 {
2772 GNUNET_SCHEDULER_cancel (connection->timer);
2773 connection->timer = NULL;
2774 }
2775 if (now >= expiry)
2776 {
2778 "Timer has expired\n");
2779 connection->timer = GNUNET_SCHEDULER_add_now (timeoutcb, connection);
2780 return;
2781 }
2782
2784 "Timer set: %lf\n",
2785 (double) (expiry - now) / NGTCP2_SECONDS);
2786 /* ngtcp2_tstamp is nanosecond */
2788 (expiry - now) / 1000ULL + 1);
2789 connection->timer = GNUNET_SCHEDULER_add_delayed (delay, timeoutcb,
2790 connection);
2791}
static void timeoutcb(void *cls)
The timer callback function.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MICROSECONDS, timeoutcb(), Connection::timer, and timestamp().

Referenced by connection_on_read(), and connection_write().

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

◆ connection_write_streams()

static int connection_write_streams ( struct Connection connection)
static

Write HTTP stream data and send the packets.

Parameters
connectionthe connection of the peer
Returns
GNUNET_NO on success, GNUNET_SYSERR if failed

Definition at line 2802 of file gnunet-communicator-http3.c.

2803{
2804 uint8_t buf[1280];
2805 ngtcp2_tstamp ts = timestamp ();
2806 ngtcp2_path_storage ps;
2807 int64_t stream_id;
2808 uint32_t flags;
2809 ngtcp2_ssize nwrite;
2810 ngtcp2_ssize wdatalen;
2811 nghttp3_vec vec[16];
2812 nghttp3_ssize sveccnt;
2813 ngtcp2_pkt_info pi;
2814 int fin;
2815 int rv;
2816
2817 ngtcp2_path_storage_zero (&ps);
2818
2819 for (;;)
2820 {
2821 stream_id = -1;
2822 fin = 0;
2823 sveccnt = 0;
2824
2825 if (connection->h3_conn &&
2826 ngtcp2_conn_get_max_data_left (connection->conn))
2827 {
2828 sveccnt = nghttp3_conn_writev_stream (connection->h3_conn,
2829 &stream_id,
2830 &fin,
2831 vec,
2832 16);
2833 if (sveccnt < 0)
2834 {
2836 "nghttp3_conn_writev_stream: %s\n",
2837 nghttp3_strerror (sveccnt));
2838
2839 ngtcp2_ccerr_set_application_error (
2840 &connection->last_error,
2841 nghttp3_err_infer_quic_app_error_code (sveccnt),
2842 NULL,
2843 0);
2844 return handle_error (connection);
2845 }
2846 }
2847
2848 flags = NGTCP2_WRITE_STREAM_FLAG_MORE;
2849 if (fin)
2850 flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
2851
2852 nwrite = ngtcp2_conn_writev_stream (connection->conn,
2853 &ps.path,
2854 &pi,
2855 buf,
2856 sizeof(buf),
2857 &wdatalen,
2858 flags,
2859 stream_id,
2860 (ngtcp2_vec *) vec,
2861 (size_t) sveccnt,
2862 ts);
2863 if (nwrite < 0)
2864 {
2865 switch (nwrite)
2866 {
2867 case NGTCP2_ERR_STREAM_DATA_BLOCKED:
2868 nghttp3_conn_block_stream (connection->h3_conn, stream_id);
2869 continue;
2870 case NGTCP2_ERR_STREAM_SHUT_WR:
2871 nghttp3_conn_shutdown_stream_write (connection->h3_conn, stream_id);
2872 continue;
2873 case NGTCP2_ERR_WRITE_MORE:
2874 rv = nghttp3_conn_add_write_offset (connection->h3_conn, stream_id,
2875 wdatalen);
2876 if (0 != rv)
2877 {
2879 "nghttp3_conn_add_write_offset: %s\n",
2880 nghttp3_strerror (rv));
2881 ngtcp2_ccerr_set_application_error (
2882 &connection->last_error,
2883 nghttp3_err_infer_quic_app_error_code (rv),
2884 NULL, 0);
2885 return handle_error (connection);
2886 }
2887 continue;
2888 }
2890 "ngtcp2_conn_writev_stream: %s\n",
2891 ngtcp2_strerror (nwrite));
2892 ngtcp2_ccerr_set_liberr (&connection->last_error,
2893 nwrite,
2894 NULL,
2895 0);
2896 return handle_error (connection);
2897 }
2898 if (0 == nwrite)
2899 {
2900 ngtcp2_conn_update_pkt_tx_time (connection->conn, ts);
2901 return 0;
2902 }
2903 if (wdatalen > 0)
2904 {
2905 rv = nghttp3_conn_add_write_offset (connection->h3_conn, stream_id,
2906 wdatalen);
2907 if (0 != rv)
2908 {
2910 "nghttp3_conn_add_write_offset: %s\n",
2911 nghttp3_strerror (rv));
2912 ngtcp2_ccerr_set_application_error (
2913 &connection->last_error,
2914 nghttp3_err_infer_quic_app_error_code (rv),
2915 NULL, 0);
2916 return handle_error (connection);
2917 }
2918 }
2919 if (GNUNET_NO != send_packet (connection, buf, nwrite))
2920 break;
2921 }
2922
2923 return GNUNET_NO;
2924}

References Connection::conn, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, Connection::h3_conn, handle_error(), Connection::last_error, ps, send_packet(), and timestamp().

Referenced by connection_write().

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

◆ mq_init()

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

Definition at line 2976 of file gnunet-communicator-http3.c.

2979{
2980 struct Connection *connection;
2981 struct sockaddr *local_addr;
2982 socklen_t local_addrlen;
2983 struct sockaddr *remote_addr;
2984 socklen_t remote_addrlen;
2985 const char *path;
2986 char *bindto;
2987 struct GNUNET_HashCode remote_addr_key;
2988 int rv;
2989
2990 if (GNUNET_OK !=
2993 "BINDTO",
2994 &bindto))
2995 {
2998 "BINDTO");
2999 return GNUNET_SYSERR;
3000 }
3001 local_addr = udp_address_to_sockaddr (bindto, &local_addrlen);
3002 if (0 != strncmp (address,
3004 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
3005 {
3006 GNUNET_break_op (0);
3007 return GNUNET_SYSERR;
3008 }
3009 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
3010 remote_addr = udp_address_to_sockaddr (path, &remote_addrlen);
3011
3012 GNUNET_CRYPTO_hash (address, strlen (address), &remote_addr_key);
3013 connection = GNUNET_CONTAINER_multihashmap_get (addr_map, &remote_addr_key);
3014 if (NULL != connection)
3015 {
3017 "receiver %s already exist or is being connected to\n",
3018 address);
3019 return GNUNET_SYSERR;
3020 }
3021
3022 /* Create a new connection */
3023 connection = GNUNET_new (struct Connection);
3024 connection->address = remote_addr;
3025 connection->address_len = remote_addrlen;
3026 connection->target = *peer_id;
3027 connection->is_initiator = GNUNET_YES;
3028 connection->id_rcvd = GNUNET_YES;
3029 connection->id_sent = GNUNET_NO;
3030 connection->foreign_addr =
3031 sockaddr_to_udpaddr_string (connection->address, connection->address_len);
3032 connection->nt = GNUNET_NT_scanner_get_type (is,
3034 remote_addrlen);
3035 connection->timeout =
3039 &remote_addr_key,
3040 connection,
3043 "# connections active",
3045 GNUNET_NO);
3046
3047 /* client_gnutls_init */
3048 rv = client_gnutls_init (connection);
3049 if (GNUNET_NO != rv)
3050 {
3051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client_gnutls_init failed\n");
3052 return GNUNET_SYSERR;
3053 }
3054
3055 /* client_quic_init */
3056 rv = client_quic_init (connection,
3057 local_addr, local_addrlen,
3058 remote_addr, remote_addrlen);
3059 if (GNUNET_NO != rv)
3060 {
3061 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client_quic_init failed\n");
3062 return GNUNET_SYSERR;
3063 }
3064
3065 ngtcp2_conn_set_tls_native_handle (connection->conn, connection->session);
3066
3067 rv = connection_write (connection);
3068 if (GNUNET_NO != rv)
3069 {
3071 "connection_write failed\n");
3072 return GNUNET_SYSERR;
3073 }
3075 return GNUNET_OK;
3076}
static char * peer_id
Option –peer.
static int client_quic_init(struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen)
Create new ngtcp2_conn as client side.
static int client_gnutls_init(struct Connection *connection)
As the client, initialize the corresponding connection.
static struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
#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, Connection::address, Connection::address_len, cfg, client_gnutls_init(), client_quic_init(), COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, Connection::conn, connection_write(), Connection::foreign_addr, GNUNET_break_op, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_multihashmap_size(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_new, GNUNET_NO, GNUNET_NT_scanner_get_type(), GNUNET_OK, GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_relative_to_absolute(), GNUNET_YES, Connection::id_rcvd, Connection::id_sent, is, Connection::is_initiator, local_addr, Connection::nt, peer_id, remote_addr, Connection::session, sockaddr_to_udpaddr_string(), stats, Connection::streams, Connection::target, Connection::timeout, 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:

◆ 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 3093 of file gnunet-communicator-http3.c.

3099{
3100 char *my_addr;
3102
3103 if (GNUNET_YES == add_remove)
3104 {
3106
3107 GNUNET_asprintf (&my_addr,
3108 "%s-%s",
3110 GNUNET_a2s (addr, addrlen));
3111 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
3112 ai =
3114 my_addr,
3115 nt,
3117 GNUNET_free (my_addr);
3118 *app_ctx = ai;
3119 }
3120 else
3121 {
3122 ai = *app_ctx;
3124 *app_ctx = NULL;
3125 }
3126}
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.
#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:

◆ get_connection_delete_it()

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

Iterator over all connection to clean up.

Parameters
clsNULL
keyconnection->address
valuethe connection to destroy
Returns
GNUNET_OK to continue to iterate

Definition at line 3138 of file gnunet-communicator-http3.c.

3141{
3142 struct Connection *connection = value;
3143 (void) cls;
3144 (void) key;
3145 handle_error (connection);
3146 connection_destroy (connection);
3147 return GNUNET_OK;
3148}

References connection_destroy(), GNUNET_OK, handle_error(), key, and value.

Referenced by do_shutdown().

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

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Shutdown the HTTP3 communicator.

Parameters
clsNULL (always)

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

3158{
3160 "do_shutdown start\n");
3163 NULL);
3165 gnutls_certificate_free_credentials (cred);
3166
3167 if (NULL != nat)
3168 {
3170 nat = NULL;
3171 }
3172 if (NULL != read_task)
3173 {
3175 read_task = NULL;
3176 }
3177 if (NULL != udp_sock)
3178 {
3181 udp_sock = NULL;
3182 }
3183 if (NULL != ch)
3184 {
3186 ch = NULL;
3187 }
3188 if (NULL != stats)
3189 {
3191 stats = NULL;
3192 }
3193 if (NULL != pils)
3194 {
3196 pils = NULL;
3197 }
3198 if (NULL != is)
3199 {
3201 is = NULL;
3202 }
3204 "do_shutdown finished\n");
3205}
static int get_connection_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all connection to clean up.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
static struct GNUNET_SCHEDULER_Task * read_task
ID of listen task.
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition nat_api.c:703
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
Definition nt.c:428
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

References addr_map, ch, cred, get_connection_delete_it(), GNUNET_break, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NAT_unregister(), GNUNET_NETWORK_socket_close(), GNUNET_NT_scanner_done(), GNUNET_OK, GNUNET_PILS_disconnect(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), GNUNET_TRANSPORT_communicator_disconnect(), GNUNET_YES, is, nat, pils, read_task, stats, and udp_sock.

Here is the call graph for this function:

◆ connection_feed_data()

static int connection_feed_data ( struct Connection connection,
struct sockaddr *  local_addr,
socklen_t  local_addrlen,
struct sockaddr *  remote_addr,
socklen_t  remote_addrlen,
const ngtcp2_pkt_info *  pi,
const uint8_t *  data,
size_t  datalen 
)
static

Decrypt QUIC packet.

Both the server and the client will use this function.

Parameters
connectionthe connection
local_addrour address
local_addrlenlength of our address
remote_addrpeer's address
remote_addrlenlength of peer's address
pingtcp2 packet info
datathe QUIC packet to be processed
datalenthe length of data
Returns
GNUNET_NO if success, or a negative value.

Definition at line 3223 of file gnunet-communicator-http3.c.

3228{
3229 ngtcp2_path path;
3230 int rv;
3231
3232 path.local.addr = local_addr;
3233 path.local.addrlen = local_addrlen;
3234 path.remote.addr = remote_addr;
3235 path.remote.addrlen = remote_addrlen;
3236
3237 rv = ngtcp2_conn_read_pkt (connection->conn, &path, pi, data, datalen,
3238 timestamp ());
3239 if (0 != rv)
3240 {
3242 "ngtcp2_conn_read_pkt: %s\n",
3243 ngtcp2_strerror (rv));
3244 switch (rv)
3245 {
3246 case NGTCP2_ERR_DRAINING:
3247 if (GNUNET_NO == connection->is_initiator)
3248 {
3249 start_draining_period (connection);
3251 }
3252 else
3253 {
3254 ngtcp2_ccerr_set_liberr (&connection->last_error, rv, NULL, 0);
3255 }
3256 case NGTCP2_ERR_RETRY:
3257 /* client side doesn't get this */
3258 return NETWORK_ERR_RETRY;
3259 case NGTCP2_ERR_DROP_CONN:
3260 /* client side doesn't get this */
3261 return NETWORK_ERR_DROP_CONN;
3262 case NGTCP2_ERR_CRYPTO:
3263 if (! connection->last_error.error_code)
3264 {
3265 ngtcp2_ccerr_set_tls_alert (
3266 &connection->last_error,
3267 ngtcp2_conn_get_tls_alert (connection->conn),
3268 NULL, 0);
3269 }
3270 break;
3271 default:
3272 if (! connection->last_error.error_code)
3273 {
3274 ngtcp2_ccerr_set_liberr (&connection->last_error, rv, NULL, 0);
3275 }
3276 }
3277 return handle_error (connection);
3278 }
3279 return GNUNET_NO;
3280}
static void start_draining_period(struct Connection *connection)
Start the draining period, called after receiving CONNECTION_CLOSE.

References Connection::conn, data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, handle_error(), Connection::is_initiator, Connection::last_error, local_addr, NETWORK_ERR_CLOSE_WAIT, NETWORK_ERR_DROP_CONN, NETWORK_ERR_RETRY, remote_addr, start_draining_period(), and timestamp().

Referenced by connection_on_read(), and sock_read().

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

◆ connection_on_read()

static int connection_on_read ( struct Connection connection,
struct sockaddr *  local_addr,
socklen_t  local_addrlen,
struct sockaddr *  remote_addr,
socklen_t  remote_addrlen,
const ngtcp2_pkt_info *  pi,
const uint8_t *  data,
size_t  datalen 
)
static

Connection read the packet data.

This function will only be called by the server.

Parameters
connectionthe connection
local_addrour address
local_addrlenlength of our address
remote_addrpeer's address
remote_addrlenlength of peer's address
pingtcp2 packet info
datathe QUIC packet to be processed
datalenthe length of data
Returns
GNUNET_NO if success, or the return value of connection_feed_data.

Definition at line 3299 of file gnunet-communicator-http3.c.

3304{
3305 int rv;
3306 rv = connection_feed_data (connection, local_addr, local_addrlen, remote_addr,
3307 remote_addrlen, pi, data, datalen);
3308 if (GNUNET_NO != rv)
3309 {
3310 return rv;
3311 }
3312
3313 connection_update_timer (connection);
3314 return GNUNET_NO;
3315}
static int connection_feed_data(struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
Decrypt QUIC packet.

References connection_feed_data(), connection_update_timer(), data, GNUNET_NO, local_addr, and remote_addr.

Referenced by server_read_pkt().

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

◆ connection_init()

static struct Connection * connection_init ( struct sockaddr *  local_addr,
socklen_t  local_addrlen,
struct sockaddr *  remote_addr,
socklen_t  remote_addrlen,
const ngtcp2_cid *  dcid,
const ngtcp2_cid *  scid,
uint32_t  version 
)
static

Create a new connection.

This function will only be called by the server.

Parameters
local_addrour address
local_addrlenlength of our address
remote_addrpeer's address
remote_addrlenlength of peer's address
dcidscid of the data packet from the client
sciddcid of the data packet from the client
versionversion of the data packet from the client
Returns
a new connection, NULL if error occurs.

Definition at line 3332 of file gnunet-communicator-http3.c.

3338{
3339 struct Connection *new_connection;
3340 ngtcp2_path path;
3341 ngtcp2_transport_params params;
3342 ngtcp2_cid scid_;
3343 ngtcp2_conn *conn = NULL;
3344 ngtcp2_settings settings;
3345 ngtcp2_callbacks callbacks = {
3346 .recv_client_initial = ngtcp2_crypto_recv_client_initial_cb,
3347 .recv_crypto_data = ngtcp2_crypto_recv_crypto_data_cb,
3348 .encrypt = ngtcp2_crypto_encrypt_cb,
3349 .decrypt = ngtcp2_crypto_decrypt_cb,
3350 .hp_mask = ngtcp2_crypto_hp_mask_cb,
3351 .update_key = ngtcp2_crypto_update_key_cb,
3352 .delete_crypto_aead_ctx = ngtcp2_crypto_delete_crypto_aead_ctx_cb,
3353 .delete_crypto_cipher_ctx = ngtcp2_crypto_delete_crypto_cipher_ctx_cb,
3354 .get_path_challenge_data = ngtcp2_crypto_get_path_challenge_data_cb,
3355 .version_negotiation = ngtcp2_crypto_version_negotiation_cb,
3356
3357 .acked_stream_data_offset = acked_stream_data_offset_cb,
3358 .recv_stream_data = recv_stream_data_cb,
3359 .stream_open = stream_open_cb,
3360 .rand = rand_cb,
3361 .get_new_connection_id = get_new_connection_id_cb,
3362 .stream_close = stream_close_cb,
3363 .extend_max_remote_streams_bidi = extend_max_remote_streams_bidi_cb,
3364 .stream_stop_sending = stream_stop_sending_cb,
3365 .extend_max_stream_data = extend_max_stream_data_cb,
3366 .recv_tx_key = recv_tx_key_cb,
3367 };
3368
3369
3370 int rv;
3371
3372 path.local.addr = local_addr;
3373 path.local.addrlen = local_addrlen;
3374 path.remote.addr = remote_addr;
3375 path.remote.addrlen = remote_addrlen;
3376
3377 new_connection = GNUNET_new (struct Connection);
3378 memset (new_connection, 0, sizeof (struct Connection));
3379
3380 gnutls_init (&new_connection->session,
3381 GNUTLS_SERVER
3382 | GNUTLS_ENABLE_EARLY_DATA
3383 | GNUTLS_NO_END_OF_EARLY_DATA);
3384 gnutls_priority_set_direct (new_connection->session, PRIORITY, NULL);
3385 gnutls_credentials_set (new_connection->session,
3386 GNUTLS_CRD_CERTIFICATE, cred);
3387
3388 ngtcp2_transport_params_default (&params);
3389 params.initial_max_streams_uni = 3;
3390 params.initial_max_streams_bidi = 128;
3391 params.initial_max_stream_data_bidi_local = 128 * 1024;
3392 params.initial_max_stream_data_bidi_remote = 256 * 1024;
3393 params.initial_max_stream_data_uni = 256 * 1024;
3394 params.initial_max_data = 1024 * 1024;
3395 params.original_dcid_present = 1;
3396 params.max_idle_timeout = 30 * NGTCP2_SECONDS;
3397 params.original_dcid = *scid;
3398
3399 ngtcp2_settings_default (&settings);
3400
3401 scid_.datalen = NGTCP2_MAX_CIDLEN;
3403 &scid_.data, scid_.datalen);
3404
3405 rv = ngtcp2_conn_server_new (&conn,
3406 dcid,
3407 &scid_,
3408 &path,
3409 version,
3410 &callbacks,
3411 &settings,
3412 &params,
3413 NULL,
3414 new_connection);
3415 if (rv < 0)
3416 {
3418 "ngtcp2_conn_server_new: %s\n",
3419 ngtcp2_strerror (rv));
3420 return NULL;
3421 }
3422 new_connection->conn = conn;
3423 new_connection->address = GNUNET_memdup (remote_addr, remote_addrlen);
3424 new_connection->address_len = remote_addrlen;
3425 new_connection->foreign_addr =
3426 sockaddr_to_udpaddr_string (new_connection->address,
3427 new_connection->address_len);
3428 new_connection->is_initiator = GNUNET_NO;
3429 new_connection->id_rcvd = GNUNET_NO;
3430 new_connection->id_sent = GNUNET_NO;
3431 ngtcp2_crypto_gnutls_configure_server_session (new_connection->session);
3432 ngtcp2_conn_set_tls_native_handle (new_connection->conn,
3433 new_connection->session);
3434 gnutls_session_set_ptr (new_connection->session,
3435 &new_connection->conn_ref);
3436
3437 new_connection->conn_ref.get_conn = get_conn;
3438 new_connection->conn_ref.user_data = new_connection;
3439 new_connection->streams = GNUNET_CONTAINER_multihashmap_create (10,
3440 GNUNET_NO);
3441
3442 return new_connection;
3443}
static int stream_open_cb(ngtcp2_conn *conn, int64_t stream_id, void *user_data)
The callback function for ngtcp2_callbacks.stream_open.
static int recv_tx_key_cb(ngtcp2_conn *conn, ngtcp2_encryption_level level, void *user_data)
The callback function for ngtcp2_callbacks.recv_tx_key.
static int extend_max_remote_streams_bidi_cb(ngtcp2_conn *conn, uint64_t max_streams, void *user_data)
The callback function for ngtcp2_callbacks.extend_max_remote_streams_bidi.

References acked_stream_data_offset_cb(), Connection::address, Connection::address_len, Connection::conn, Connection::conn_ref, cred, extend_max_remote_streams_bidi_cb(), extend_max_stream_data_cb(), Connection::foreign_addr, get_conn(), get_new_connection_id_cb(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_CRYPTO_random_block(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_memdup, GNUNET_new, GNUNET_NO, Connection::id_rcvd, Connection::id_sent, Connection::is_initiator, local_addr, PRIORITY, rand_cb(), recv_stream_data_cb(), recv_tx_key_cb(), remote_addr, Connection::session, sockaddr_to_udpaddr_string(), stream_close_cb(), stream_open_cb(), stream_stop_sending_cb(), and Connection::streams.

Referenced by server_read_pkt().

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

◆ server_read_pkt()

static void server_read_pkt ( struct Connection connection,
const struct GNUNET_HashCode addr_key,
struct sockaddr *  local_addr,
socklen_t  local_addrlen,
struct sockaddr *  remote_addr,
socklen_t  remote_addrlen,
const ngtcp2_pkt_info *  pi,
const uint8_t *  data,
size_t  datalen 
)
static

The server processes the newly received data packet.

This function will only be called by the server.

Parameters
connectionthe connection
addr_keythe hash key of peer's address
local_addrour address
local_addrlenlength of our address
remote_addrpeer's address
remote_addrlenlength of peer's address
pingtcp2 packet info
datathe QUIC packet to be processed
datalenthe length of data

TODO: handle the stateless reset token.

Definition at line 3461 of file gnunet-communicator-http3.c.

3467{
3468 ngtcp2_version_cid version_cid;
3469 int rv;
3470
3471 rv = ngtcp2_pkt_decode_version_cid (&version_cid, data, datalen,
3472 NGTCP2_MAX_CIDLEN);
3473 switch (rv)
3474 {
3475 case 0:
3476 break;
3477 case NGTCP2_ERR_VERSION_NEGOTIATION:
3478 // TODO: send version negotiation
3479 return;
3480 default:
3482 "Can't decode version and CID: %s\n",
3483 ngtcp2_strerror (rv));
3484 return;
3485 }
3486
3487 if (NULL == connection)
3488 {
3489 ngtcp2_pkt_hd header;
3490 rv = ngtcp2_accept (&header, data, datalen);
3491 if (0 != rv)
3492 {
3494 "ngtcp2_accept: %s\n",
3495 ngtcp2_strerror (rv));
3496 return;
3497 }
3498
3503 connection = connection_init (local_addr, local_addrlen, remote_addr,
3504 remote_addrlen, &header.scid, &header.dcid,
3505 header.version);
3506 if (NULL == connection)
3507 {
3509 "accept connection error!\n");
3510 return;
3511 }
3512
3514 addr_key,
3515 connection,
3517 rv = connection_on_read (connection, local_addr, local_addrlen, remote_addr,
3518 remote_addrlen, pi, data, datalen);
3519 switch (rv)
3520 {
3521 case 0:
3522 break;
3523 case NETWORK_ERR_RETRY:
3524 // TODO: send retry
3525 return;
3526 default:
3527 return;
3528 }
3529
3530 rv = connection_write (connection);
3531 if (GNUNET_NO != rv)
3532 {
3533 return;
3534 }
3535
3536 // add to cid_map here
3537 return;
3538 }
3539
3540 if (ngtcp2_conn_in_closing_period (connection->conn))
3541 {
3542 rv = send_conn_close (connection);
3543 if (GNUNET_NO != rv)
3544 {
3545 connection_destroy (connection);
3546 }
3547 return;
3548 }
3549
3550 if (ngtcp2_conn_in_draining_period (connection->conn))
3551 {
3552 return;
3553 }
3554
3555 rv = connection_on_read (connection, local_addr, local_addrlen, remote_addr,
3556 remote_addrlen, pi, data, datalen);
3557 if (GNUNET_NO != rv)
3558 {
3559 if (NETWORK_ERR_CLOSE_WAIT != rv)
3560 {
3561 connection_destroy (connection);
3562 }
3563 return;
3564 }
3565
3566 connection_write (connection);
3567}
static struct Connection * connection_init(struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_cid *dcid, const ngtcp2_cid *scid, uint32_t version)
Create a new connection.
static int connection_on_read(struct Connection *connection, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
Connection read the packet data.

References addr_map, Connection::conn, connection_destroy(), connection_init(), connection_on_read(), connection_write(), data, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, local_addr, NETWORK_ERR_CLOSE_WAIT, NETWORK_ERR_RETRY, remote_addr, and send_conn_close().

Referenced by sock_read().

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

Socket read task.

Parameters
clsNULL

Definition at line 3576 of file gnunet-communicator-http3.c.

3577{
3578 struct sockaddr_storage sa;
3579 socklen_t salen = sizeof (sa);
3580 ssize_t rcvd;
3581 uint8_t buf[UINT16_MAX];
3582 struct GNUNET_HashCode addr_key;
3583 struct Connection *connection;
3584 int rv;
3585 char *bindto;
3586 struct sockaddr *local_addr;
3587 socklen_t local_addrlen;
3588
3589 (void) cls;
3590 if (GNUNET_OK !=
3593 "BINDTO",
3594 &bindto))
3595 {
3598 "BINDTO");
3599 return;
3600 }
3601 local_addr = udp_address_to_sockaddr (bindto, &local_addrlen);
3603 udp_sock,
3604 &sock_read,
3605 NULL);
3606
3607 while (1)
3608 {
3609 char *addr_string;
3610
3612 buf,
3613 sizeof(buf),
3614 (struct sockaddr *) &sa,
3615 &salen);
3616 if (-1 == rcvd)
3617 {
3618 struct sockaddr *addr = (struct sockaddr*) &sa;
3619
3620 if (EAGAIN == errno)
3621 break; // We are done reading data
3623 "Failed to recv from %s family %d failed sock %p\n",
3624 GNUNET_a2s ((struct sockaddr*) &sa,
3625 sizeof (*addr)),
3626 addr->sa_family,
3627 udp_sock);
3629 return;
3630 }
3632 "Read %llu bytes\n",
3633 (unsigned long long) rcvd);
3634 if (0 == rcvd)
3635 {
3636 GNUNET_break_op (0);
3638 "Read 0 bytes from UDP socket\n");
3639 return;
3640 }
3641
3642 addr_string =
3643 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa,
3644 salen);
3645 GNUNET_CRYPTO_hash (addr_string, strlen (addr_string),
3646 &addr_key);
3647 GNUNET_free (addr_string);
3648 connection = GNUNET_CONTAINER_multihashmap_get (addr_map, &addr_key);
3649
3650 if (NULL != connection && GNUNET_YES == connection->is_initiator)
3651 {
3652 ngtcp2_pkt_info pi = {0};
3653
3654 rv = connection_feed_data (connection, local_addr, local_addrlen,
3655 (struct sockaddr *) &sa,
3656 salen, &pi, buf, rcvd);
3657 if (GNUNET_NO != rv)
3658 {
3659 return;
3660 }
3661 rv = connection_write (connection);
3662 if (rv < 0)
3663 {
3665 "connection write error!\n");
3666 return;
3667 }
3668 }
3669 else
3670 {
3671 ngtcp2_pkt_info pi = {0};
3672
3673 server_read_pkt (connection, &addr_key,
3674 local_addr, local_addrlen,
3675 (struct sockaddr *) &sa, salen,
3676 &pi, buf, rcvd);
3677 }
3678
3679 }
3680
3682
3683}
static void sock_read(void *cls)
Socket read task.
static void server_read_pkt(struct Connection *connection, const struct GNUNET_HashCode *addr_key, struct sockaddr *local_addr, socklen_t local_addrlen, struct sockaddr *remote_addr, socklen_t remote_addrlen, const ngtcp2_pkt_info *pi, const uint8_t *data, size_t datalen)
The server processes the newly received data packet.
#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:687
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:1517

References addr_map, cfg, COMMUNICATOR_CONFIG_SECTION, connection_feed_data(), connection_write(), GNUNET_a2s(), GNUNET_break_op, GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_config_missing(), GNUNET_log_strerror, GNUNET_NETWORK_socket_recvfrom(), GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, Connection::is_initiator, local_addr, read_task, server_read_pkt(), sock_read(), sockaddr_to_udpaddr_string(), udp_address_to_sockaddr(), and udp_sock.

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

Get our public key for initial packet

Definition at line 3695 of file gnunet-communicator-http3.c.

3699{
3700 char *bindto;
3701 struct sockaddr *in;
3702 socklen_t in_len;
3703 struct sockaddr_storage in_sto;
3704 socklen_t sto_len;
3705 char *cert_file;
3706 char *key_file;
3707 int rv;
3708
3709 (void) cls;
3710 cfg = c;
3711 if (GNUNET_OK !=
3714 "BINDTO",
3715 &bindto))
3716 {
3719 "BINDTO");
3720 return;
3721 }
3722
3723 key_file = NULL;
3724 cert_file = NULL;
3725 if ((GNUNET_OK !=
3728 "KEY_FILE",
3729 &key_file)))
3730 key_file = GNUNET_strdup ("https.key");
3731 if (GNUNET_OK !=
3734 "CERT_FILE",
3735 &cert_file))
3736 cert_file = GNUNET_strdup ("https.crt");
3737 if ((GNUNET_OK != GNUNET_DISK_file_test (key_file)) ||
3738 (GNUNET_OK != GNUNET_DISK_file_test (cert_file)))
3739 {
3740 struct GNUNET_Process *cert_creation;
3741
3743 "Creating new certificate\n");
3745 if (GNUNET_OK !=
3747 cert_creation,
3748 "gnunet-transport-certificate-creation",
3749 "gnunet-transport-certificate-creation",
3750 key_file,
3751 cert_file,
3752 NULL))
3753 {
3754 GNUNET_process_destroy (cert_creation);
3756 "Can't create new key pair %s/%s\n",
3757 key_file,
3758 cert_file);
3759 GNUNET_free (key_file);
3760 GNUNET_free (cert_file);
3761 return;
3762 }
3764 GNUNET_process_wait (cert_creation,
3765 true,
3766 NULL,
3767 NULL));
3768 GNUNET_process_destroy (cert_creation);
3769 }
3770
3772 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
3773 (GNUNET_YES ==
3776 "DISABLE_V6")))
3777 {
3779 }
3780
3781 in = udp_address_to_sockaddr (bindto, &in_len);
3782
3783 if (NULL == in)
3784 {
3786 "Failed to setup UDP socket address with path `%s'\n",
3787 bindto);
3788 GNUNET_free (bindto);
3789 return;
3790 }
3791 udp_sock =
3792 GNUNET_NETWORK_socket_create (in->sa_family,
3793 SOCK_DGRAM,
3794 IPPROTO_UDP);
3795 if (NULL == udp_sock)
3796 {
3799 "Failed to create socket for %s family %d\n",
3800 GNUNET_a2s (in,
3801 in_len),
3802 in->sa_family);
3803 GNUNET_free (in);
3804 GNUNET_free (bindto);
3805 return;
3806 }
3807 if (AF_INET6 == in->sa_family)
3809 if (GNUNET_OK !=
3811 in,
3812 in_len))
3813 {
3815 "bind",
3816 bindto);
3818 "Failed to bind socket for %s family %d sock %p\n",
3819 GNUNET_a2s (in,
3820 in_len),
3821 in->sa_family,
3822 udp_sock);
3824 udp_sock = NULL;
3825 GNUNET_free (in);
3826 GNUNET_free (bindto);
3827 return;
3828 }
3829 sto_len = sizeof(in_sto);
3830 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
3831 (struct sockaddr *) &in_sto,
3832 &sto_len))
3833 {
3834 memcpy (&in_sto, in, in_len);
3835 sto_len = in_len;
3836 }
3837 GNUNET_free (in);
3838 GNUNET_free (bindto);
3839 in = (struct sockaddr *) &in_sto;
3840 in_len = sto_len;
3842 "transport",
3843 "Bound to `%s' sock %p\n",
3844 GNUNET_a2s ((const struct sockaddr *) &in_sto,
3845 sto_len),
3846 udp_sock);
3847 switch (in->sa_family)
3848 {
3849 case AF_INET:
3850 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
3851 break;
3852
3853 case AF_INET6:
3854 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
3855 break;
3856
3857 default:
3858 GNUNET_break (0);
3859 my_port = 0;
3860 }
3862
3865
3866 rv = gnutls_certificate_allocate_credentials (&cred);
3867 if (GNUNET_NO == rv)
3868 rv = gnutls_certificate_set_x509_system_trust (cred);
3869 if (GNUNET_NO > rv)
3870 {
3872 "cred init failed: %s\n",
3873 gnutls_strerror (rv));
3874 return;
3875 }
3876 rv = gnutls_certificate_set_x509_key_file (cred,
3877 cert_file,
3878 key_file,
3879 GNUTLS_X509_FMT_PEM);
3881 "key_file: %s\ncert_file: %s\n",
3882 key_file, cert_file);
3883 GNUNET_free (cert_file);
3884 GNUNET_free (key_file);
3885 if (rv < 0)
3886 {
3888 "gnutls_certificate_set_x509_key_file: %s\n",
3889 gnutls_strerror (rv));
3890 return;
3891 }
3895 pils = GNUNET_PILS_connect (cfg, NULL, NULL);
3896 if (NULL == pils)
3897 {
3898 GNUNET_log (
3900 _ (
3901 "Transport service is lacking PILS connection. Exiting.\n"));
3903 return;
3904 }
3905
3907 udp_sock,
3908 &sock_read,
3909 NULL);
3914 &mq_init,
3915 NULL,
3916 &notify_cb,
3917 NULL,
3918 NULL);
3919 if (NULL == ch)
3920 {
3921 GNUNET_break (0);
3923 return;
3924 }
3925
3928 IPPROTO_UDP,
3929 1 /* one address */,
3930 (const struct sockaddr **) &in,
3931 &in_len,
3934 NULL /* closure */);
3935}
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
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 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 int have_v6_socket
GNUNET_YES if udp_sock supports IPv6.
static uint16_t my_port
Port number to which we are actually bound.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:465
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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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".
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition disk.c:557
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:1000
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:832
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
Definition network.c:79
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
enum GNUNET_GenericReturnValue GNUNET_process_run_command_va(struct GNUNET_Process *p, const char *filename,...)
Set the command and start a process.
Definition os_process.c:903
enum GNUNET_GenericReturnValue GNUNET_process_wait(struct GNUNET_Process *proc, bool blocking, enum GNUNET_OS_ProcessStatusType *type, unsigned long *code)
Wait for a process to terminate.
void GNUNET_process_destroy(struct GNUNET_Process *proc)
Cleans up process structure contents (OS-dependent) and deallocates it.
Definition os_process.c:363
struct GNUNET_Process * GNUNET_process_create(enum GNUNET_OS_InheritStdioFlags std_inheritance)
Create a process handle.
Definition os_process.c:462
@ GNUNET_OS_INHERIT_STD_OUT_AND_ERR
When these flags are set, the child process will inherit stdout and stderr of the parent.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
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:1345
#define _(String)
GNU gettext support macro.
Definition platform.h:179

References _, addr_map, cfg, ch, COMMUNICATOR_ADDRESS_PREFIX, COMMUNICATOR_CONFIG_SECTION, cred, disable_v6, do_shutdown, GNUNET_a2s(), GNUNET_break, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_multihashmap_create(), GNUNET_DISK_file_test(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, 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_NETWORK_test_pf(), GNUNET_NO, GNUNET_NT_scanner_init(), GNUNET_OK, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, GNUNET_PILS_connect(), GNUNET_process_create(), GNUNET_process_destroy(), GNUNET_process_run_command_va(), GNUNET_process_wait(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_strdup, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TRANSPORT_CC_RELIABLE, GNUNET_TRANSPORT_communicator_connect(), GNUNET_YES, have_v6_socket, is, mq_init(), my_port, nat, nat_address_cb(), notify_cb(), pils, 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 
)

The main function for the UNIX communicator.

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

Definition at line 3946 of file gnunet-communicator-http3.c.

3947{
3948 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
3950 };
3951 int ret;
3952
3954 "transport",
3955 "Starting http3 communicator\n");
3956 ret = (GNUNET_OK ==
3958 argc,
3959 argv,
3960 "gnunet-communicator-http3",
3961 _ ("GNUnet HTTP3 communicator"),
3962 options,
3963 &run,
3964 NULL))
3965 ? 0
3966 : 1;
3967 return ret;
3968}
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_GETOPT_OPTION_END
Marker for the end of the list of options.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
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_OS_project_data_gnunet(), GNUNET_PROGRAM_run(), options, ret, and run().

Here is the call graph for this function:

Variable Documentation

◆ addr_map

struct GNUNET_CONTAINER_MultiHashMap* addr_map
static

Map of sockaddr -> struct Connection.

TODO: Maybe it would be better to use cid as key? addr_map can't be discarded yet, because mq_init parameter is address. So currently use cid_map seems not a perfet way.

Definition at line 75 of file gnunet-communicator-http3.c.

Referenced by connection_destroy(), do_shutdown(), mq_init(), run(), server_read_pkt(), and sock_read().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

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

◆ pils

struct GNUNET_PILS_Handle* pils
static

Handle to the pils service.

Definition at line 85 of file gnunet-communicator-http3.c.

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

◆ disable_v6

int disable_v6
static

IPv6 disabled or not.

Definition at line 90 of file gnunet-communicator-http3.c.

Referenced by run(), and udp_address_to_sockaddr().

◆ udp_sock

struct GNUNET_NETWORK_Handle* udp_sock
static

◆ read_task

struct GNUNET_SCHEDULER_Task* read_task
static

ID of listen task.

Definition at line 100 of file gnunet-communicator-http3.c.

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

◆ ch

Our environment.

Definition at line 105 of file gnunet-communicator-http3.c.

Referenced by do_shutdown(), http_recv_data_cb(), nat_address_cb(), run(), and setup_connection_mq().

◆ nat

struct GNUNET_NAT_Handle* nat
static

Connection to NAT service.

Definition at line 110 of file gnunet-communicator-http3.c.

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

◆ have_v6_socket

int have_v6_socket
static

GNUNET_YES if udp_sock supports IPv6.

Definition at line 115 of file gnunet-communicator-http3.c.

Referenced by run().

◆ my_port

uint16_t my_port
static

Port number to which we are actually bound.

Definition at line 120 of file gnunet-communicator-http3.c.

Referenced by run().

◆ is

struct GNUNET_NT_InterfaceScanner* is
static

Network scanner to determine network types.

Definition at line 125 of file gnunet-communicator-http3.c.

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

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

For logging statistics.

Definition at line 130 of file gnunet-communicator-http3.c.

Referenced by connection_destroy(), do_shutdown(), and mq_init().

◆ cred