17#include <ngtcp2/ngtcp2.h>
18#include <ngtcp2/ngtcp2_crypto.h>
19#include <ngtcp2/ngtcp2_crypto_gnutls.h>
20#include <nghttp3/nghttp3.h>
21#include <gnutls/crypto.h>
22#include <gnutls/gnutls.h>
29#define COMMUNICATOR_CONFIG_SECTION "communicator-http3"
34#define COMMUNICATOR_ADDRESS_PREFIX "http3"
39#define PRIORITY "NORMAL:-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"
48#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
53#define NUM_LONG_POLL 16
135static gnutls_certificate_credentials_t
cred;
414 clock_gettime (CLOCK_MONOTONIC, &tp);
415 return (uint64_t) tp.tv_sec * NGTCP2_SECONDS + (uint64_t) tp.tv_nsec;
430 socklen_t address_len)
464static struct sockaddr *
473 if (1 == sscanf (bindto,
"%u%1s", &
port,
dummy))
476 if (
port > UINT16_MAX)
479 "BINDTO specification `%s' invalid: value too large for port\n",
485 struct sockaddr_in *i4;
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;
495 struct sockaddr_in6 *i6;
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;
506 colon = strrchr (cp,
':');
512 if (1 == sscanf (colon,
"%u%1s", &
port,
dummy))
515 if (
port > UINT16_MAX)
518 "BINDTO specification `%s' invalid: value too large for port\n",
528 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
541 struct sockaddr_in v4;
543 memset (&v4, 0,
sizeof(v4));
544 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
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);
552 *sock_len =
sizeof(
struct sockaddr_in);
559 struct sockaddr_in6 v6;
562 memset (&v6, 0,
sizeof(v6));
564 if ((
'[' == *cp) && (
']' == cp[strlen (cp) - 1]))
567 cp[strlen (cp) - 1] =
'\0';
569 if (1 == inet_pton (AF_INET6,
start, &v6.sin6_addr))
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);
577 *sock_len =
sizeof(v6);
594 return ((
struct Connection*) (ref->user_data))->conn;
600 const struct sockaddr *addr,
605 "No connection reversal implemented!\n");
647 "send packet failed!\n");
666 struct Stream *new_stream;
670 memset (new_stream, 0,
sizeof (
struct Stream));
703 "can't remove non-exist pair in connection->streams, stream_id = %"
758 gnutls_datum_t alpn = { (
unsigned char *)
"h3",
sizeof(
"h3") - 1};
771 | GNUTLS_ENABLE_EARLY_DATA
772 | GNUTLS_NO_END_OF_EARLY_DATA);
776 "gnutls_init error: %s\n",
777 gnutls_strerror (rv));
784 "ngtcp2_crypto_gnutls_configure_client_session failed\n");
791 "gnutls_priority_set_direct: %s\n",
792 gnutls_strerror (rv));
801 "gnutls_credentials_set: %s\n",
802 gnutls_strerror (rv));
806 GNUTLS_ALPN_MANDATORY);
885 while (NULL != msg_curr)
887 msg_curr = msg_curr->
next;
893 while (NULL != msg_curr)
895 msg_curr = msg_curr->
next;
902 while (NULL != long_poll_curr)
904 long_poll_temp = long_poll_curr;
905 long_poll_curr = long_poll_curr->
next;
906 if (long_poll_temp->
timer)
911 if (NULL != connection->
d_qh)
914 connection->
d_qh = NULL;
924 "tried to remove non-existent connection from addr_map\n");
928 "# connections active",
932 ngtcp2_conn_del (connection->
conn);
935 nghttp3_conn_del (connection->
h3_conn);
937 gnutls_deinit (connection->
session);
965 nv.name = (
const uint8_t *)
name;
966 nv.namelen = strlen (
name);
967 nv.value = (
const uint8_t *)
value;
968 nv.valuelen = strlen (
value);
979read_data (nghttp3_conn *conn, int64_t stream_id, nghttp3_vec *vec,
980 size_t veccnt, uint32_t *pflags,
void *user_data,
981 void *stream_user_data)
983 struct Stream *stream = stream_user_data;
985 vec[0].base = stream->
data;
987 *pflags |= NGHTTP3_DATA_FLAG_EOF;
1006 const uint8_t *
data,
1010 char contentlen[20];
1011 nghttp3_data_reader dr = {};
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",
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);
1042 nva, 7, &dr, stream);
1046 "nghttp3_conn_submit_request: %s\n",
1047 nghttp3_strerror (rv));
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",
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);
1091 nva, 5, NULL, stream);
1095 "nghttp3_conn_submit_request: %s\n",
1096 nghttp3_strerror (rv));
1118 long_poll->
timer = NULL;
1120 "long_poll_timeoutcb called!\n");
1121 stream = long_poll->
stream;
1123 if (NULL != long_poll->
prev)
1127 if (NULL != long_poll->
next)
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,
1152 "nghttp3_conn_submit_response: %s\n",
1153 nghttp3_strerror (rv));
1156 ngtcp2_conn_shutdown_stream_read (connection->
conn, 0,
1158 NGHTTP3_H3_NO_ERROR);
1174 uint8_t *
data,
size_t datalen)
1177 nghttp3_data_reader dr = {};
1178 char content_length_str[20];
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);
1204 "nghttp3_conn_submit_response: %s\n",
1205 nghttp3_strerror (rv));
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);
1246 "nghttp3_conn_submit_response: %s\n",
1247 nghttp3_strerror (rv));
1255 "rm msg, len = %lu\n",
1268 "server recv GET request\n");
1274 (uint8_t *)
msg->buf,
1285 "add long_poll, len = %lu\n",
1288 long_poll->
stream = stream;
1289 long_poll->
next = NULL;
1311 while (NULL != long_poll &&
1315 if (NULL != long_poll->
next)
1325 (uint8_t *)
msg->buf,
1328 if (NULL != long_poll->
next)
1334 "rm long_poll, len = %lu\n",
1358 uint16_t msize = ntohs (
msg->
size);
1359 struct Stream *post_stream;
1364 "mq_send_d: init = %d, msg->size = %u, time: %llu\n",
1366 (
unsigned long long)
timestamp () / NGTCP2_SECONDS);
1367 if (NULL == connection->
conn)
1370 "No quic connection has been established yet\n");
1376 if (msize > connection->
d_mtu)
1379 "msize: %u, mtu: %lu\n",
1386 "connection destroy called, destroying connection\n");
1397 ngtcp2_conn_open_bidi_stream (connection->
conn,
1414 if (NULL != long_poll->
next)
1420 "rm long_poll, len = %lu\n",
1429 "add msg, len = %lu\n",
1432 send_buf->
size = msize;
1434 send_buf->
next = NULL;
1443 while (NULL != long_poll &&
1447 if (NULL != long_poll->
next)
1457 (uint8_t *) send_buf->
buf,
1460 if (NULL != long_poll->
next)
1466 "rm long_poll, len = %lu\n",
1489 "Default MQ destroyed\n");
1490 if (
mq == connection->
d_mq)
1492 connection->
d_mq = NULL;
1527 "MQ error in queue to %s: %d\n",
1547 "setup_connection_mq: init = %u\n",
1549 switch (connection->
address->sa_family)
1566 connection->
d_mtu = base_mtu;
1568 if (NULL == connection->
d_mq)
1595 ngtcp2_conn_extend_max_stream_offset (connection->
conn,
1598 ngtcp2_conn_extend_max_offset (connection->
conn,
1608 uint64_t app_error_code,
void *conn_user_data,
1609 void *stream_user_data)
1611 struct Connection *connection = conn_user_data;
1615 "HTTP stream %lu closed\n",
1616 (
unsigned long) stream_id);
1618 ngtcp2_is_bidi_stream (stream_id))
1620 ngtcp2_conn_extend_max_streams_bidi (connection->
conn, 1);
1623 ! ngtcp2_is_bidi_stream (stream_id))
1625 ngtcp2_conn_extend_max_streams_uni (connection->
conn, 1);
1638 const uint8_t *
data,
1641 void *stream_user_data)
1649 "http_recv_data_cb\n");
1658 "message recv len of %zd less than length of peer identity\n",
1660 return NGHTTP3_ERR_CALLBACK_FAILURE;
1680 "GNUNET_TRANSPORT_communicator_receive:%d, hdr->len = %u, datalen = %lu, init = %d\n",
1682 return NGHTTP3_ERR_CALLBACK_FAILURE;
1685 "GNUNET_TRANSPORT_communicator_receive:%d, hdr->len = %u, datalen = %lu, init = %d\n",
1699 void *stream_user_data)
1715 void *user_data,
void *stream_user_data)
1723 return NGHTTP3_ERR_CALLBACK_FAILURE;
1736 nghttp3_rcbuf *
name, nghttp3_rcbuf *
value, uint8_t flags,
1737 void *user_data,
void *stream_user_data)
1739 nghttp3_vec namebuf = nghttp3_rcbuf_get_buf (
name);
1740 nghttp3_vec valbuf = nghttp3_rcbuf_get_buf (
value);
1744 (
int) namebuf.len, namebuf.base,
1745 (
int) valbuf.len, valbuf.base);
1749 struct Stream *stream = stream_user_data;
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);
1757 case NGHTTP3_QPACK_TOKEN__METHOD:
1759 stream->
method = (uint8_t *) malloc (valbuf.len);
1760 memcpy (stream->
method, valbuf.base, valbuf.len);
1762 case NGHTTP3_QPACK_TOKEN__AUTHORITY:
1764 stream->
authority = (uint8_t *) malloc (valbuf.len);
1765 memcpy (stream->
authority, valbuf.base, valbuf.len);
1778 uint64_t app_error_code,
void *user_data,
1779 void *stream_user_data)
1784 rv = ngtcp2_conn_shutdown_stream_read (connection->
conn,
1791 "ngtcp2_conn_shutdown_stream_read: %s\n",
1792 ngtcp2_strerror (rv));
1793 return NGHTTP3_ERR_CALLBACK_FAILURE;
1804 void *stream_user_data)
1807 struct Stream *stream = stream_user_data;
1817 return NGHTTP3_ERR_CALLBACK_FAILURE;
1827 while (NULL != long_poll)
1832 "client side recv GET response\n");
1834 rv = ngtcp2_conn_open_bidi_stream (connection->
conn,
1839 "ngtcp2_conn_open_bidi_stream: %s\n",
1840 ngtcp2_strerror (rv));
1846 long_poll = long_poll->
next;
1858 uint64_t app_error_code,
void *user_data,
1859 void *stream_user_data)
1864 rv = ngtcp2_conn_shutdown_stream_write (connection->
conn,
1871 "ngtcp2_conn_shutdown_stream_write: %s\n",
1872 ngtcp2_strerror (rv));
1873 return NGHTTP3_ERR_CALLBACK_FAILURE;
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 = {
1906 if (NULL != connection->
h3_conn)
1911 if (ngtcp2_conn_get_streams_uni_left (connection->
conn) < 3)
1914 "uni stream left less than 3\n");
1920 callbacks.begin_headers = NULL;
1924 nghttp3_settings_default (&settings);
1925 settings.qpack_blocked_streams = 100;
1926 settings.qpack_encoder_max_dtable_capacity = 4096;
1930 const ngtcp2_transport_params *params =
1931 ngtcp2_conn_get_local_transport_params (connection->
conn);
1933 rv = nghttp3_conn_server_new (&connection->
h3_conn,
1938 nghttp3_conn_set_max_client_streams_bidi (connection->
h3_conn,
1939 params->initial_max_streams_bidi);
1943 "nghttp3_conn_server_new: %s\n",
1944 nghttp3_strerror (rv));
1950 rv = nghttp3_conn_client_new (&connection->
h3_conn,
1958 "nghttp3_conn_client_new: %s\n",
1959 nghttp3_strerror (rv));
1964 rv = ngtcp2_conn_open_uni_stream (connection->
conn, &ctrl_stream_id, NULL);
1968 "ngtcp2_conn_open_uni_stream: %s\n",
1969 ngtcp2_strerror (rv));
1973 rv = nghttp3_conn_bind_control_stream (connection->
h3_conn, ctrl_stream_id);
1977 "nghttp3_conn_bind_control_stream: %s\n",
1978 nghttp3_strerror (rv));
1982 rv = ngtcp2_conn_open_uni_stream (connection->
conn, &enc_stream_id, NULL);
1986 "ngtcp2_conn_open_uni_stream: %s\n",
1987 ngtcp2_strerror (rv));
1991 rv = ngtcp2_conn_open_uni_stream (connection->
conn, &dec_stream_id, NULL);
1995 "ngtcp2_conn_open_uni_stream: %s\n",
1996 ngtcp2_strerror (rv));
2000 rv = nghttp3_conn_bind_qpack_streams (connection->
h3_conn,
2001 enc_stream_id, dec_stream_id);
2005 "nghttp3_conn_bind_qpack_streams: %s\n",
2006 nghttp3_strerror (rv));
2011 "Bind control stream: %" PRIi64
", enc stream: %" PRIi64
2012 ", dec stream: %" PRIi64
"\n",
2013 ctrl_stream_id, enc_stream_id, dec_stream_id);
2024 const ngtcp2_rand_ctx *rand_ctx)
2038 uint8_t *token,
size_t cidlen,
2047 cid->datalen = cidlen;
2050 NGTCP2_STATELESS_RESET_TOKENLEN);
2060 uint64_t offset,
const uint8_t *
data,
size_t datalen,
2062 void *stream_user_data)
2065 nghttp3_ssize nconsumed;
2067 if (NULL == connection->
h3_conn)
2071 nconsumed = nghttp3_conn_read_stream (connection->
h3_conn, stream_id,
2073 flags & NGTCP2_STREAM_DATA_FLAG_FIN);
2077 "nghttp3_conn_read_stream: %s, init = %d\n",
2078 nghttp3_strerror (nconsumed), connection->
is_initiator);
2079 ngtcp2_ccerr_set_application_error (
2081 nghttp3_err_infer_quic_app_error_code (nconsumed),
2083 return NGTCP2_ERR_CALLBACK_FAILURE;
2099 if (! ngtcp2_is_bidi_stream (stream_id))
2115 uint64_t app_error_code,
void *user_data,
2116 void *stream_user_data)
2122 "stream_close id = %" PRIi64
"\n",
2124 if (! (flags & NGTCP2_STREAM_CLOSE_FLAG_APP_ERROR_CODE_SET))
2126 app_error_code = NGHTTP3_H3_NO_ERROR;
2131 if (0 == app_error_code)
2133 app_error_code = NGHTTP3_H3_NO_ERROR;
2136 rv = nghttp3_conn_close_stream (connection->
h3_conn,
2143 case NGHTTP3_ERR_STREAM_NOT_FOUND:
2145 ngtcp2_is_bidi_stream (stream_id))
2147 ngtcp2_conn_extend_max_streams_bidi (connection->
conn, 1);
2150 ! ngtcp2_is_bidi_stream (stream_id))
2152 ngtcp2_conn_extend_max_streams_uni (connection->
conn, 1);
2157 "nghttp3_conn_close_stream: %s\n",
2158 nghttp3_strerror (rv));
2159 ngtcp2_ccerr_set_application_error (
2161 nghttp3_err_infer_quic_app_error_code (rv),
2163 return NGTCP2_ERR_CALLBACK_FAILURE;
2175 uint64_t offset, uint64_t datalen,
void *user_data,
2176 void *stream_user_data)
2181 if (NULL == connection->
h3_conn)
2186 rv = nghttp3_conn_add_ack_offset (connection->
h3_conn, stream_id, datalen);
2190 "nghttp3_conn_add_ack_offset: %s\n",
2191 nghttp3_strerror (rv));
2192 return NGTCP2_ERR_CALLBACK_FAILURE;
2203 uint64_t max_data,
void *user_data,
2204 void *stream_user_data)
2209 rv = nghttp3_conn_unblock_stream (connection->
h3_conn, stream_id);
2213 "nghttp3_conn_unblock_stream: %s\n",
2214 nghttp3_strerror (rv));
2215 return NGTCP2_ERR_CALLBACK_FAILURE;
2226 uint64_t app_error_code,
void *user_data,
2227 void *stream_user_data)
2234 rv = nghttp3_conn_shutdown_stream_read (connection->
h3_conn, stream_id);
2238 "nghttp3_conn_shutdown_stream_read: %s\n",
2239 nghttp3_strerror (rv));
2240 return NGTCP2_ERR_CALLBACK_FAILURE;
2255 if (NULL == connection->
h3_conn)
2259 nghttp3_conn_set_max_client_streams_bidi (connection->
h3_conn, max_streams);
2269 uint64_t app_error_code,
void *user_data,
2270 void *stream_user_data)
2277 rv = nghttp3_conn_shutdown_stream_read (connection->
h3_conn, stream_id);
2281 "nghttp3_conn_shutdown_stream_read: %s\n",
2282 nghttp3_strerror (rv));
2283 return NGTCP2_ERR_CALLBACK_FAILURE;
2300 if (NGTCP2_ENCRYPTION_LEVEL_1RTT != level)
2308 return NGTCP2_ERR_CALLBACK_FAILURE;
2327 if (NGTCP2_ENCRYPTION_LEVEL_1RTT != level)
2335 return NGTCP2_ERR_CALLBACK_FAILURE;
2347 rv = ngtcp2_conn_open_bidi_stream (conn, &stream->
stream_id, NULL);
2359 rv = ngtcp2_conn_open_bidi_stream (conn, &stream->
stream_id, NULL);
2362 long_poll->
stream = stream;
2363 long_poll->
next = NULL;
2365 long_poll->
timer = NULL;
2396 socklen_t local_addrlen,
2398 socklen_t remote_addrlen)
2403 ngtcp2_settings settings;
2404 ngtcp2_transport_params params;
2405 ngtcp2_path path = {
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,
2434 scid.datalen = NGTCP2_MAX_CIDLEN;
2438 dcid.datalen = NGTCP2_MAX_CIDLEN;
2442 ngtcp2_settings_default (&settings);
2445 ngtcp2_transport_params_default (¶ms);
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,
2459 NGTCP2_PROTO_VER_V1,
2468 "ngtcp2_conn_client_new: %s\n",
2469 ngtcp2_strerror (rv));
2472 ngtcp2_conn_set_tls_native_handle (connection->
conn, connection->
session);
2473 connection->
conn_ref.user_data = connection;
2488 connection->
timer = NULL;
2490 if (ngtcp2_conn_in_closing_period (connection->
conn))
2493 "Closing period over\n");
2497 if (ngtcp2_conn_in_draining_period (connection->
conn))
2500 "Draining period over\n");
2515 ngtcp2_duration pto;
2518 if (NULL != connection->
timer)
2521 connection->
timer = NULL;
2523 pto = ngtcp2_conn_get_pto (connection->
conn);
2530 "Start draining period\n");
2547 ngtcp2_path_storage
ps;
2549 ngtcp2_ssize nwrite;
2550 ngtcp2_duration pto;
2553 if (NULL == connection->
conn ||
2554 ngtcp2_conn_in_closing_period (connection->
conn) ||
2555 ngtcp2_conn_in_draining_period (connection->
conn))
2561 "Start closing period\n");
2565 if (NULL != connection->
timer)
2568 connection->
timer = NULL;
2570 pto = ngtcp2_conn_get_pto (connection->
conn);
2581 ngtcp2_path_storage_zero (&
ps);
2582 nwrite = ngtcp2_conn_write_connection_close (connection->
conn,
2586 NGTCP2_MAX_UDP_PAYLOAD_SIZE,
2592 "ngtcp2_conn_write_connection_close: %s\n",
2593 ngtcp2_strerror (nwrite));
2623 "Closing period, send CONNECTION_CLOSE\n");
2652 if (NGTCP2_CCERR_TYPE_IDLE_CLOSE == connection->
last_error.type)
2662 if (ngtcp2_conn_in_draining_period (connection->
conn))
2688 rv = ngtcp2_conn_handle_expiry (connection->
conn,
timestamp ());
2692 "ngtcp2_conn_handle_expiry: %s\n",
2693 ngtcp2_strerror (rv));
2694 ngtcp2_ccerr_set_liberr (&connection->
last_error, rv, NULL, 0);
2713 "timeoutcb func called!\n");
2714 connection->
timer = NULL;
2761 ngtcp2_tstamp expiry;
2767 expiry = ngtcp2_conn_get_expiry (connection->
conn);
2770 if (NULL != connection->
timer)
2773 connection->
timer = NULL;
2778 "Timer has expired\n");
2785 (
double) (expiry - now) / NGTCP2_SECONDS);
2788 (expiry - now) / 1000ULL + 1);
2806 ngtcp2_path_storage
ps;
2809 ngtcp2_ssize nwrite;
2810 ngtcp2_ssize wdatalen;
2811 nghttp3_vec vec[16];
2812 nghttp3_ssize sveccnt;
2817 ngtcp2_path_storage_zero (&
ps);
2826 ngtcp2_conn_get_max_data_left (connection->
conn))
2828 sveccnt = nghttp3_conn_writev_stream (connection->
h3_conn,
2836 "nghttp3_conn_writev_stream: %s\n",
2837 nghttp3_strerror (sveccnt));
2839 ngtcp2_ccerr_set_application_error (
2841 nghttp3_err_infer_quic_app_error_code (sveccnt),
2848 flags = NGTCP2_WRITE_STREAM_FLAG_MORE;
2850 flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
2852 nwrite = ngtcp2_conn_writev_stream (connection->
conn,
2867 case NGTCP2_ERR_STREAM_DATA_BLOCKED:
2868 nghttp3_conn_block_stream (connection->
h3_conn, stream_id);
2870 case NGTCP2_ERR_STREAM_SHUT_WR:
2871 nghttp3_conn_shutdown_stream_write (connection->
h3_conn, stream_id);
2873 case NGTCP2_ERR_WRITE_MORE:
2874 rv = nghttp3_conn_add_write_offset (connection->
h3_conn, stream_id,
2879 "nghttp3_conn_add_write_offset: %s\n",
2880 nghttp3_strerror (rv));
2881 ngtcp2_ccerr_set_application_error (
2883 nghttp3_err_infer_quic_app_error_code (rv),
2890 "ngtcp2_conn_writev_stream: %s\n",
2891 ngtcp2_strerror (nwrite));
2892 ngtcp2_ccerr_set_liberr (&connection->
last_error,
2900 ngtcp2_conn_update_pkt_tx_time (connection->
conn, ts);
2905 rv = nghttp3_conn_add_write_offset (connection->
h3_conn, stream_id,
2910 "nghttp3_conn_add_write_offset: %s\n",
2911 nghttp3_strerror (rv));
2912 ngtcp2_ccerr_set_application_error (
2914 nghttp3_err_infer_quic_app_error_code (rv),
2940 (ngtcp2_conn_in_closing_period (connection->
conn) ||
2941 ngtcp2_conn_in_draining_period (connection->
conn)))
2982 socklen_t local_addrlen;
2984 socklen_t remote_addrlen;
3014 if (NULL != connection)
3017 "receiver %s already exist or is being connected to\n",
3043 "# connections active",
3065 ngtcp2_conn_set_tls_native_handle (connection->
conn, connection->
session);
3071 "connection_write failed\n");
3097 const struct sockaddr *addr,
3160 "do_shutdown start\n");
3165 gnutls_certificate_free_credentials (
cred);
3204 "do_shutdown finished\n");
3224 struct sockaddr *
local_addr, socklen_t local_addrlen,
3225 struct sockaddr *
remote_addr, socklen_t remote_addrlen,
3226 const ngtcp2_pkt_info *pi,
3227 const uint8_t *
data,
size_t datalen)
3233 path.local.addrlen = local_addrlen;
3235 path.remote.addrlen = remote_addrlen;
3237 rv = ngtcp2_conn_read_pkt (connection->
conn, &path, pi,
data, datalen,
3242 "ngtcp2_conn_read_pkt: %s\n",
3243 ngtcp2_strerror (rv));
3246 case NGTCP2_ERR_DRAINING:
3254 ngtcp2_ccerr_set_liberr (&connection->
last_error, rv, NULL, 0);
3256 case NGTCP2_ERR_RETRY:
3259 case NGTCP2_ERR_DROP_CONN:
3262 case NGTCP2_ERR_CRYPTO:
3265 ngtcp2_ccerr_set_tls_alert (
3267 ngtcp2_conn_get_tls_alert (connection->
conn),
3274 ngtcp2_ccerr_set_liberr (&connection->
last_error, rv, NULL, 0);
3300 struct sockaddr *
local_addr, socklen_t local_addrlen,
3301 struct sockaddr *
remote_addr, socklen_t remote_addrlen,
3302 const ngtcp2_pkt_info *pi,
3303 const uint8_t *
data,
size_t datalen)
3307 remote_addrlen, pi,
data, datalen);
3333 socklen_t local_addrlen,
3335 socklen_t remote_addrlen,
3336 const ngtcp2_cid *dcid,
const ngtcp2_cid *scid,
3341 ngtcp2_transport_params params;
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,
3373 path.local.addrlen = local_addrlen;
3375 path.remote.addrlen = remote_addrlen;
3378 memset (new_connection, 0,
sizeof (
struct Connection));
3380 gnutls_init (&new_connection->
session,
3382 | GNUTLS_ENABLE_EARLY_DATA
3383 | GNUTLS_NO_END_OF_EARLY_DATA);
3385 gnutls_credentials_set (new_connection->
session,
3386 GNUTLS_CRD_CERTIFICATE,
cred);
3388 ngtcp2_transport_params_default (¶ms);
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;
3399 ngtcp2_settings_default (&settings);
3401 scid_.datalen = NGTCP2_MAX_CIDLEN;
3403 &scid_.data, scid_.datalen);
3405 rv = ngtcp2_conn_server_new (&
conn,
3418 "ngtcp2_conn_server_new: %s\n",
3419 ngtcp2_strerror (rv));
3431 ngtcp2_crypto_gnutls_configure_server_session (new_connection->
session);
3432 ngtcp2_conn_set_tls_native_handle (new_connection->
conn,
3434 gnutls_session_set_ptr (new_connection->
session,
3438 new_connection->
conn_ref.user_data = new_connection;
3442 return new_connection;
3463 struct sockaddr *
local_addr, socklen_t local_addrlen,
3464 struct sockaddr *
remote_addr, socklen_t remote_addrlen,
3465 const ngtcp2_pkt_info *pi,
3466 const uint8_t *
data,
size_t datalen)
3468 ngtcp2_version_cid version_cid;
3471 rv = ngtcp2_pkt_decode_version_cid (&version_cid,
data, datalen,
3477 case NGTCP2_ERR_VERSION_NEGOTIATION:
3482 "Can't decode version and CID: %s\n",
3483 ngtcp2_strerror (rv));
3487 if (NULL == connection)
3489 ngtcp2_pkt_hd header;
3490 rv = ngtcp2_accept (&header,
data, datalen);
3494 "ngtcp2_accept: %s\n",
3495 ngtcp2_strerror (rv));
3504 remote_addrlen, &header.scid, &header.dcid,
3506 if (NULL == connection)
3509 "accept connection error!\n");
3518 remote_addrlen, pi,
data, datalen);
3540 if (ngtcp2_conn_in_closing_period (connection->
conn))
3550 if (ngtcp2_conn_in_draining_period (connection->
conn))
3556 remote_addrlen, pi,
data, datalen);
3578 struct sockaddr_storage sa;
3579 socklen_t salen =
sizeof (sa);
3581 uint8_t buf[UINT16_MAX];
3587 socklen_t local_addrlen;
3614 (
struct sockaddr *) &sa,
3618 struct sockaddr *addr = (
struct sockaddr*) &sa;
3620 if (EAGAIN == errno)
3623 "Failed to recv from %s family %d failed sock %p\n",
3632 "Read %llu bytes\n",
3633 (
unsigned long long) rcvd);
3638 "Read 0 bytes from UDP socket\n");
3652 ngtcp2_pkt_info pi = {0};
3655 (
struct sockaddr *) &sa,
3656 salen, &pi, buf, rcvd);
3665 "connection write error!\n");
3671 ngtcp2_pkt_info pi = {0};
3675 (
struct sockaddr *) &sa, salen,
3697 const char *cfgfile,
3701 struct sockaddr *in;
3703 struct sockaddr_storage in_sto;
3743 "Creating new certificate\n");
3748 "gnunet-transport-certificate-creation",
3749 "gnunet-transport-certificate-creation",
3756 "Can't create new key pair %s/%s\n",
3786 "Failed to setup UDP socket address with path `%s'\n",
3799 "Failed to create socket for %s family %d\n",
3807 if (AF_INET6 == in->sa_family)
3818 "Failed to bind socket for %s family %d sock %p\n",
3829 sto_len =
sizeof(in_sto);
3831 (
struct sockaddr *) &in_sto,
3834 memcpy (&in_sto, in, in_len);
3839 in = (
struct sockaddr *) &in_sto;
3843 "Bound to `%s' sock %p\n",
3844 GNUNET_a2s ((
const struct sockaddr *) &in_sto,
3847 switch (in->sa_family)
3850 my_port = ntohs (((
struct sockaddr_in *) in)->sin_port);
3854 my_port = ntohs (((
struct sockaddr_in6 *) in)->sin6_port);
3866 rv = gnutls_certificate_allocate_credentials (&
cred);
3868 rv = gnutls_certificate_set_x509_system_trust (
cred);
3872 "cred init failed: %s\n",
3873 gnutls_strerror (rv));
3876 rv = gnutls_certificate_set_x509_key_file (
cred,
3879 GNUTLS_X509_FMT_PEM);
3881 "key_file: %s\ncert_file: %s\n",
3882 key_file, cert_file);
3888 "gnutls_certificate_set_x509_key_file: %s\n",
3889 gnutls_strerror (rv));
3901 "Transport service is lacking PILS connection. Exiting.\n"));
3930 (
const struct sockaddr **) &in,
3955 "Starting http3 communicator\n");
3960 "gnunet-communicator-http3",
3961 _ (
"GNUnet HTTP3 communicator"),
struct GNUNET_GETOPT_CommandLineOption options[]
struct GNUNET_MessageHeader * msg
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
static int start
Set if we are to start default services (including ARM).
static int ret
Final status code.
static int do_shutdown
Set to GNUNET_YES if we are shutting down.
static uint16_t port
Port number.
static char * peer_id
Option –peer.
static int send_conn_close(struct Connection *connection)
Send the packet in the conn_closebuf.
static void start_draining_period(struct Connection *connection)
Start the draining period, called after receiving CONNECTION_CLOSE.
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 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 connection_write(struct Connection *connection)
Write the data in the stream into the packet and handle timer.
static int get_connection_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all connection to clean up.
static void mq_destroy_d(struct GNUNET_MQ_Handle *mq, void *impl_state)
Signature of functions implementing the destruction of a message queue.
static int get_stream_delete_it(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator over all streams to clean up.
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 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.
#define PRIORITY
the priorities to use on the ciphers, key exchange methods, and macs.
static int stream_start_response(struct Connection *connection, struct Stream *stream)
Make response to the request.
#define COMMUNICATOR_ADDRESS_PREFIX
Address prefix used by the communicator.
static void long_poll_timeoutcb(void *cls)
Timeout callback function in the long polling struct.
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 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 connection_write_streams(struct Connection *connection)
Write HTTP stream data and send the packets.
static int send_packet(struct Connection *connection, const uint8_t *data, size_t datalen)
Send the udp packet to remote.
static uint64_t timestamp(void)
Get current timestamp.
#define ADDRESS_VALIDITY_PERIOD
How long do we believe our addresses to remain up (before the other peer should revalidate).
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 gnutls_certificate_credentials_t cred
The credential.
static int setup_httpconn(struct Connection *connection)
Setup the http3 connection.
network_error
Defines some error types related to network errors.
@ NETWORK_ERR_SEND_BLOCKED
static int client_gnutls_init(struct Connection *connection)
As the client, initialize the corresponding connection.
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 void connection_destroy(struct Connection *connection)
Destroys a receiving state due to timeout or shutdown.
static void try_connection_reversal(void *cls, const struct sockaddr *addr, socklen_t addrlen)
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 struct GNUNET_NT_InterfaceScanner * is
Network scanner to determine network types.
static void connection_update_timer(struct Connection *connection)
Update the timer.
static int disable_v6
IPv6 disabled or not.
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 struct GNUNET_STATISTICS_Handle * stats
For logging statistics.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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 int recv_tx_key_cb(ngtcp2_conn *conn, ngtcp2_encryption_level level, void *user_data)
The callback function for ngtcp2_callbacks.recv_tx_key.
#define NUM_LONG_POLL
Long polling requests' number.
static void http_consume(struct Connection *connection, int64_t stream_id, size_t consumed)
Extend connection and stream offset.
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
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 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 sock_read(void *cls)
Socket read task.
#define COMMUNICATOR_CONFIG_SECTION
Configuration section used by the communicator.
static nghttp3_nv make_nv(const char *name, const char *value, uint8_t flag)
Make name/value pair for request headers.
static void nat_address_cb(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
static struct GNUNET_TRANSPORT_CommunicatorHandle * ch
Our environment.
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 struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
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 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 void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Setup communicator and launch network interactions.
static void reschedule_peer_timeout(struct Connection *connection)
Increment connection timeout due to activity.
static struct GNUNET_NAT_Handle * nat
Connection to NAT service.
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 struct GNUNET_CONTAINER_MultiHashMap * addr_map
Map of sockaddr -> struct Connection.
static struct GNUNET_SCHEDULER_Task * read_task
ID of listen task.
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 handle_error(struct Connection *connection)
Handle errors.
static void setup_connection_mq(struct Connection *connection)
Setup the MQ for the connection.
static void mq_cancel(struct GNUNET_MQ_Handle *mq, void *impl_state)
Implementation function that cancels the currently sent message.
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 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 void close_waitcb(void *cls)
The timeout callback function of closing/draining period.
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 ...
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 Stream * create_stream(struct Connection *connection, int64_t stream_id)
Create a new stream of connection with stream_id.
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 start_closing_period(struct Connection *connection)
Start the closing period and build the packet contains CONNECTION_CLOSE.
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 timeoutcb(void *cls)
The timer callback function.
static int handle_expiry(struct Connection *connection)
Handles expired timer.
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 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,...
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 submit_get_request(struct Connection *connection, struct Stream *stream)
Client side submits the GET request, allow the server to send messages.
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 void remove_stream(struct Connection *connection, int64_t stream_id)
Remove the stream with the specified stream_id in connection.
static void mq_error(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static struct GNUNET_PILS_Handle * pils
Handle to the pils service.
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.
static int stream_send_data(struct Stream *stream, uint8_t *data, size_t datalen)
Send message through the specified stream.
static struct GNUNET_TRANSPORT_AddressIdentifier * ai
Handle to the operation that publishes our address.
static char * address
GNS address for this phone.
static struct GNUNET_PEERSTORE_Handle * ps
Handle to the PEERSTORE service.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static struct GNUNET_NAT_AUTO_Test * nt
Handle to a NAT test operation.
static char * remote_addr
Remote address to use for connection reversal request.
static char * local_addr
Local address to use for connection reversal request.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Core service; the main API for encrypted P2P communications.
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.
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Constants for network protocols.
API to create, modify and access statistics.
Bandwidth allocation API for applications to interact with.
API of the transport service towards the communicator processes.
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.
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.
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.
#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...
void GNUNET_TRANSPORT_communicator_disconnect(struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
Disconnect from the transport service.
struct GNUNET_TRANSPORT_CommunicatorHandle * GNUNET_TRANSPORT_communicator_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section_name, const char *addr_prefix, enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc, GNUNET_TRANSPORT_CommunicatorMqInit mq_init, void *mq_init_cls, GNUNET_TRANSPORT_CommunicatorNotify notify_cb, void *notify_cb_cls, GNUNET_TRANSPORT_StartBurstNotify sb)
Connect to the transport service.
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_TRANSPORT_CC_RELIABLE
Transmission is reliabile (with ACKs), e.g.
@ GNUNET_TRANSPORT_CS_OUTBOUND
this is an outbound connection (transport initiated)
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_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.
#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?
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_STRONG
High-quality operations are desired.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_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.
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.
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.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash 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_log(kind,...)
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
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).
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#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...
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...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
GNUNET_MQ_Error
Error codes for the queue.
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.
void GNUNET_MQ_impl_send_continue(struct GNUNET_MQ_Handle *mq)
Call the send implementation for the next queued message, if any.
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...
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
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).
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_test_pf(int pf)
Test if the given protocol family is supported by this system.
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.
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).
GNUNET_NetworkType
Types of networks (with separate quotas) we support.
void GNUNET_NT_scanner_done(struct GNUNET_NT_InterfaceScanner *is)
Terminate interface scanner.
struct GNUNET_NT_InterfaceScanner * GNUNET_NT_scanner_init(void)
Initialize the address characterization client handle.
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.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
enum GNUNET_GenericReturnValue GNUNET_process_run_command_va(struct GNUNET_Process *p, const char *filename,...)
Set the command and start a process.
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.
struct GNUNET_Process * GNUNET_process_create(enum GNUNET_OS_InheritStdioFlags std_inheritance)
Create a process handle.
@ GNUNET_OS_INHERIT_STD_OUT_AND_ERR
When these flags are set, the child process will inherit stdout and stderr of the parent.
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,...
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
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...
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,...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
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.
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.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Used to keep track of context of peer.
ngtcp2_conn * conn
The QUIC connection.
ngtcp2_ssize conn_closebuflen
The length of conn_closebuf;.
enum GNUNET_NetworkType nt
Which network type does this queue use?
gnutls_session_t session
The gnutls session.
struct Long_Poll_Request * long_poll_head
head pointer of long polling struct queue.
ngtcp2_crypto_conn_ref conn_ref
The structure to get a pointer to ngtcp2_conn.
struct sockaddr * address
Address of the other peer.
int is_initiator
Flag to indicate if we are the initiator of the connection.
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.
size_t d_mtu
MTU we allowed transport for this receiver's default queue.
struct GNUNET_PeerIdentity target
To whom are we talking to.
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.
struct GNUNET_CONTAINER_MultiHashMap * streams
Information of the stream.
int id_rcvd
Flag to indicate whether we know the PeerIdentity (target) yet.
struct GNUNET_TIME_Absolute timeout
Timeout for this connection.
struct GNUNET_MQ_Handle * d_mq
Default message queue we are providing for the ch.
ngtcp2_ccerr last_error
The connection error.
uint8_t * conn_closebuf
conn_closebuf contains a packet which contains CONNECTION_CLOSE.
size_t long_poll_len
length of long polling struct queue.
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.
socklen_t address_len
Length of the address.
int connection_destroy_called
connection_destroy already called on connection.
struct GNUNET_SCHEDULER_Task * timer
The timer of this connection.
int id_sent
Flag to indicate whether we have sent OUR PeerIdentity to this peer.
size_t msg_queue_len
length of message queue.
Internal representation of the hash map.
Definition of a command line option.
Handle to a message queue.
Handle for active NAT registrations.
Handle to the interface scanner.
A handle for the PILS service.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Internal representation of an address a communicator is currently providing for the transport service...
Opaque handle to the transport service for communicators.
Handle returned to identify the internal data structure the transport API has created to manage a mes...
Message to send using http.
char * buf
buffer containing data to send
struct HTTP_Message * next
next pointer for double linked list
uint64_t delay_time
Timeout value.
struct Long_Poll_Request * prev
Previous structure.
struct Long_Poll_Request * next
Next structure.
struct Stream * stream
The long polling stream.
struct GNUNET_SCHEDULER_Task * timer
Timeout timer for long polling stream.
size_t urilen
The length of request uri.
struct Connection * connection
The connection that stream belongs to.
size_t authoritylen
The length of request authority.
uint8_t * uri
The request uri.
uint8_t * method
The request method.
uint8_t * data
The stream data.
uint64_t datalen
The length of stream data.
int64_t stream_id
ID of this stream.
size_t methodlen
The length of request method.
uint8_t * authority
The request authority.
struct Long_Poll_Request * long_poll_struct
The long polling request structure.