mirror of
https://github.com/moparisthebest/curl
synced 2025-01-11 14:08:07 -05:00
ngtcp2: introduce qlog support
If the QLOGDIR environment variable is set, enable qlogging. ... and create Curl_qlogdir() in the new generic vquic/vquic.c file for QUIC functions that are backend independent. Closes #5353
This commit is contained in:
parent
2a81439553
commit
14c17a2b6e
@ -36,9 +36,9 @@ LIB_VTLS_HFILES = vtls/bearssl.h vtls/gskit.h vtls/gtls.h vtls/mbedtls.h \
|
|||||||
vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h vtls/openssl.h \
|
vtls/mbedtls_threadlock.h vtls/mesalink.h vtls/nssg.h vtls/openssl.h \
|
||||||
vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
|
vtls/schannel.h vtls/sectransp.h vtls/vtls.h vtls/wolfssl.h
|
||||||
|
|
||||||
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c
|
LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c
|
||||||
|
|
||||||
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h
|
LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h vquic/vquic.h
|
||||||
|
|
||||||
LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
|
LIB_VSSH_CFILES = vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "dynbuf.h"
|
#include "dynbuf.h"
|
||||||
|
#include "vquic.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -160,9 +161,25 @@ static int setup_initial_crypto_context(struct quicsocket *qs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quic_settings(ngtcp2_settings *s,
|
static void qlog_callback(void *user_data, const void *data, size_t datalen)
|
||||||
uint64_t stream_buffer_size)
|
|
||||||
{
|
{
|
||||||
|
struct quicsocket *qs = (struct quicsocket *)user_data;
|
||||||
|
if(qs->qlogfd != -1) {
|
||||||
|
ssize_t rc = write(qs->qlogfd, data, datalen);
|
||||||
|
if(rc == -1) {
|
||||||
|
/* on write error, stop further write attempts */
|
||||||
|
close(qs->qlogfd);
|
||||||
|
qs->qlogfd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void quic_settings(struct quicsocket *qs,
|
||||||
|
uint64_t stream_buffer_size,
|
||||||
|
ngtcp2_cid *dcid)
|
||||||
|
{
|
||||||
|
ngtcp2_settings *s = &qs->settings;
|
||||||
ngtcp2_settings_default(s);
|
ngtcp2_settings_default(s);
|
||||||
#ifdef DEBUG_NGTCP2
|
#ifdef DEBUG_NGTCP2
|
||||||
s->log_printf = quic_printf;
|
s->log_printf = quic_printf;
|
||||||
@ -177,6 +194,10 @@ static void quic_settings(ngtcp2_settings *s,
|
|||||||
s->transport_params.initial_max_streams_bidi = 1;
|
s->transport_params.initial_max_streams_bidi = 1;
|
||||||
s->transport_params.initial_max_streams_uni = 3;
|
s->transport_params.initial_max_streams_uni = 3;
|
||||||
s->transport_params.max_idle_timeout = QUIC_IDLE_TIMEOUT;
|
s->transport_params.max_idle_timeout = QUIC_IDLE_TIMEOUT;
|
||||||
|
if(qs->qlogfd != -1) {
|
||||||
|
s->qlog.write = qlog_callback;
|
||||||
|
s->qlog.odcid = *dcid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *keylog_file; /* not thread-safe */
|
static FILE *keylog_file; /* not thread-safe */
|
||||||
@ -825,6 +846,7 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
|
|||||||
struct quicsocket *qs = &conn->hequic[sockindex];
|
struct quicsocket *qs = &conn->hequic[sockindex];
|
||||||
char ipbuf[40];
|
char ipbuf[40];
|
||||||
long port;
|
long port;
|
||||||
|
int qfd;
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
uint8_t paramsbuf[64];
|
uint8_t paramsbuf[64];
|
||||||
ngtcp2_transport_params params;
|
ngtcp2_transport_params params;
|
||||||
@ -864,7 +886,9 @@ CURLcode Curl_quic_connect(struct connectdata *conn,
|
|||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
quic_settings(&qs->settings, data->set.buffer_size);
|
(void)Curl_qlogdir(data, qs->scid.data, NGTCP2_MAX_CIDLEN, &qfd);
|
||||||
|
qs->qlogfd = qfd; /* -1 if failure above */
|
||||||
|
quic_settings(qs, data->set.buffer_size, &qs->dcid);
|
||||||
|
|
||||||
qs->local_addrlen = sizeof(qs->local_addr);
|
qs->local_addrlen = sizeof(qs->local_addr);
|
||||||
rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
|
rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr,
|
||||||
@ -950,6 +974,8 @@ static CURLcode ng_disconnect(struct connectdata *conn,
|
|||||||
int i;
|
int i;
|
||||||
struct quicsocket *qs = &conn->hequic[0];
|
struct quicsocket *qs = &conn->hequic[0];
|
||||||
(void)dead_connection;
|
(void)dead_connection;
|
||||||
|
if(qs->qlogfd != -1)
|
||||||
|
close(qs->qlogfd);
|
||||||
if(qs->ssl)
|
if(qs->ssl)
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
SSL_free(qs->ssl);
|
SSL_free(qs->ssl);
|
||||||
|
@ -63,6 +63,7 @@ struct quicsocket {
|
|||||||
|
|
||||||
nghttp3_conn *h3conn;
|
nghttp3_conn *h3conn;
|
||||||
nghttp3_conn_settings h3settings;
|
nghttp3_conn_settings h3settings;
|
||||||
|
int qlogfd;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
|
@ -34,10 +34,7 @@
|
|||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "strerror.h"
|
#include "strerror.h"
|
||||||
#include "dynbuf.h"
|
#include "vquic.h"
|
||||||
#ifdef HAVE_FCNTL_H
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -204,39 +201,12 @@ CURLcode Curl_quic_connect(struct connectdata *conn, curl_socket_t sockfd,
|
|||||||
|
|
||||||
/* Known to not work on Windows */
|
/* Known to not work on Windows */
|
||||||
#if !defined(WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD)
|
#if !defined(WIN32) && defined(HAVE_QUICHE_CONN_SET_QLOG_FD)
|
||||||
#ifdef O_BINARY
|
|
||||||
#define QLOGMODE O_WRONLY|O_CREAT|O_BINARY
|
|
||||||
#else
|
|
||||||
#define QLOGMODE O_WRONLY|O_CREAT
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
const char *qlog_dir = getenv("QLOGDIR");
|
int qfd;
|
||||||
if(qlog_dir) {
|
(void)Curl_qlogdir(data, qs->scid, sizeof(qs->scid), &qfd);
|
||||||
struct dynbuf fname;
|
if(qfd != -1)
|
||||||
unsigned int i;
|
quiche_conn_set_qlog_fd(qs->conn, qfd,
|
||||||
Curl_dyn_init(&fname, DYN_QLOG_NAME);
|
"qlog title", "curl qlog");
|
||||||
result = Curl_dyn_add(&fname, qlog_dir);
|
|
||||||
if(!result)
|
|
||||||
result = Curl_dyn_add(&fname, "/");
|
|
||||||
for(i = 0; (i < sizeof(qs->scid)) && !result; i++) {
|
|
||||||
char hex[3];
|
|
||||||
msnprintf(hex, 3, "%02x", qs->scid[i]);
|
|
||||||
result = Curl_dyn_add(&fname, hex);
|
|
||||||
}
|
|
||||||
if(!result)
|
|
||||||
result = Curl_dyn_add(&fname, ".qlog");
|
|
||||||
|
|
||||||
if(!result) {
|
|
||||||
int qlogfd = open(Curl_dyn_ptr(&fname), QLOGMODE,
|
|
||||||
data->set.new_file_perms);
|
|
||||||
if(qlogfd != -1)
|
|
||||||
quiche_conn_set_qlog_fd(qs->conn, qlogfd,
|
|
||||||
"qlog title", "curl qlog");
|
|
||||||
}
|
|
||||||
Curl_dyn_free(&fname);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
85
lib/vquic/vquic.c
Normal file
85
lib/vquic/vquic.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_QUIC
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "dynbuf.h"
|
||||||
|
#include "curl_printf.h"
|
||||||
|
#include "vquic.h"
|
||||||
|
|
||||||
|
#ifdef O_BINARY
|
||||||
|
#define QLOGMODE O_WRONLY|O_CREAT|O_BINARY
|
||||||
|
#else
|
||||||
|
#define QLOGMODE O_WRONLY|O_CREAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the QLOGDIR environment variable is set, open and return a file
|
||||||
|
* descriptor to write the log to.
|
||||||
|
*
|
||||||
|
* This function returns error if something failed outside of failing to
|
||||||
|
* create the file. Open file success is deemed by seeing if the returned fd
|
||||||
|
* is != -1.
|
||||||
|
*/
|
||||||
|
CURLcode Curl_qlogdir(struct Curl_easy *data,
|
||||||
|
unsigned char *scid,
|
||||||
|
size_t scidlen,
|
||||||
|
int *qlogfdp)
|
||||||
|
{
|
||||||
|
const char *qlog_dir = getenv("QLOGDIR");
|
||||||
|
*qlogfdp = -1;
|
||||||
|
if(qlog_dir) {
|
||||||
|
struct dynbuf fname;
|
||||||
|
CURLcode result;
|
||||||
|
unsigned int i;
|
||||||
|
Curl_dyn_init(&fname, DYN_QLOG_NAME);
|
||||||
|
result = Curl_dyn_add(&fname, qlog_dir);
|
||||||
|
if(!result)
|
||||||
|
result = Curl_dyn_add(&fname, "/");
|
||||||
|
for(i = 0; (i < scidlen) && !result; i++) {
|
||||||
|
char hex[3];
|
||||||
|
msnprintf(hex, 3, "%02x", scid[i]);
|
||||||
|
result = Curl_dyn_add(&fname, hex);
|
||||||
|
}
|
||||||
|
if(!result)
|
||||||
|
result = Curl_dyn_add(&fname, ".qlog");
|
||||||
|
|
||||||
|
if(!result) {
|
||||||
|
int qlogfd = open(Curl_dyn_ptr(&fname), QLOGMODE,
|
||||||
|
data->set.new_file_perms);
|
||||||
|
if(qlogfd != -1)
|
||||||
|
*qlogfdp = qlogfd;
|
||||||
|
}
|
||||||
|
Curl_dyn_free(&fname);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
|
#endif
|
34
lib/vquic/vquic.h
Normal file
34
lib/vquic/vquic.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef HEADER_CURL_VQUIC_QUIC_H
|
||||||
|
#define HEADER_CURL_VQUIC_QUIC_H
|
||||||
|
/***************************************************************************
|
||||||
|
* _ _ ____ _
|
||||||
|
* Project ___| | | | _ \| |
|
||||||
|
* / __| | | | |_) | |
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
* are also available at https://curl.haxx.se/docs/copyright.html.
|
||||||
|
*
|
||||||
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
* copies of the Software, and permit persons to whom the Software is
|
||||||
|
* furnished to do so, under the terms of the COPYING file.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "curl_setup.h"
|
||||||
|
|
||||||
|
#ifdef ENABLE_QUIC
|
||||||
|
CURLcode Curl_qlogdir(struct Curl_easy *data,
|
||||||
|
unsigned char *scid,
|
||||||
|
size_t scidlen,
|
||||||
|
int *qlogfdp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HEADER_CURL_VQUIC_QUIC_H */
|
Loading…
Reference in New Issue
Block a user