diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vquic')
-rw-r--r-- | Utilities/cmcurl/lib/vquic/ngtcp2.c | 66 | ||||
-rw-r--r-- | Utilities/cmcurl/lib/vquic/quiche.c | 33 |
2 files changed, 60 insertions, 39 deletions
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.c b/Utilities/cmcurl/lib/vquic/ngtcp2.c index d4d0e8b..7f07675 100644 --- a/Utilities/cmcurl/lib/vquic/ngtcp2.c +++ b/Utilities/cmcurl/lib/vquic/ngtcp2.c @@ -57,6 +57,8 @@ #define H3BUGF(x) do { } while(0) #endif +#define H3_ALPN_H3_29 "\x5h3-29" + /* * This holds outgoing HTTP/3 stream data that is used by nghttp3 until acked. * It is used as a circular buffer. Add new bytes at the end until it reaches @@ -224,7 +226,7 @@ static int write_client_handshake(struct quicsocket *qs, int rv; crypto_data = &qs->crypto_data[level]; - if(crypto_data->buf == NULL) { + if(!crypto_data->buf) { crypto_data->buf = malloc(4096); if(!crypto_data->buf) return 0; @@ -351,8 +353,8 @@ static int quic_init_ssl(struct quicsocket *qs) SSL_set_app_data(qs->ssl, qs); SSL_set_connect_state(qs->ssl); - alpn = (const uint8_t *)NGHTTP3_ALPN_H3; - alpnlen = sizeof(NGHTTP3_ALPN_H3) - 1; + alpn = (const uint8_t *)H3_ALPN_H3_29; + alpnlen = sizeof(H3_ALPN_H3_29) - 1; if(alpn) SSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen); @@ -529,8 +531,8 @@ static int quic_init_ssl(struct quicsocket *qs) } /* strip the first byte (the length) from NGHTTP3_ALPN_H3 */ - alpn.data = (unsigned char *)NGHTTP3_ALPN_H3 + 1; - alpn.size = sizeof(NGHTTP3_ALPN_H3) - 2; + alpn.data = (unsigned char *)H3_ALPN_H3_29 + 1; + alpn.size = sizeof(H3_ALPN_H3_29) - 2; if(alpn.data) gnutls_alpn_set_protocols(qs->ssl, &alpn, 1, 0); @@ -580,7 +582,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, { struct quicsocket *qs = (struct quicsocket *)user_data; ssize_t nconsumed; - int fin = flags & NGTCP2_STREAM_DATA_FLAG_FIN ? 1 : 0; + int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0; (void)offset; (void)stream_user_data; @@ -601,7 +603,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, static int cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t offset, size_t datalen, void *user_data, + uint64_t offset, uint64_t datalen, void *user_data, void *stream_user_data) { struct quicsocket *qs = (struct quicsocket *)user_data; @@ -613,7 +615,7 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -632,7 +634,7 @@ static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id, rv = nghttp3_conn_close_stream(qs->h3conn, stream_id, app_error_code); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -651,7 +653,7 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -680,7 +682,7 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -739,7 +741,10 @@ static ngtcp2_callbacks ng_callbacks = { NULL, /* handshake_confirmed */ NULL, /* recv_new_token */ ngtcp2_crypto_delete_crypto_aead_ctx_cb, - ngtcp2_crypto_delete_crypto_cipher_ctx_cb + ngtcp2_crypto_delete_crypto_cipher_ctx_cb, + NULL, /* recv_datagram */ + NULL, /* ack_datagram */ + NULL /* lost_datagram */ }; /* @@ -758,7 +763,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, ngtcp2_path path; /* TODO: this must be initialized properly */ struct quicsocket *qs = &conn->hequic[sockindex]; char ipbuf[40]; - long port; + int port; int qfd; if(qs->conn) @@ -773,7 +778,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; } - infof(data, "Connect socket %d over QUIC to %s:%ld\n", + infof(data, "Connect socket %d over QUIC to %s:%d\n", sockfd, ipbuf, port); qs->version = NGTCP2_PROTO_VER_MAX; @@ -807,8 +812,8 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_QUIC_CONNECT_ERROR; ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, - qs->local_addrlen, NULL); - ngtcp2_addr_init(&path.remote, addr, addrlen, NULL); + qs->local_addrlen); + ngtcp2_addr_init(&path.remote, addr, addrlen); rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, NGTCP2_PROTO_VER_MIN, &ng_callbacks, @@ -827,7 +832,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, */ int Curl_quic_ver(char *p, size_t len) { - ngtcp2_info *ng2 = ngtcp2_version(0); + const ngtcp2_info *ng2 = ngtcp2_version(0); nghttp3_info *ht3 = nghttp3_version(0); return msnprintf(p, len, "ngtcp2/%s nghttp3/%s", ng2->version_str, ht3->version_str); @@ -870,8 +875,10 @@ static void qs_disconnect(struct quicsocket *qs) #endif qs->ssl = NULL; #ifdef USE_GNUTLS - if(qs->cred) + if(qs->cred) { gnutls_certificate_free_credentials(qs->cred); + qs->cred = NULL; + } #endif for(i = 0; i < 3; i++) Curl_safefree(qs->crypto_data[i].buf); @@ -927,6 +934,7 @@ static const struct Curl_handler Curl_handler_http3 = { ng_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ng_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -1291,7 +1299,6 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, { struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; - int rv; (void)user_data; if(!data->set.postfields) { @@ -1302,8 +1309,8 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE); if(stream->h3out->used == 0) { - rv = nghttp3_conn_resume_stream(conn, stream_id); - if(rv != 0) { + int rv = nghttp3_conn_resume_stream(conn, stream_id); + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } } @@ -1539,7 +1546,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, } /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + if(authority_idx && authority_idx != AUTHORITY_DST_IDX) { nghttp3_nv authority = nva[authority_idx]; for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { nva[i] = nva[i - 1]; @@ -1730,12 +1737,12 @@ static CURLcode ng_process_ingress(struct Curl_easy *data, } ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, - qs->local_addrlen, NULL); + qs->local_addrlen); ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr, - remote_addrlen, NULL); + remote_addrlen); rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts); - if(rv != 0) { + if(rv) { /* TODO Send CONNECTION_CLOSE if possible */ return CURLE_RECV_ERROR; } @@ -1779,7 +1786,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, } rv = ngtcp2_conn_handle_expiry(qs->qconn, ts); - if(rv != 0) { + if(rv) { failf(data, "ngtcp2_conn_handle_expiry returned error: %s", ngtcp2_strerror(rv)); return CURLE_SEND_ERROR; @@ -1788,7 +1795,6 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, ngtcp2_path_storage_zero(&ps); for(;;) { - outlen = -1; veccnt = 0; stream_id = -1; fin = 0; @@ -1816,7 +1822,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, outlen == NGTCP2_ERR_STREAM_SHUT_WR) { assert(ndatalen == -1); rv = nghttp3_conn_block_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_block_stream returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; @@ -1826,7 +1832,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, else if(outlen == NGTCP2_ERR_WRITE_MORE) { assert(ndatalen >= 0); rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_add_write_offset returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; @@ -1842,7 +1848,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, } else if(ndatalen >= 0) { rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_add_write_offset returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; diff --git a/Utilities/cmcurl/lib/vquic/quiche.c b/Utilities/cmcurl/lib/vquic/quiche.c index d138dd3..b62d884 100644 --- a/Utilities/cmcurl/lib/vquic/quiche.c +++ b/Utilities/cmcurl/lib/vquic/quiche.c @@ -157,6 +157,7 @@ static const struct Curl_handler Curl_handler_http3 = { quiche_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ quiche_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -180,7 +181,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, struct quicsocket *qs = &conn->hequic[sockindex]; char *keylog_file = NULL; char ipbuf[40]; - long port; + int port; #ifdef DEBUG_QUICHE /* initialize debug log callback only once */ @@ -225,7 +226,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, quiche_config_log_keys(qs->cfg); qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid, - sizeof(qs->scid), qs->cfg); + sizeof(qs->scid), addr, addrlen, qs->cfg); if(!qs->conn) { failf(data, "can't create quiche connection"); return CURLE_OUT_OF_MEMORY; @@ -359,22 +360,34 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd, ssize_t recvd; uint8_t *buf = (uint8_t *)data->state.buffer; size_t bufsize = data->set.buffer_size; + struct sockaddr_storage from; + socklen_t from_len; + quiche_recv_info recv_info; + + DEBUGASSERT(qs->conn); /* in case the timeout expired */ quiche_conn_on_timeout(qs->conn); do { - recvd = recv(sockfd, buf, bufsize, 0); + from_len = sizeof(from); + + recvd = recvfrom(sockfd, buf, bufsize, 0, + (struct sockaddr *)&from, &from_len); + if((recvd < 0) && ((SOCKERRNO == EAGAIN) || (SOCKERRNO == EWOULDBLOCK))) break; if(recvd < 0) { - failf(data, "quiche: recv() unexpectedly returned %zd " + failf(data, "quiche: recvfrom() unexpectedly returned %zd " "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd); return CURLE_RECV_ERROR; } - recvd = quiche_conn_recv(qs->conn, buf, recvd); + recv_info.from = (struct sockaddr *) &from; + recv_info.from_len = from_len; + + recvd = quiche_conn_recv(qs->conn, buf, recvd, &recv_info); if(recvd == QUICHE_ERR_DONE) break; @@ -397,9 +410,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd, ssize_t sent; uint8_t out[1200]; int64_t timeout_ns; + quiche_send_info send_info; do { - sent = quiche_conn_send(qs->conn, out, sizeof(out)); + sent = quiche_conn_send(qs->conn, out, sizeof(out), &send_info); if(sent == QUICHE_ERR_DONE) break; @@ -408,9 +422,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd, return CURLE_SEND_ERROR; } - sent = send(sockfd, out, sent, 0); + sent = sendto(sockfd, out, sent, 0, + (struct sockaddr *)&send_info.to, send_info.to_len); if(sent < 0) { - failf(data, "send() returned %zd", sent); + failf(data, "sendto() returned %zd", sent); return CURLE_SEND_ERROR; } } while(1); @@ -748,7 +763,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, } /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + if(authority_idx && authority_idx != AUTHORITY_DST_IDX) { quiche_h3_header authority = nva[authority_idx]; for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { nva[i] = nva[i - 1]; |