Packages
hackney
3.0.2
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/lsquic/src/liblsquic/lsquic_ev_log.c
/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */
#ifndef WIN32
#include <arpa/inet.h>
#else
#include <vc_compat.h>
#endif
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <openssl/x509.h>
#include "lsquic.h"
#include "lsquic_types.h"
#include "lsquic_int_types.h"
#include "lsquic_packet_common.h"
#include "lsquic_packet_gquic.h"
#include "lsquic_packet_in.h"
#include "lsquic_packet_out.h"
#include "lsquic_parse.h"
#include "lsquic_frame_common.h"
#include "lsquic_headers.h"
#include "lsquic_str.h"
#include "lsquic_frame_reader.h"
#include "lsquic_enc_sess.h"
#include "lsquic_ev_log.h"
#include "lsquic_sizes.h"
#include "lsquic_trans_params.h"
#include "lsquic_util.h"
#include "lsquic_hash.h"
#include "lsquic_conn.h"
#include "lsxpack_header.h"
#define LSQUIC_LOGGER_MODULE LSQLM_EVENT
#include "lsquic_logger.h"
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
/* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */
/* Messages that do not include connection ID go above this point */
#define LSQUIC_LOG_CONN_ID cid
#define LCID(...) LSQ_LOG2(LSQ_LOG_DEBUG, __VA_ARGS__) /* LCID: log with CID */
/* Messages that are to include connection ID go below this point */
/* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */
/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV */
void
lsquic_ev_log_packet_in (const lsquic_cid_t *cid,
const lsquic_packet_in_t *packet_in)
{
unsigned packet_sz;
switch (packet_in->pi_flags & (PI_FROM_MINI|PI_GQUIC))
{
case PI_FROM_MINI|PI_GQUIC:
LCID("RX packet #%"PRIu64" (mini)", packet_in->pi_packno);
break;
case PI_FROM_MINI:
LCID("RX packet #%"PRIu64" %s (mini), ecn: %u",
packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type],
lsquic_packet_in_ecn(packet_in));
break;
case PI_GQUIC:
packet_sz = packet_in->pi_data_sz
+ (packet_in->pi_flags & PI_DECRYPTED ? GQUIC_PACKET_HASH_SZ : 0);
LCID("RX packet #%"PRIu64", size: %u", packet_in->pi_packno, packet_sz);
break;
default:
packet_sz = packet_in->pi_data_sz
+ (packet_in->pi_flags & PI_DECRYPTED ? IQUIC_TAG_LEN : 0);
if (packet_in->pi_flags & PI_LOG_QL_BITS)
LCID("RX packet #%"PRIu64" %s, size: %u; ecn: %u, spin: %d; "
"path: %hhu; Q: %d; L: %d",
packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type],
packet_sz,
lsquic_packet_in_ecn(packet_in),
/* spin bit value is only valid for short packet headers */
lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id,
((packet_in->pi_flags & PI_SQUARE_BIT) > 0),
((packet_in->pi_flags & PI_LOSS_BIT) > 0));
else
LCID("RX packet #%"PRIu64" %s, size: %u; ecn: %u, spin: %d; "
"path: %hhu",
packet_in->pi_packno, lsquic_hety2str[packet_in->pi_header_type],
packet_sz,
lsquic_packet_in_ecn(packet_in),
/* spin bit value is only valid for short packet headers */
lsquic_packet_in_spin_bit(packet_in), packet_in->pi_path_id);
break;
}
}
void
lsquic_ev_log_ack_frame_in (const lsquic_cid_t *cid,
const struct ack_info *acki)
{
char buf[MAX_ACKI_STR_SZ];
lsquic_acki2str(acki, buf, sizeof(buf));
LCID("RX ACK frame: %s", buf);
}
void
lsquic_ev_log_stream_frame_in (const lsquic_cid_t *cid,
const struct stream_frame *frame)
{
LCID("RX STREAM frame: stream %"PRIu64"; offset %"PRIu64"; size %"PRIu16
"; fin: %d", frame->stream_id, frame->data_frame.df_offset,
frame->data_frame.df_size, (int) frame->data_frame.df_fin);
}
void
lsquic_ev_log_crypto_frame_in (const lsquic_cid_t *cid,
const struct stream_frame *frame, unsigned enc_level)
{
LCID("RX CRYPTO frame: level %u; offset %"PRIu64"; size %"PRIu16,
enc_level, frame->data_frame.df_offset, frame->data_frame.df_size);
}
void
lsquic_ev_log_stop_waiting_frame_in (const lsquic_cid_t *cid,
lsquic_packno_t least)
{
LCID("RX STOP_WAITING frame: least unacked packno %"PRIu64, least);
}
void
lsquic_ev_log_window_update_frame_in (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id, uint64_t offset)
{
LCID("RX WINDOW_UPDATE frame: stream %"PRIu64"; offset %"PRIu64,
stream_id, offset);
}
void
lsquic_ev_log_blocked_frame_in (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id)
{
LCID("RX BLOCKED frame: stream %"PRIu64, stream_id);
}
void
lsquic_ev_log_connection_close_frame_in (const lsquic_cid_t *cid,
uint64_t error_code, int reason_len, const char *reason)
{
LCID("RX CONNECTION_CLOSE frame: error code %"PRIu64", reason: %.*s",
error_code, reason_len, reason);
}
void
lsquic_ev_log_goaway_frame_in (const lsquic_cid_t *cid, uint32_t error_code,
lsquic_stream_id_t stream_id, int reason_len, const char *reason)
{
LCID("RX GOAWAY frame: error code %"PRIu32", stream %"PRIu64
", reason: %.*s", error_code, stream_id, reason_len, reason);
}
void
lsquic_ev_log_rst_stream_frame_in (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id, uint64_t offset, uint64_t error_code)
{
LCID("RX RST_STREAM frame: error code %"PRIu64", stream %"PRIu64
", offset: %"PRIu64, error_code, stream_id, offset);
}
void
lsquic_ev_log_stop_sending_frame_in (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id, uint64_t error_code)
{
LCID("RX STOP_SENDING frame: error code %"PRIu64", stream %"PRIu64,
error_code, stream_id);
}
void
lsquic_ev_log_padding_frame_in (const lsquic_cid_t *cid, size_t len)
{
LCID("RX PADDING frame of %zd bytes", len);
}
void
lsquic_ev_log_ping_frame_in (const lsquic_cid_t *cid)
{
LCID("RX PING frame");
}
void
lsquic_ev_log_packet_created (const lsquic_cid_t *cid,
const struct lsquic_packet_out *packet_out)
{
LCID("created packet #%"PRIu64" %s; flags: version=%d, nonce=%d, conn_id=%d",
packet_out->po_packno,
lsquic_hety2str[packet_out->po_header_type],
!!(packet_out->po_flags & PO_VERSION),
!!(packet_out->po_flags & PO_NONCE),
!!(packet_out->po_flags & PO_CONN_ID));
}
void
lsquic_ev_log_packet_sent (const lsquic_cid_t *cid,
const struct lsquic_packet_out *packet_out)
{
char frames[lsquic_frame_types_str_sz];
if (lsquic_packet_out_verneg(packet_out))
LCID("TX version negotiation packet, size %hu",
packet_out->po_data_sz);
else if (lsquic_packet_out_retry(packet_out))
LCID("TX stateless retry packet, size %hu", packet_out->po_data_sz);
else if (lsquic_packet_out_pubres(packet_out))
LCID("TX public reset packet, size %hu", packet_out->po_data_sz);
else if (packet_out->po_lflags & POL_GQUIC)
LCID("TX packet #%"PRIu64" (%s), size %hu",
packet_out->po_packno,
/* Frame types is a list of different frames types contained
* in the packet, no more. Count and order of frames is not
* printed.
*/
lsquic_frame_types_to_str(frames, sizeof(frames),
packet_out->po_frame_types),
packet_out->po_enc_data_sz);
else if (packet_out->po_lflags & POL_LOG_QL_BITS)
LCID("TX packet #%"PRIu64" %s (%s), size %hu, "
"ecn: %u, spin: %d; kp: %u, path: %hhu, flags: %u; "
"Q: %u; L: %u",
packet_out->po_packno, lsquic_hety2str[packet_out->po_header_type],
/* Frame types is a list of different frames types contained
* in the packet, no more. Count and order of frames is not
* printed.
*/
lsquic_frame_types_to_str(frames, sizeof(frames),
packet_out->po_frame_types),
packet_out->po_enc_data_sz,
lsquic_packet_out_ecn(packet_out),
/* spin bit value is only valid for short packet headers */
lsquic_packet_out_spin_bit(packet_out),
lsquic_packet_out_kp(packet_out),
packet_out->po_path->np_path_id,
(unsigned) packet_out->po_flags,
lsquic_packet_out_square_bit(packet_out),
lsquic_packet_out_loss_bit(packet_out));
else
LCID("TX packet #%"PRIu64" %s (%s), size %hu, "
"ecn: %u, spin: %d; kp: %u, path: %hhu, flags: %u",
packet_out->po_packno, lsquic_hety2str[packet_out->po_header_type],
/* Frame types is a list of different frames types contained
* in the packet, no more. Count and order of frames is not
* printed.
*/
lsquic_frame_types_to_str(frames, sizeof(frames),
packet_out->po_frame_types),
packet_out->po_enc_data_sz,
lsquic_packet_out_ecn(packet_out),
/* spin bit value is only valid for short packet headers */
lsquic_packet_out_spin_bit(packet_out),
lsquic_packet_out_kp(packet_out),
packet_out->po_path->np_path_id,
(unsigned) packet_out->po_flags);
}
void
lsquic_ev_log_packet_not_sent (const lsquic_cid_t *cid,
const struct lsquic_packet_out *packet_out)
{
char frames[lsquic_frame_types_str_sz];
LCID("unsent packet #%"PRIu64" %s, size %hu",
packet_out->po_packno,
/* Frame types is a list of different frames types contained in
* the packet, no more. Count and order of frames is not printed.
*/
lsquic_frame_types_to_str(frames, sizeof(frames),
packet_out->po_frame_types),
packet_out->po_enc_data_sz);
}
void
lsquic_ev_log_http_headers_in (const lsquic_cid_t *cid, int is_server,
const struct uncompressed_headers *uh)
{
const struct http1x_headers *h1h;
const char *cr, *p;
if (uh->uh_flags & UH_PP)
LCID("read push promise; stream %"PRIu64", promised stream %"PRIu64,
uh->uh_stream_id, uh->uh_oth_stream_id);
else
LCID("read %s headers; stream: %"PRIu64", depends on stream: %"PRIu64
", weight: %hu, exclusive: %d, fin: %d",
is_server ? "request" : "response",
uh->uh_stream_id, uh->uh_oth_stream_id, uh->uh_weight,
(int) uh->uh_exclusive, !!(uh->uh_flags & UH_FIN));
if (uh->uh_flags & UH_H1H)
{
h1h = uh->uh_hset;
for (p = h1h->h1h_buf; p < h1h->h1h_buf + h1h->h1h_size; p = cr + 2)
{
cr = strchr(p, '\r');
if (cr && cr > p)
LCID(" %.*s", (int) (cr - p), p);
else
break;
}
}
}
void
lsquic_ev_log_action_stream_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *buf, size_t bufsz,
const char *what)
{
struct stream_frame frame;
int len;
len = pf->pf_parse_stream_frame(buf, bufsz, &frame);
if (len > 0)
LCID("%s STREAM frame: stream %"PRIu64", offset: %"PRIu64
", size: %"PRIu16", fin: %d", what, frame.stream_id,
frame.data_frame.df_offset, frame.data_frame.df_size,
frame.data_frame.df_fin);
else
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse STREAM frame");
}
void
lsquic_ev_log_generated_crypto_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *buf, size_t bufsz)
{
struct stream_frame frame;
int len;
len = pf->pf_parse_crypto_frame(buf, bufsz, &frame);
if (len > 0)
LCID("generated CRYPTO frame: offset: %"PRIu64", size: %"PRIu16,
frame.data_frame.df_offset, frame.data_frame.df_size);
else
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse CRYPTO frame");
}
void
lsquic_ev_log_generated_ack_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *ack_buf,
size_t ack_buf_sz)
{
struct ack_info acki;
int len;
char buf[MAX_ACKI_STR_SZ];
len = pf->pf_parse_ack_frame(ack_buf, ack_buf_sz, &acki,
TP_DEF_ACK_DELAY_EXP);
if (len < 0)
{
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse ACK frame");
return;
}
lsquic_acki2str(&acki, buf, sizeof(buf));
LCID("generated ACK frame: %s", buf);
}
void
lsquic_ev_log_generated_new_token_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *frame_buf,
size_t frame_buf_sz)
{
const unsigned char *token;
size_t sz;
char *buf;
int len;
len = pf->pf_parse_new_token_frame(frame_buf, frame_buf_sz, &token, &sz);
if (len < 0)
{
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse NEW_TOKEN frame");
return;
}
buf = malloc(sz * 2 + 1);
if (buf)
{
lsquic_hexstr(token, sz, buf, sz * 2 + 1);
LCID("generated NEW_TOKEN frame: %s", buf);
free(buf);
}
}
void
lsquic_ev_log_generated_path_chal_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *frame_buf,
size_t frame_buf_sz)
{
uint64_t chal;
int len;
char hexbuf[sizeof(chal) * 2 + 1];
len = pf->pf_parse_path_chal_frame(frame_buf, frame_buf_sz, &chal);
if (len > 0)
LCID("generated PATH_CHALLENGE(%s) frame",
HEXSTR((unsigned char *) &chal, sizeof(chal), hexbuf));
else
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse PATH_CHALLENGE frame");
}
void
lsquic_ev_log_generated_path_resp_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *frame_buf,
size_t frame_buf_sz)
{
uint64_t resp;
int len;
char hexbuf[sizeof(resp) * 2 + 1];
len = pf->pf_parse_path_resp_frame(frame_buf, frame_buf_sz, &resp);
if (len > 0)
LCID("generated PATH_RESPONSE(%s) frame",
HEXSTR((unsigned char *) &resp, sizeof(resp), hexbuf));
else
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse PATH_RESPONSE frame");
}
void
lsquic_ev_log_generated_new_connection_id_frame (const lsquic_cid_t *cid,
const struct parse_funcs *pf, const unsigned char *frame_buf,
size_t frame_buf_sz)
{
const unsigned char *token;
lsquic_cid_t new_cid;
uint64_t seqno, retire_prior_to;
int len;
char token_buf[IQUIC_SRESET_TOKEN_SZ * 2 + 1];
char cid_buf[MAX_CID_LEN * 2 + 1];
len = pf->pf_parse_new_conn_id(frame_buf, frame_buf_sz, &seqno,
&retire_prior_to, &new_cid, &token);
if (len < 0)
{
LSQ_LOG2(LSQ_LOG_WARN, "cannot parse NEW_CONNECTION_ID frame");
return;
}
lsquic_hexstr(new_cid.idbuf, new_cid.len, cid_buf, sizeof(cid_buf));
lsquic_hexstr(token, IQUIC_SRESET_TOKEN_SZ, token_buf, sizeof(token_buf));
LCID("generated NEW_CONNECTION_ID frame: seqno: %"PRIu64"; retire prior "
"to: %"PRIu64"; cid: %s; token: %s", seqno, retire_prior_to,
cid_buf, token_buf);
}
void
lsquic_ev_log_generated_stop_waiting_frame (const lsquic_cid_t *cid,
lsquic_packno_t lunack)
{
LCID("generated STOP_WAITING frame; least unacked: %"PRIu64, lunack);
}
void
lsquic_ev_log_generated_stop_sending_frame (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id, uint16_t error_code)
{
LCID("generated STOP_SENDING frame; stream ID: %"PRIu64"; error code: "
"%"PRIu16, stream_id, error_code);
}
void
lsquic_ev_log_generated_http_headers (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id,
int is_server, const struct http_prio_frame *prio_frame,
const struct lsquic_http_headers *headers)
{
lsquic_stream_id_t dep_stream_id;
int exclusive, i;
unsigned short weight;
if (is_server)
LCID("generated HTTP response HEADERS for stream %"PRIu64, stream_id);
else
{
memcpy(&dep_stream_id, prio_frame->hpf_stream_id, 4);
dep_stream_id = htonl(dep_stream_id);
exclusive = dep_stream_id >> 31;
dep_stream_id &= ~(1 << 31);
weight = prio_frame->hpf_weight + 1;
LCID("generated HTTP request HEADERS for stream %"PRIu64
", dep stream: %"PRIu64", weight: %hu, exclusive: %d", stream_id,
dep_stream_id, weight, exclusive);
}
for (i = 0; i < headers->count; ++i)
if (headers->headers[i].buf)
LCID(" %.*s: %.*s",
(int) headers->headers[i].name_len,
lsxpack_header_get_name(&headers->headers[i]),
(int) headers->headers[i].val_len,
lsxpack_header_get_value(&headers->headers[i]));
}
void
lsquic_ev_log_generated_http_push_promise (const lsquic_cid_t *cid,
lsquic_stream_id_t stream_id, lsquic_stream_id_t promised_stream_id,
const struct lsquic_http_headers *headers)
{
int i;
LCID("generated HTTP PUSH_PROMISE for stream %"PRIu64"; promised stream %"
PRIu64, stream_id, promised_stream_id);
for (i = 0; i < headers->count; ++i)
if (headers->headers[i].buf)
LCID(" %.*s: %.*s",
(int) headers->headers[i].name_len,
lsxpack_header_get_name(&headers->headers[i]),
(int) headers->headers[i].val_len,
lsxpack_header_get_value(&headers->headers[i]));
}
void
lsquic_ev_log_create_connection (const lsquic_cid_t *cid,
const struct sockaddr *local_sa,
const struct sockaddr *peer_sa)
{
LCID("connection created");
}
void
lsquic_ev_log_hsk_completed (const lsquic_cid_t *cid)
{
LCID("handshake completed");
}
void
lsquic_ev_log_sess_resume (const lsquic_cid_t *cid)
{
LCID("sess_resume successful");
}
void
lsquic_ev_log_check_certs (const lsquic_cid_t *cid, const lsquic_str_t **certs,
size_t count)
{
LCID("check certs");
}
void
lsquic_ev_log_cert_chain (const lsquic_cid_t *cid, struct stack_st_X509 *chain)
{
X509_NAME *name;
X509 *cert;
unsigned i;
char buf[0x100];
for (i = 0; i < sk_X509_num(chain); ++i)
{
cert = sk_X509_value(chain, i);
name = X509_get_subject_name(cert);
LCID("cert #%u: name: %s", i,
X509_NAME_oneline(name, buf, sizeof(buf)));
}
}
void
lsquic_ev_log_version_negotiation (const lsquic_cid_t *cid,
const char *action, const char *ver)
{
LCID("version negotiation: %s version %s", action, ver);
}