compiles in debug/release. tests pass (in debug config at least)

This commit is contained in:
Amol Deshpande 2018-03-12 15:25:01 -07:00
parent 0e7c6aad9e
commit 461e84d874
97 changed files with 4282 additions and 875 deletions

View file

@ -10,6 +10,9 @@
#include <assert.h>
#include <stdlib.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic.h"
#include "lsquic_types.h"

View file

@ -7,6 +7,9 @@
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_buf.h"

View file

@ -7,8 +7,12 @@
#define LSQUIC_CONN_H
#include <sys/queue.h>
#ifndef WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#else
#include <ws2ipdef.h>
#endif
struct lsquic_conn;
struct lsquic_enc_session;

View file

@ -6,6 +6,11 @@
#include <zlib.h>
#include <openssl/ssl.h>
#ifndef WIN32
#else
#include <stdlib.h>
#include <vc_compat.h>
#endif
#include "lsquic_int_types.h"
#include "lsquic_crypto.h"
@ -440,7 +445,7 @@ int decompress_certs(const unsigned char *in, const unsigned char *in_end,
{
int ret;
size_t i;
uint8_t* uncompressed_data, *uncompressed_data_buf;
uint8_t* uncompressed_data = NULL, *uncompressed_data_buf = NULL;
lsquic_str_t *dict;
uint32_t uncompressed_size;
size_t count = *out_certs_count;

View file

@ -11,6 +11,9 @@
#include <openssl/hmac.h>
#include <zlib.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_crypto.h"
@ -211,7 +214,7 @@ uint128 fnv1a_128(const uint8_t * data, int len)
void fnv1a_128_s(const uint8_t * data, int len, uint8_t *md)
{
return fnv1a_128_2_s(data, len, NULL, 0, md);
fnv1a_128_2_s(data, len, NULL, 0, md);
}
@ -281,6 +284,7 @@ void lshkdf_extract(const unsigned char *ikm, int ikm_len, const unsigned char *
}
#define SHA256LEN 32
int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_len,
uint16_t c_key_len, uint8_t *c_key,
uint16_t s_key_len, uint8_t *s_key,
@ -288,7 +292,6 @@ int lshkdf_expand(const unsigned char *prk, const unsigned char *info, int info_
uint16_t s_key_iv_len, uint8_t *s_key_iv,
uint16_t sub_key_len, uint8_t *sub_key)
{
const int SHA256LEN = 32;
int L = c_key_len + s_key_len + c_key_iv_len + s_key_iv_len + sub_key_len;
int N = (L + SHA256LEN - 1) / SHA256LEN;
unsigned char *p_org;

View file

@ -8,6 +8,9 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_int_types.h"
#include "lsquic_types.h"
@ -133,10 +136,10 @@ lsquic_cubic_was_quiet (struct lsquic_cubic *cubic, lsquic_time_t now)
void
lsquic_cubic_ack (struct lsquic_cubic *cubic, lsquic_time_t now,
lsquic_cubic_ack (struct lsquic_cubic *cubic, lsquic_time_t now_time,
lsquic_time_t rtt, int app_limited, unsigned n_bytes)
{
LSQ_DEBUG("%s(cubic, %"PRIu64", %"PRIu64", %d, %u)", __func__, now, rtt,
LSQ_DEBUG("%s(cubic, %"PRIu64", %"PRIu64", %d, %u)", __func__, now_time, rtt,
app_limited, n_bytes);
if (0 == cubic->cu_min_delay || rtt < cubic->cu_min_delay)
{
@ -151,7 +154,7 @@ lsquic_cubic_ack (struct lsquic_cubic *cubic, lsquic_time_t now,
}
else if (!app_limited)
{
cubic_update(cubic, now, n_bytes);
cubic_update(cubic, now_time, n_bytes);
LSQ_DEBUG("ACK: cwnd: %lu", cubic->cu_cwnd);
}

View file

@ -9,24 +9,17 @@
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_data_in_if.h"
static const struct data_in_iface di_if_error;
static const struct data_in error_data_in = {
.di_if = &di_if_error,
.di_flags = 0,
};
struct data_in *
data_in_error_new (struct lsquic_conn_public *conn_pub)
{
return (struct data_in *) &error_data_in;
}
static void
@ -87,3 +80,12 @@ static const struct data_in_iface di_if_error = {
.di_mem_used = error_di_mem_used,
.di_switch_impl = error_di_switch_impl,
};
static const struct data_in error_data_in = {
.di_if = &di_if_error,
.di_flags = 0,
};
struct data_in *
data_in_error_new (struct lsquic_conn_public *conn_pub)
{
return (struct data_in *) &error_data_in;
}

View file

@ -53,15 +53,14 @@ struct data_block
unsigned char db_data[DB_DATA_SIZE];
};
typedef char db_set_covers_all_db_data[(N_DB_SETS * 64 >= DB_DATA_SIZE) - 1];
typedef char db_set_no_waste[(N_DB_SETS * 64 - 64 <= DB_DATA_SIZE) - 1];
typedef char db_block_is_4K[(sizeof(struct data_block) == 0x1000) - 1];
typedef char db_set_covers_all_db_data[(N_DB_SETS * 64 >= DB_DATA_SIZE) ?1: - 1];
typedef char db_set_no_waste[(N_DB_SETS * 64 - 64 <= DB_DATA_SIZE)?1: - 1];
typedef char db_block_is_4K[(sizeof(struct data_block) == 0x1000) ?1:- 1];
TAILQ_HEAD(dblock_head, data_block);
static const struct data_in_iface di_if_hash;
struct hash_data_in
@ -109,43 +108,6 @@ my_log2 /* silly name to suppress compiler warning */ (unsigned sz)
}
struct data_in *
data_in_hash_new (struct lsquic_conn_public *conn_pub, uint32_t stream_id,
uint64_t byteage)
{
struct hash_data_in *hdi;
unsigned n;
hdi = malloc(sizeof(*hdi));
if (!hdi)
return NULL;
hdi->hdi_data_in.di_if = &di_if_hash;
hdi->hdi_data_in.di_flags = 0;
hdi->hdi_conn_pub = conn_pub;
hdi->hdi_stream_id = stream_id;
hdi->hdi_fin_off = 0;
hdi->hdi_flags = 0;
hdi->hdi_last_block = NULL;
if (byteage >= DB_DATA_SIZE /* __builtin_clz is undefined if
argument is 0 */)
hdi->hdi_nbits = my_log2(byteage / DB_DATA_SIZE) + 2;
else
hdi->hdi_nbits = 3;
hdi->hdi_count = 0;
hdi->hdi_buckets = malloc(sizeof(hdi->hdi_buckets[0]) *
N_BUCKETS(hdi->hdi_nbits));
if (!hdi->hdi_buckets)
{
free(hdi);
return NULL;
}
for (n = 0; n < N_BUCKETS(hdi->hdi_nbits); ++n)
TAILQ_INIT(&hdi->hdi_buckets[n]);
return &hdi->hdi_data_in;
}
static void
@ -637,3 +599,40 @@ static const struct data_in_iface di_if_hash = {
.di_mem_used = hash_di_mem_used,
.di_switch_impl = hash_di_switch_impl,
};
struct data_in *
data_in_hash_new (struct lsquic_conn_public *conn_pub, uint32_t stream_id,
uint64_t byteage)
{
struct hash_data_in *hdi;
unsigned n;
hdi = malloc(sizeof(*hdi));
if (!hdi)
return NULL;
hdi->hdi_data_in.di_if = &di_if_hash;
hdi->hdi_data_in.di_flags = 0;
hdi->hdi_conn_pub = conn_pub;
hdi->hdi_stream_id = stream_id;
hdi->hdi_fin_off = 0;
hdi->hdi_flags = 0;
hdi->hdi_last_block = NULL;
if (byteage >= DB_DATA_SIZE /* __builtin_clz is undefined if
argument is 0 */)
hdi->hdi_nbits = my_log2(byteage / DB_DATA_SIZE) + 2;
else
hdi->hdi_nbits = 3;
hdi->hdi_count = 0;
hdi->hdi_buckets = malloc(sizeof(hdi->hdi_buckets[0]) *
N_BUCKETS(hdi->hdi_nbits));
if (!hdi->hdi_buckets)
{
free(hdi);
return NULL;
}
for (n = 0; n < N_BUCKETS(hdi->hdi_nbits); ++n)
TAILQ_INIT(&hdi->hdi_buckets[n]);
return &hdi->hdi_data_in;
}

View file

@ -116,30 +116,8 @@ struct nocopy_data_in
((unsigned char *) (data_frame) - offsetof(struct stream_frame, data_frame))
static const struct data_in_iface di_if_nocopy;
struct data_in *
data_in_nocopy_new (struct lsquic_conn_public *conn_pub, uint32_t stream_id)
{
struct nocopy_data_in *ncdi;
ncdi = malloc(sizeof(*ncdi));
if (!ncdi)
return NULL;
TAILQ_INIT(&ncdi->ncdi_frames_in);
ncdi->ncdi_data_in.di_if = &di_if_nocopy;
ncdi->ncdi_data_in.di_flags = 0;
ncdi->ncdi_conn_pub = conn_pub;
ncdi->ncdi_stream_id = stream_id;
ncdi->ncdi_byteage = 0;
ncdi->ncdi_n_frames = 0;
ncdi->ncdi_n_holes = 0;
ncdi->ncdi_cons_far = 0;
return &ncdi->ncdi_data_in;
}
static void
nocopy_di_destroy (struct data_in *data_in)
@ -444,3 +422,24 @@ static const struct data_in_iface di_if_nocopy = {
.di_mem_used = nocopy_di_mem_used,
.di_switch_impl = nocopy_di_switch_impl,
};
struct data_in *
data_in_nocopy_new (struct lsquic_conn_public *conn_pub, uint32_t stream_id)
{
struct nocopy_data_in *ncdi;
ncdi = malloc(sizeof(*ncdi));
if (!ncdi)
return NULL;
TAILQ_INIT(&ncdi->ncdi_frames_in);
ncdi->ncdi_data_in.di_if = &di_if_nocopy;
ncdi->ncdi_data_in.di_flags = 0;
ncdi->ncdi_conn_pub = conn_pub;
ncdi->ncdi_stream_id = stream_id;
ncdi->ncdi_byteage = 0;
ncdi->ncdi_n_frames = 0;
ncdi->ncdi_n_holes = 0;
ncdi->ncdi_cons_far = 0;
return &ncdi->ncdi_data_in;
}

View file

@ -1,5 +1,9 @@
/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */
#include <time.h>
#ifdef WIN32
#include <vc_compat.h>
#define localtime_r(a,b) localtime_s(b,a)
#endif
#include "lsquic_eng_hist.h"

View file

@ -11,14 +11,16 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <sys/time.h>
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#endif
@ -164,9 +166,11 @@ struct lsquic_engine
union {
struct {
/* This iterator does not have any state: it uses `conns_in' */
int ignore;
} conn_in;
struct {
/* This iterator does not have any state: it uses `conns_pend_rw' */
int ignore;
} rw_pend;
struct {
/* Iterator state to process connections in Advisory Tick Time
@ -176,6 +180,7 @@ struct lsquic_engine
} attq;
struct {
/* Iterator state to process all connections */
int ignore;
} all;
struct {
lsquic_conn_t *conn;

View file

@ -1,9 +1,14 @@
/* Copyright (c) 2017 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 "lsquic.h"
#include "lsquic_types.h"
@ -25,7 +30,7 @@
/* Messages that do not include connection ID go above this point */
#define LSQUIC_LOG_CONN_ID cid
#define LCID(a...) LSQ_LOG2(LSQ_LOG_DEBUG, a) /* LCID: log with 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 */
/* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

View file

@ -19,171 +19,171 @@ struct uncompressed_headers;
/* Log a generic event not tied to any particular connection */
#define EV_LOG_GENERIC_EVENT(args...) do { \
#define EV_LOG_GENERIC_EVENT(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_logger_log1(LSQ_LOG_DEBUG, LSQLM_EVENT, args); \
lsquic_logger_log1(LSQ_LOG_DEBUG, LSQLM_EVENT, __VA_ARGS__); \
} while (0)
/* Log a generic event associated with connection `cid' */
#define EV_LOG_CONN_EVENT(cid, args...) do { \
#define EV_LOG_CONN_EVENT(cid, ...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_logger_log2(LSQ_LOG_DEBUG, LSQLM_EVENT, cid, args); \
lsquic_logger_log2(LSQ_LOG_DEBUG, LSQLM_EVENT, cid, __VA_ARGS__); \
} while (0)
void
lsquic_ev_log_packet_in (lsquic_cid_t, const struct lsquic_packet_in *);
#define EV_LOG_PACKET_IN(args...) do { \
#define EV_LOG_PACKET_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_packet_in(args); \
lsquic_ev_log_packet_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_ack_frame_in (lsquic_cid_t, const struct ack_info *);
#define EV_LOG_ACK_FRAME_IN(args...) do { \
#define EV_LOG_ACK_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_ack_frame_in(args); \
lsquic_ev_log_ack_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_stream_frame_in (lsquic_cid_t, const struct stream_frame *);
#define EV_LOG_STREAM_FRAME_IN(args...) do { \
#define EV_LOG_STREAM_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_stream_frame_in(args); \
lsquic_ev_log_stream_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_window_update_frame_in (lsquic_cid_t, uint32_t stream_id,
uint64_t offset);
#define EV_LOG_WINDOW_UPDATE_FRAME_IN(args...) do { \
#define EV_LOG_WINDOW_UPDATE_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_window_update_frame_in(args); \
lsquic_ev_log_window_update_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_blocked_frame_in (lsquic_cid_t, uint32_t stream_id);
#define EV_LOG_BLOCKED_FRAME_IN(args...) do { \
#define EV_LOG_BLOCKED_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_blocked_frame_in(args); \
lsquic_ev_log_blocked_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_stop_waiting_frame_in (lsquic_cid_t, lsquic_packno_t);
#define EV_LOG_STOP_WAITING_FRAME_IN(args...) do { \
#define EV_LOG_STOP_WAITING_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_stop_waiting_frame_in(args); \
lsquic_ev_log_stop_waiting_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_connection_close_frame_in (lsquic_cid_t, uint32_t error_code,
int reason_len, const char *reason);
#define EV_LOG_CONNECTION_CLOSE_FRAME_IN(args...) do { \
#define EV_LOG_CONNECTION_CLOSE_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_connection_close_frame_in(args); \
lsquic_ev_log_connection_close_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_goaway_frame_in (lsquic_cid_t, uint32_t error_code,
uint32_t stream_id, int reason_len, const char *reason);
#define EV_LOG_GOAWAY_FRAME_IN(args...) do { \
#define EV_LOG_GOAWAY_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_goaway_frame_in(args); \
lsquic_ev_log_goaway_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_rst_stream_frame_in (lsquic_cid_t, uint32_t stream_id,
uint64_t offset, uint32_t error_code);
#define EV_LOG_RST_STREAM_FRAME_IN(args...) do { \
#define EV_LOG_RST_STREAM_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_rst_stream_frame_in(args); \
lsquic_ev_log_rst_stream_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_padding_frame_in (lsquic_cid_t, size_t len);
#define EV_LOG_PADDING_FRAME_IN(args...) do { \
#define EV_LOG_PADDING_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_padding_frame_in(args); \
lsquic_ev_log_padding_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_ping_frame_in (lsquic_cid_t);
#define EV_LOG_PING_FRAME_IN(args...) do { \
#define EV_LOG_PING_FRAME_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_ping_frame_in(args); \
lsquic_ev_log_ping_frame_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_packet_created (lsquic_cid_t, const struct lsquic_packet_out *);
#define EV_LOG_PACKET_CREATED(args...) do { \
#define EV_LOG_PACKET_CREATED(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_packet_created(args); \
lsquic_ev_log_packet_created(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_packet_sent (lsquic_cid_t, const struct lsquic_packet_out *);
#define EV_LOG_PACKET_SENT(args...) do { \
#define EV_LOG_PACKET_SENT(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_packet_sent(args); \
lsquic_ev_log_packet_sent(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_packet_not_sent (lsquic_cid_t, const struct lsquic_packet_out *);
#define EV_LOG_PACKET_NOT_SENT(args...) do { \
#define EV_LOG_PACKET_NOT_SENT(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_packet_not_sent(args); \
lsquic_ev_log_packet_not_sent(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_http_headers_in (lsquic_cid_t, int is_server,
const struct uncompressed_headers *);
#define EV_LOG_HTTP_HEADERS_IN(args...) do { \
#define EV_LOG_HTTP_HEADERS_IN(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_http_headers_in(args); \
lsquic_ev_log_http_headers_in(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_action_stream_frame (lsquic_cid_t, const struct parse_funcs *pf,
const unsigned char *, size_t len, const char *action);
#define EV_LOG_GENERATED_STREAM_FRAME(args...) do { \
#define EV_LOG_GENERATED_STREAM_FRAME(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_action_stream_frame(args, "generated"); \
lsquic_ev_log_action_stream_frame(__VA_ARGS__, "generated"); \
} while (0)
#define EV_LOG_UPDATED_STREAM_FRAME(args...) do { \
#define EV_LOG_UPDATED_STREAM_FRAME(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_action_stream_frame(args, "updated"); \
lsquic_ev_log_action_stream_frame(__VA_ARGS__, "updated"); \
} while (0)
void
lsquic_ev_log_generated_ack_frame (lsquic_cid_t, const struct parse_funcs *,
const unsigned char *, size_t len);
#define EV_LOG_GENERATED_ACK_FRAME(args...) do { \
#define EV_LOG_GENERATED_ACK_FRAME(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_generated_ack_frame(args); \
lsquic_ev_log_generated_ack_frame(__VA_ARGS__); \
} while (0)
void
lsquic_ev_log_generated_stop_waiting_frame (lsquic_cid_t, lsquic_packno_t);
#define EV_LOG_GENERATED_STOP_WAITING_FRAME(args...) do { \
#define EV_LOG_GENERATED_STOP_WAITING_FRAME(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_generated_stop_waiting_frame(args); \
lsquic_ev_log_generated_stop_waiting_frame(__VA_ARGS__); \
} while (0)
void
@ -192,9 +192,9 @@ lsquic_ev_log_generated_http_headers (lsquic_cid_t, uint32_t stream_id,
const struct lsquic_http_headers *);
#define EV_LOG_GENERATED_HTTP_HEADERS(args...) do { \
#define EV_LOG_GENERATED_HTTP_HEADERS(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_generated_http_headers(args); \
lsquic_ev_log_generated_http_headers(__VA_ARGS__); \
} while (0)
void
@ -203,9 +203,9 @@ lsquic_ev_log_generated_http_push_promise (lsquic_cid_t, uint32_t stream_id,
const struct lsquic_http_headers *headers,
const struct lsquic_http_headers *extra_headers);
#define EV_LOG_GENERATED_HTTP_PUSH_PROMISE(args...) do { \
#define EV_LOG_GENERATED_HTTP_PUSH_PROMISE(...) do { \
if (LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT)) \
lsquic_ev_log_generated_http_push_promise(args); \
lsquic_ev_log_generated_http_push_promise(__VA_ARGS__); \
} while (0)
#endif

View file

@ -3,7 +3,9 @@
* lsquic_frame_reader.c -- Read HTTP frames from stream
*/
#ifndef WIN32
#include <arpa/inet.h>
#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@ -698,11 +700,12 @@ code_str_to_reason (const char *code_str, int code_len)
};
long code;
char code_buf[ code_len + 1 ];
char * code_buf = malloc(code_len + 1 );
strncpy(code_buf, code_str, code_len);
code_buf[code_len] = '\0';
code = strtol(code_buf, NULL, 10) - 100;
free(code_buf);
if (code > 0 && code < (long) (sizeof(http_reason_phrases) /
sizeof(http_reason_phrases[0])))
return http_reason_phrases[code];

View file

@ -8,7 +8,9 @@
* the whole frame.
*/
#ifndef WIN32
#include <arpa/inet.h>
#endif
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
@ -54,7 +56,7 @@ struct frame_buf
/* Make sure that frab_buf is at least five bytes long, otherwise a frame
* won't fit into two adjacent frabs.
*/
typedef char three_byte_frab_buf[(sizeof(((struct frame_buf *)0)->frab_buf) >= 5) - 1];
typedef char three_byte_frab_buf[(sizeof(((struct frame_buf *)0)->frab_buf) >= 5) ?1 : - 1];
TAILQ_HEAD(frame_buf_head, frame_buf);

View file

@ -6,13 +6,15 @@
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/time.h>
#endif
#include <sys/queue.h>
#include "lsquic_types.h"
#include "lsquic.h"
@ -208,22 +210,22 @@ struct full_conn
#define MAX_ERRMSG 256
#define SET_ERRMSG(conn, errmsg...) do { \
#define SET_ERRMSG(conn, ...) do { \
if (!(conn)->fc_errmsg) \
(conn)->fc_errmsg = malloc(MAX_ERRMSG); \
if ((conn)->fc_errmsg) \
snprintf((conn)->fc_errmsg, MAX_ERRMSG, errmsg); \
snprintf((conn)->fc_errmsg, MAX_ERRMSG, __VA_ARGS__); \
} while (0)
#define ABORT_WITH_FLAG(conn, flag, errmsg...) do { \
SET_ERRMSG(conn, errmsg); \
#define ABORT_WITH_FLAG(conn, flag, ...) do { \
SET_ERRMSG(conn, __VA_ARGS__); \
(conn)->fc_flags |= flag; \
LSQ_ERROR("Abort connection: " errmsg); \
LSQ_ERROR("Abort connection: " __VA_ARGS__); \
} while (0)
#define ABORT_ERROR(errmsg...) ABORT_WITH_FLAG(conn, FC_ERROR, errmsg)
#define ABORT_ERROR(...) ABORT_WITH_FLAG(conn, FC_ERROR, __VA_ARGS__)
#define ABORT_TIMEOUT(errmsg...) ABORT_WITH_FLAG(conn, FC_TIMED_OUT, errmsg)
#define ABORT_TIMEOUT(...) ABORT_WITH_FLAG(conn, FC_TIMED_OUT, __VA_ARGS__)
static void
idle_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now);
@ -249,7 +251,6 @@ write_is_possible (struct full_conn *);
static int
dispatch_stream_read_events (struct full_conn *, struct lsquic_stream *);
static const struct headers_stream_callbacks headers_callbacks;
#if KEEP_CLOSED_STREAM_HISTORY
@ -512,174 +513,9 @@ apply_peer_settings (struct full_conn *conn)
}
static const struct conn_iface full_conn_iface;
static struct full_conn *
new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub,
const struct lsquic_stream_if *stream_if,
void *stream_if_ctx, unsigned flags,
unsigned short max_packet_size)
{
struct full_conn *conn;
lsquic_stream_t *headers_stream;
int saved_errno;
assert(0 == (flags & ~(FC_SERVER|FC_HTTP)));
conn = calloc(1, sizeof(*conn));
if (!conn)
return NULL;
headers_stream = NULL;
conn->fc_conn.cn_cid = cid;
conn->fc_conn.cn_pack_size = max_packet_size;
conn->fc_flags = flags;
conn->fc_enpub = enpub;
conn->fc_pub.enpub = enpub;
conn->fc_pub.mm = &enpub->enp_mm;
conn->fc_pub.lconn = &conn->fc_conn;
conn->fc_pub.send_ctl = &conn->fc_send_ctl;
conn->fc_pub.packet_out_malo =
lsquic_malo_create(sizeof(struct lsquic_packet_out));
conn->fc_stream_ifs[STREAM_IF_STD].stream_if = stream_if;
conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = stream_if_ctx;
conn->fc_settings = &enpub->enp_settings;
/* Calculate maximum number of incoming streams using the same mechanism
* and parameters as found in Chrome:
*/
conn->fc_cfg.max_streams_in =
(unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f);
if (conn->fc_cfg.max_streams_in <
enpub->enp_settings.es_max_streams_in + 10)
conn->fc_cfg.max_streams_in =
enpub->enp_settings.es_max_streams_in + 10;
/* `max_streams_out' gets reset when handshake is complete and we
* learn of peer settings. 100 seems like a sane default value
* because it is what other implementations use. In server mode,
* we do not open any streams until the handshake is complete; in
* client mode, we are limited to 98 outgoing requests alongside
* handshake and headers streams.
*/
conn->fc_cfg.max_streams_out = 100;
TAILQ_INIT(&conn->fc_pub.sending_streams);
TAILQ_INIT(&conn->fc_pub.read_streams);
TAILQ_INIT(&conn->fc_pub.write_streams);
TAILQ_INIT(&conn->fc_pub.service_streams);
STAILQ_INIT(&conn->fc_stream_ids_to_reset);
lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW);
lsquic_alarmset_init(&conn->fc_alset, cid);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK, ack_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn);
lsquic_set32_init(&conn->fc_closed_stream_ids[0]);
lsquic_set32_init(&conn->fc_closed_stream_ids[1]);
lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw);
lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub,
&conn->fc_ver_neg, &conn->fc_pub, conn->fc_conn.cn_pack_size);
conn->fc_pub.all_streams = lsquic_hash_create();
if (!conn->fc_pub.all_streams)
goto cleanup_on_error;
lsquic_rechist_init(&conn->fc_rechist, cid);
if (conn->fc_flags & FC_HTTP)
{
conn->fc_pub.hs = lsquic_headers_stream_new(
!!(conn->fc_flags & FC_SERVER), conn->fc_pub.mm, conn->fc_settings,
&headers_callbacks, conn);
if (!conn->fc_pub.hs)
goto cleanup_on_error;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = lsquic_headers_stream_if;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.hs;
headers_stream = new_stream(conn, LSQUIC_STREAM_HEADERS,
SCF_CALL_ON_NEW);
if (!headers_stream)
goto cleanup_on_error;
}
else
{
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = stream_if;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = stream_if_ctx;
}
if (conn->fc_settings->es_support_push)
conn->fc_flags |= FC_SUPPORT_PUSH;
conn->fc_conn.cn_if = &full_conn_iface;
return conn;
cleanup_on_error:
saved_errno = errno;
if (conn->fc_pub.all_streams)
lsquic_hash_destroy(conn->fc_pub.all_streams);
lsquic_rechist_cleanup(&conn->fc_rechist);
if (conn->fc_flags & FC_HTTP)
{
if (conn->fc_pub.hs)
lsquic_headers_stream_destroy(conn->fc_pub.hs);
if (headers_stream)
lsquic_stream_destroy(headers_stream);
}
memset(conn, 0, sizeof(*conn));
free(conn);
errno = saved_errno;
return NULL;
}
struct lsquic_conn *
full_conn_client_new (struct lsquic_engine_public *enpub,
const struct lsquic_stream_if *stream_if,
void *stream_if_ctx, unsigned flags,
const char *hostname, unsigned short max_packet_size)
{
struct full_conn *conn;
enum lsquic_version version;
lsquic_cid_t cid;
const struct enc_session_funcs *esf;
version = highest_bit_set(enpub->enp_settings.es_versions);
esf = select_esf_by_ver(version);
cid = esf->esf_generate_cid();
conn = new_conn_common(cid, enpub, stream_if, stream_if_ctx, flags,
max_packet_size);
if (!conn)
return NULL;
conn->fc_conn.cn_esf = esf;
conn->fc_conn.cn_enc_session =
conn->fc_conn.cn_esf->esf_create_client(hostname, cid, conn->fc_enpub);
if (!conn->fc_conn.cn_enc_session)
{
LSQ_WARN("could not create enc session: %s", strerror(errno));
conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
return NULL;
}
if (conn->fc_flags & FC_HTTP)
conn->fc_last_stream_id = LSQUIC_STREAM_HEADERS; /* Client goes 5, 7, 9.... */
else
conn->fc_last_stream_id = LSQUIC_STREAM_HANDSHAKE;
conn->fc_hsk_ctx.client.lconn = &conn->fc_conn;
conn->fc_hsk_ctx.client.mm = &enpub->enp_mm;
conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg;
conn->fc_stream_ifs[STREAM_IF_HSK]
.stream_if = &lsquic_client_hsk_stream_if;
conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client;
init_ver_neg(conn, conn->fc_settings->es_versions);
conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver);
if (conn->fc_settings->es_handshake_to)
lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE,
lsquic_time_now() + conn->fc_settings->es_handshake_to);
if (!new_stream(conn, LSQUIC_STREAM_HANDSHAKE, SCF_CALL_ON_NEW))
{
LSQ_WARN("could not create handshake stream: %s", strerror(errno));
conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
return NULL;
}
conn->fc_flags |= FC_CREATED_OK;
LSQ_INFO("Created new client connection");
EV_LOG_CONN_EVENT(cid, "created full connection");
return &conn->fc_conn;
}
void
@ -982,7 +818,7 @@ lsquic_conn_get_engine (lsquic_conn_t *lconn)
}
static unsigned
static ssize_t
count_zero_bytes (const unsigned char *p, size_t len)
{
const unsigned char *const end = p + len;
@ -997,11 +833,11 @@ process_padding_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
const unsigned char *p, size_t len)
{
if (conn->fc_conn.cn_version >= LSQVER_038)
return count_zero_bytes(p, len);
return (unsigned)count_zero_bytes(p, len);
if (lsquic_is_zero(p, len))
{
EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len);
return len;
return (unsigned )len;
}
else
return 0;
@ -3154,3 +2990,167 @@ static const struct conn_iface full_conn_iface = {
.ci_tick = full_conn_ci_tick,
.ci_user_wants_read = full_conn_ci_user_wants_read,
};
static struct full_conn *
new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub,
const struct lsquic_stream_if *stream_if,
void *stream_if_ctx, unsigned flags,
unsigned short max_packet_size)
{
struct full_conn *conn;
lsquic_stream_t *headers_stream;
int saved_errno;
assert(0 == (flags & ~(FC_SERVER|FC_HTTP)));
conn = calloc(1, sizeof(*conn));
if (!conn)
return NULL;
headers_stream = NULL;
conn->fc_conn.cn_cid = cid;
conn->fc_conn.cn_pack_size = max_packet_size;
conn->fc_flags = flags;
conn->fc_enpub = enpub;
conn->fc_pub.enpub = enpub;
conn->fc_pub.mm = &enpub->enp_mm;
conn->fc_pub.lconn = &conn->fc_conn;
conn->fc_pub.send_ctl = &conn->fc_send_ctl;
conn->fc_pub.packet_out_malo =
lsquic_malo_create(sizeof(struct lsquic_packet_out));
conn->fc_stream_ifs[STREAM_IF_STD].stream_if = stream_if;
conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = stream_if_ctx;
conn->fc_settings = &enpub->enp_settings;
/* Calculate maximum number of incoming streams using the same mechanism
* and parameters as found in Chrome:
*/
conn->fc_cfg.max_streams_in =
(unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f);
if (conn->fc_cfg.max_streams_in <
enpub->enp_settings.es_max_streams_in + 10)
conn->fc_cfg.max_streams_in =
enpub->enp_settings.es_max_streams_in + 10;
/* `max_streams_out' gets reset when handshake is complete and we
* learn of peer settings. 100 seems like a sane default value
* because it is what other implementations use. In server mode,
* we do not open any streams until the handshake is complete; in
* client mode, we are limited to 98 outgoing requests alongside
* handshake and headers streams.
*/
conn->fc_cfg.max_streams_out = 100;
TAILQ_INIT(&conn->fc_pub.sending_streams);
TAILQ_INIT(&conn->fc_pub.read_streams);
TAILQ_INIT(&conn->fc_pub.write_streams);
TAILQ_INIT(&conn->fc_pub.service_streams);
STAILQ_INIT(&conn->fc_stream_ids_to_reset);
lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW);
lsquic_alarmset_init(&conn->fc_alset, cid);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK, ack_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn);
lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn);
lsquic_set32_init(&conn->fc_closed_stream_ids[0]);
lsquic_set32_init(&conn->fc_closed_stream_ids[1]);
lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw);
lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub,
&conn->fc_ver_neg, &conn->fc_pub, conn->fc_conn.cn_pack_size);
conn->fc_pub.all_streams = lsquic_hash_create();
if (!conn->fc_pub.all_streams)
goto cleanup_on_error;
lsquic_rechist_init(&conn->fc_rechist, cid);
if (conn->fc_flags & FC_HTTP)
{
conn->fc_pub.hs = lsquic_headers_stream_new(
!!(conn->fc_flags & FC_SERVER), conn->fc_pub.mm, conn->fc_settings,
&headers_callbacks, conn);
if (!conn->fc_pub.hs)
goto cleanup_on_error;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = lsquic_headers_stream_if;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.hs;
headers_stream = new_stream(conn, LSQUIC_STREAM_HEADERS,
SCF_CALL_ON_NEW);
if (!headers_stream)
goto cleanup_on_error;
}
else
{
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if = stream_if;
conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = stream_if_ctx;
}
if (conn->fc_settings->es_support_push)
conn->fc_flags |= FC_SUPPORT_PUSH;
conn->fc_conn.cn_if = &full_conn_iface;
return conn;
cleanup_on_error:
saved_errno = errno;
if (conn->fc_pub.all_streams)
lsquic_hash_destroy(conn->fc_pub.all_streams);
lsquic_rechist_cleanup(&conn->fc_rechist);
if (conn->fc_flags & FC_HTTP)
{
if (conn->fc_pub.hs)
lsquic_headers_stream_destroy(conn->fc_pub.hs);
if (headers_stream)
lsquic_stream_destroy(headers_stream);
}
memset(conn, 0, sizeof(*conn));
free(conn);
errno = saved_errno;
return NULL;
}
struct lsquic_conn *
full_conn_client_new (struct lsquic_engine_public *enpub,
const struct lsquic_stream_if *stream_if,
void *stream_if_ctx, unsigned flags,
const char *hostname, unsigned short max_packet_size)
{
struct full_conn *conn;
enum lsquic_version version;
lsquic_cid_t cid;
const struct enc_session_funcs *esf;
version = highest_bit_set(enpub->enp_settings.es_versions);
esf = select_esf_by_ver(version);
cid = esf->esf_generate_cid();
conn = new_conn_common(cid, enpub, stream_if, stream_if_ctx, flags,
max_packet_size);
if (!conn)
return NULL;
conn->fc_conn.cn_esf = esf;
conn->fc_conn.cn_enc_session =
conn->fc_conn.cn_esf->esf_create_client(hostname, cid, conn->fc_enpub);
if (!conn->fc_conn.cn_enc_session)
{
LSQ_WARN("could not create enc session: %s", strerror(errno));
conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
return NULL;
}
if (conn->fc_flags & FC_HTTP)
conn->fc_last_stream_id = LSQUIC_STREAM_HEADERS; /* Client goes 5, 7, 9.... */
else
conn->fc_last_stream_id = LSQUIC_STREAM_HANDSHAKE;
conn->fc_hsk_ctx.client.lconn = &conn->fc_conn;
conn->fc_hsk_ctx.client.mm = &enpub->enp_mm;
conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg;
conn->fc_stream_ifs[STREAM_IF_HSK]
.stream_if = &lsquic_client_hsk_stream_if;
conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client;
init_ver_neg(conn, conn->fc_settings->es_versions);
conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver);
if (conn->fc_settings->es_handshake_to)
lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE,
lsquic_time_now() + conn->fc_settings->es_handshake_to);
if (!new_stream(conn, LSQUIC_STREAM_HANDSHAKE, SCF_CALL_ON_NEW))
{
LSQ_WARN("could not create handshake stream: %s", strerror(errno));
conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
return NULL;
}
conn->fc_flags |= FC_CREATED_OK;
LSQ_INFO("Created new client connection");
EV_LOG_CONN_EVENT(cid, "created full connection");
return &conn->fc_conn;
}

View file

@ -5,7 +5,9 @@
#include <time.h>
#include <string.h>
#include <sys/queue.h>
#ifndef WIN32
#include <sys/socket.h>
#endif
#include <openssl/ssl.h>
#include <openssl/crypto.h>
@ -933,7 +935,7 @@ lsquic_enc_session_gen_chlo (lsquic_enc_session_t *enc_session,
unsigned char pub_key[32];
size_t ua_len;
uint32_t opts[1]; /* Only NSTP is supported for now */
unsigned n_opts, msg_len, n_tags, pad_size;
unsigned n_opts, msg_len, n_tags, pad_size = 0;
struct message_writer mw;
/* Before we do anything else, sanity check: */

View file

@ -8,6 +8,9 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_malo.h"
#include "lsquic_hash.h"

View file

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <vc_compat.h>
#include "lsquic_types.h"
#include "lsquic_frame_common.h"
@ -28,7 +29,6 @@
#define LSQUIC_LOG_CONN_ID lsquic_conn_id(lsquic_stream_conn(hs->hs_stream))
#include "lsquic_logger.h"
static const struct frame_reader_callbacks frame_callbacks;
struct headers_stream
{
@ -48,6 +48,7 @@ struct headers_stream
HS_HENC_INITED = (1 << 1),
} hs_flags;
};
static lsquic_stream_ctx_t * headers_on_new_stream(void *stream_if_ctx, lsquic_stream_t *stream);
int
@ -70,42 +71,6 @@ lsquic_headers_stream_send_settings (struct headers_stream *hs,
}
static lsquic_stream_ctx_t *
headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
{
struct headers_stream *hs = stream_if_ctx;
lsquic_hdec_init(&hs->hs_hdec);
if (0 != lsquic_henc_init(&hs->hs_henc))
{
LSQ_WARN("could not initialize HPACK encoder: %s", strerror(errno));
return NULL;
}
hs->hs_flags |= HS_HENC_INITED;
hs->hs_stream = stream;
LSQ_DEBUG("stream created");
hs->hs_fr = lsquic_frame_reader_new((hs->hs_flags & HS_IS_SERVER) ? FRF_SERVER : 0,
MAX_HEADERS_SIZE, hs->hs_mm,
stream, lsquic_stream_read, &hs->hs_hdec,
&frame_callbacks, hs);
if (!hs->hs_fr)
{
LSQ_WARN("could not create frame reader: %s", strerror(errno));
hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);
return NULL;
}
hs->hs_fw = lsquic_frame_writer_new(hs->hs_mm, stream, 0, &hs->hs_henc,
lsquic_stream_write,
(hs->hs_flags & HS_IS_SERVER));
if (!hs->hs_fw)
{
LSQ_WARN("could not create frame writer: %s", strerror(errno));
hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);
return NULL;
}
lsquic_stream_wantread(stream, 1);
return (lsquic_stream_ctx_t *) hs;
}
static void
headers_on_read (lsquic_stream_t *stream, struct lsquic_stream_ctx *ctx)
@ -414,3 +379,39 @@ static const struct frame_reader_callbacks frame_callbacks = {
.frc_on_settings = headers_on_settings,
.frc_on_priority = headers_on_priority,
};
static lsquic_stream_ctx_t *
headers_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
{
struct headers_stream *hs = stream_if_ctx;
lsquic_hdec_init(&hs->hs_hdec);
if (0 != lsquic_henc_init(&hs->hs_henc))
{
LSQ_WARN("could not initialize HPACK encoder: %s", strerror(errno));
return NULL;
}
hs->hs_flags |= HS_HENC_INITED;
hs->hs_stream = stream;
LSQ_DEBUG("stream created");
hs->hs_fr = lsquic_frame_reader_new((hs->hs_flags & HS_IS_SERVER) ? FRF_SERVER : 0,
MAX_HEADERS_SIZE, hs->hs_mm,
stream, lsquic_stream_read, &hs->hs_hdec,
&frame_callbacks, hs);
if (!hs->hs_fr)
{
LSQ_WARN("could not create frame reader: %s", strerror(errno));
hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);
return NULL;
}
hs->hs_fw = lsquic_frame_writer_new(hs->hs_mm, stream, 0, &hs->hs_henc,
lsquic_stream_write,
(hs->hs_flags & HS_IS_SERVER));
if (!hs->hs_fw)
{
LSQ_WARN("could not create frame writer: %s", strerror(errno));
hs->hs_callbacks->hsc_on_conn_error(hs->hs_cb_ctx);
return NULL;
}
lsquic_stream_wantread(stream, 1);
return (lsquic_stream_ctx_t *) hs;
}

View file

@ -6,6 +6,9 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_arr.h"
#include "lsquic_hpack_common.h"

View file

@ -9,6 +9,9 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_hpack_common.h"
#include "lsquic_hpack_enc.h"

View file

@ -9,7 +9,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include <time.h>
#define LSQUIC_LOGGER_MODULE LSQLM_LOGGER /* Quis custodiet ipsos custodes? */
@ -122,6 +124,7 @@ lsquic_printf (const char *fmt, ...)
static void
print_timestamp (void)
{
#ifndef WIN32
struct tm tm;
struct timeval tv;
gettimeofday(&tv, NULL);
@ -143,6 +146,27 @@ print_timestamp (void)
else if (g_llts == LLTS_CHROMELIKE)
lsquic_printf("%02d%02d/%02d%02d%02d.%06d ", tm.tm_mon + 1,
tm.tm_mday,tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
#else
SYSTEMTIME tm = { 0 };
GetSystemTime(&tm);
if (g_llts == LLTS_YYYYMMDD_HHMMSSUS)
lsquic_printf("%04d-%02d-%02d %02d:%02d:%02d.%06d ",
tm.wYear + 1900, tm.wMonth + 1, tm.wDay,
tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds*1000 );
else if (g_llts == LLTS_YYYYMMDD_HHMMSSMS)
lsquic_printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ",
tm.wYear + 1900, tm.wMonth + 1, tm.wDay,
tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds*1000 );
else if (g_llts == LLTS_HHMMSSMS)
lsquic_printf("%02d:%02d:%02d.%03d ", tm.wHour, tm.wMinute,
tm.wSecond, tm.wMilliseconds );
else if (g_llts == LLTS_HHMMSSUS)
lsquic_printf("%02d:%02d:%02d.%03d ", tm.wHour, tm.wMinute,
tm.wSecond, tm.wMilliseconds*1000 );
else if (g_llts == LLTS_CHROMELIKE)
lsquic_printf("%02d%02d/%02d%02d%02d.%06d ", tm.wMonth + 1,
tm.wDay,tm.wHour, tm.wMinute, tm.wSecond, (int) tm.wMilliseconds*1000);
#endif
}

View file

@ -48,6 +48,9 @@
#include <stdint.h>
#include <stdlib.h>
#include <sys/queue.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "fiu-local.h"
#include "lsquic_malo.h"
@ -75,7 +78,7 @@ struct malo_page {
};
typedef char malo_header_fits_in_one_slot
[0 - (sizeof(struct malo_page) > (1 << MALO_MAX_NBITS))];
[(sizeof(struct malo_page) > (1 << MALO_MAX_NBITS)) ? -1 : 1];
struct malo {
struct malo_page page_header;
@ -187,10 +190,18 @@ lsquic_malo_destroy (struct malo *malo)
while (page != &malo->page_header)
{
next = SLIST_NEXT(page, next_page);
#ifndef WIN32
free(page);
#else
_aligned_free(page);
#endif
page = next;
}
#ifndef WIN32
free(page);
#else
_aligned_free(page);
#endif
}

View file

@ -6,6 +6,9 @@
#include <stdlib.h> /* getenv */
#endif
#include <string.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_int_types.h"

View file

@ -10,40 +10,6 @@
#include "lsquic_packet_common.h"
static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
[QUIC_FRAME_INVALID] = "QUIC_FRAME_INVALID",
[QUIC_FRAME_STREAM] = "QUIC_FRAME_STREAM",
[QUIC_FRAME_ACK] = "QUIC_FRAME_ACK",
[QUIC_FRAME_PADDING] = "QUIC_FRAME_PADDING",
[QUIC_FRAME_RST_STREAM] = "QUIC_FRAME_RST_STREAM",
[QUIC_FRAME_CONNECTION_CLOSE] = "QUIC_FRAME_CONNECTION_CLOSE",
[QUIC_FRAME_GOAWAY] = "QUIC_FRAME_GOAWAY",
[QUIC_FRAME_WINDOW_UPDATE] = "QUIC_FRAME_WINDOW_UPDATE",
[QUIC_FRAME_BLOCKED] = "QUIC_FRAME_BLOCKED",
[QUIC_FRAME_STOP_WAITING] = "QUIC_FRAME_STOP_WAITING",
[QUIC_FRAME_PING] = "QUIC_FRAME_PING",
};
#define SLEN(x) (sizeof(#x) - sizeof("QUIC_FRAME_"))
const size_t lsquic_frame_types_str_sz =
/* We don't need to include INVALID frame in this list because it is
* never a part of any frame list bitmask (e.g. po_frame_types).
*/
SLEN(QUIC_FRAME_STREAM) + 1 +
SLEN(QUIC_FRAME_ACK) + 1 +
SLEN(QUIC_FRAME_PADDING) + 1 +
SLEN(QUIC_FRAME_RST_STREAM) + 1 +
SLEN(QUIC_FRAME_CONNECTION_CLOSE) + 1 +
SLEN(QUIC_FRAME_GOAWAY) + 1 +
SLEN(QUIC_FRAME_WINDOW_UPDATE) + 1 +
SLEN(QUIC_FRAME_BLOCKED) + 1 +
SLEN(QUIC_FRAME_STOP_WAITING) + 1 +
SLEN(QUIC_FRAME_PING) + 1;
const char *
lsquic_frame_types_to_str (char *buf, size_t bufsz,
enum quic_ft_bit frame_types)

View file

@ -50,7 +50,40 @@ enum quic_ft_bit {
QUIC_FTBIT_PING = 1 << QUIC_FRAME_PING,
};
extern const size_t lsquic_frame_types_str_sz;
static const char * const frame_type_2_str[N_QUIC_FRAMES] = {
[QUIC_FRAME_INVALID] = "QUIC_FRAME_INVALID",
[QUIC_FRAME_STREAM] = "QUIC_FRAME_STREAM",
[QUIC_FRAME_ACK] = "QUIC_FRAME_ACK",
[QUIC_FRAME_PADDING] = "QUIC_FRAME_PADDING",
[QUIC_FRAME_RST_STREAM] = "QUIC_FRAME_RST_STREAM",
[QUIC_FRAME_CONNECTION_CLOSE] = "QUIC_FRAME_CONNECTION_CLOSE",
[QUIC_FRAME_GOAWAY] = "QUIC_FRAME_GOAWAY",
[QUIC_FRAME_WINDOW_UPDATE] = "QUIC_FRAME_WINDOW_UPDATE",
[QUIC_FRAME_BLOCKED] = "QUIC_FRAME_BLOCKED",
[QUIC_FRAME_STOP_WAITING] = "QUIC_FRAME_STOP_WAITING",
[QUIC_FRAME_PING] = "QUIC_FRAME_PING",
};
#define SLEN(x) (sizeof(#x) - sizeof("QUIC_FRAME_"))
/* We don't need to include INVALID frame in this list because it is
* never a part of any frame list bitmask (e.g. po_frame_types).
*/
#define lsquic_frame_types_str_sz \
SLEN(QUIC_FRAME_STREAM) + 1 + \
SLEN(QUIC_FRAME_ACK) + 1 + \
SLEN(QUIC_FRAME_PADDING) + 1 + \
SLEN(QUIC_FRAME_RST_STREAM) + 1 + \
SLEN(QUIC_FRAME_CONNECTION_CLOSE) + 1 + \
SLEN(QUIC_FRAME_GOAWAY) + 1 + \
SLEN(QUIC_FRAME_WINDOW_UPDATE) + 1 + \
SLEN(QUIC_FRAME_BLOCKED) + 1 + \
SLEN(QUIC_FRAME_STOP_WAITING) + 1 + \
SLEN(QUIC_FRAME_PING) + 1
const char *
lsquic_frame_types_to_str (char *buf, size_t bufsz, enum quic_ft_bit);

View file

@ -2,6 +2,10 @@
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <sys/queue.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_int_types.h"
#include "lsquic_types.h"

View file

@ -6,7 +6,6 @@
#ifndef LSQUIC_PACKET_IN_H
#define LSQUIC_PACKET_IN_H 1
#include <sys/queue.h>
struct lsquic_packet_in;

View file

@ -24,7 +24,7 @@
#include "lsquic_ev_log.h"
typedef char _stream_rec_arr_is_at_most_64bytes[
(sizeof(struct stream_rec_arr) <= 64) - 1];
(sizeof(struct stream_rec_arr) <= 64)? 1: - 1];
static struct stream_rec *
srec_one_posi_first (struct packet_out_srec_iter *posi,
@ -615,7 +615,7 @@ lsquic_packet_out_split_in_two (struct lsquic_mm *mm,
struct stream_rec **new_srecs, **srecs = local_arr;
struct stream_rec *srec;
unsigned n_srecs_alloced = sizeof(local_arr) / sizeof(local_arr[0]);
unsigned n_srecs, max_idx, n, nbytes;
unsigned n_srecs, max_idx = 0, n, nbytes;
#ifndef NDEBUG
unsigned short frame_sum = 0;
#endif

View file

@ -5,7 +5,11 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifndef WIN32
#include <sys/types.h>
#else
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_alarmset.h"
@ -464,11 +468,13 @@ gquic_ietf_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
p += largest_acked_len;
CHECKOUT(2);
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_be_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
{
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_be_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
}
*has_missing = n_ranges > 1;
if (n_ranges > 1)

View file

@ -10,7 +10,11 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifndef WIN32
#include <sys/types.h>
#else
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_alarmset.h"
@ -880,11 +884,13 @@ gquic_be_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
p += largest_acked_len;
CHECKOUT(2);
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_be_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
{
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_be_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
}
if (n_ranges > 1)
{

View file

@ -18,6 +18,10 @@
#define bswap_16 OSSwapInt16
#define bswap_32 OSSwapInt32
#define bswap_64 OSSwapInt64
#elif defined(WIN32)
#define bswap_16 _byteswap_ushort
#define bswap_32 _byteswap_ulong
#define bswap_64 _byteswap_uint64
#else
#include <byteswap.h>
#endif

View file

@ -8,7 +8,12 @@
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <sys/queue.h>
#ifndef WIN32
#include <sys/types.h>
#else
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_packet_common.h"

View file

@ -10,7 +10,11 @@
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#ifndef WIN32
#include <sys/types.h>
#else
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_alarmset.h"
@ -766,11 +770,13 @@ gquic_le_gen_ack_frame (unsigned char *outbuf, size_t outbuf_sz,
p += largest_acked_len;
CHECKOUT(2);
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_le_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
{
lsquic_time_t diff = now - rechist_largest_recv(rechist);
gquic_le_write_float_time16(diff, p);
LSQ_DEBUG("%s: diff: %"PRIu64"; encoded: 0x%04X", __func__, diff,
*(uint16_t*)p);
p += 2;
}
if (n_ranges > 1)
{

View file

@ -8,6 +8,7 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <vc_compat.h>
#include "lsquic_int_types.h"
#include "lsquic_types.h"

View file

@ -5,7 +5,9 @@
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include "lsquic_int_types.h"
#include "lsquic_rtt.h"

View file

@ -299,7 +299,7 @@ static void
set_retx_alarm (lsquic_send_ctl_t *ctl)
{
enum retx_mode rm;
lsquic_time_t delay, now;
lsquic_time_t delay = 0, now;
assert(!TAILQ_EMPTY(&ctl->sc_unacked_packets));
@ -879,8 +879,10 @@ lsquic_send_ctl_pacer_blocked (struct lsquic_send_ctl *ctl)
#ifndef NDEBUG
#if __GNUC__
__attribute__((weak))
#endif
#endif
int
lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl)
{
@ -912,7 +914,7 @@ static void
send_ctl_expire (lsquic_send_ctl_t *ctl, enum expire_filter filter)
{
lsquic_packet_out_t *packet_out, *next;
int n_resubmitted;
int n_resubmitted =0;
static const char *const filter_type2str[] = {
[EXFI_ALL] = "all",
[EXFI_HSK] = "handshake",
@ -1282,7 +1284,7 @@ lsquic_send_ctl_set_tcid0 (lsquic_send_ctl_t *ctl, int tcid0)
void
lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *ctl, uint32_t stream_id)
{
struct lsquic_packet_out *packet_out, *next;
struct lsquic_packet_out *packet_out = NULL, *next = NULL;
unsigned n, adj;
for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
@ -1337,8 +1339,10 @@ lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *ctl, uint32_t stream_id)
* packets.
*/
#ifndef NDEBUG
#if __GNUC__
__attribute__((weak))
#endif
#endif
int
lsquic_send_ctl_have_delayed_packets (const lsquic_send_ctl_t *ctl)
{

View file

@ -10,6 +10,9 @@
#include <string.h>
#include <sys/queue.h>
#include <sys/types.h>
#ifdef WIN32
#include <vc_compat.h>
#endif
#include "lsquic_types.h"
#include "lsquic_int_types.h"
@ -21,7 +24,7 @@
#define LSQUIC_LOG_CONN_ID iter->spi_cid
#include "lsquic_logger.h"
#define SPI_DEBUG(fmt, a...) LSQ_DEBUG("%s: " fmt, iter->spi_name, a)
#define SPI_DEBUG(fmt, ...) LSQ_DEBUG("%s: " fmt, iter->spi_name, __VA_ARGS__)
#define NEXT_STREAM(stream, off) \
(* (struct lsquic_stream **) ((unsigned char *) (stream) + (off)))

View file

@ -1702,7 +1702,7 @@ lsquic_stream_write (lsquic_stream_t *stream, const void *buf, size_t len)
struct inner_reader_iovec {
const struct iovec *iov;
const struct iovec *const end;
const struct iovec *end;
unsigned cur_iovec_off;
};

View file

@ -7,9 +7,13 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#include <unistd.h>
#else
#include <vc_compat.h>
#endif
#if !(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) && defined(__APPLE__)
#include <mach/mach_time.h>
@ -22,6 +26,9 @@
#if defined(__APPLE__)
static mach_timebase_info_data_t timebase;
#endif
#if defined(WIN32)
static LARGE_INTEGER perf_frequency;
#endif
void
lsquic_init_timers (void)
@ -29,6 +36,9 @@ lsquic_init_timers (void)
#if defined(__APPLE__)
mach_timebase_info(&timebase);
#endif
#if defined(WIN32)
QueryPerformanceFrequency(&perf_frequency);
#endif
}
@ -45,6 +55,14 @@ lsquic_time_now (void)
t /= timebase.denom;
t /= 1000;
return t;
#elif defined(WIN32)
LARGE_INTEGER counter;
lsquic_time_t t;
QueryPerformanceCounter(&counter);
t = counter.QuadPart;
t *= 1000000;
t /= perf_frequency.QuadPart;
return t;
#else
# warn Monotonically increasing clock is not available on this platform
struct timeval tv;
@ -96,7 +114,7 @@ char *get_bin_str(const void *s, size_t len, size_t max_display_len)
pOutput = &str[0] + sprintf(str, "(%zd/%zd)=0x", len, lenOrg);
for(p = s, pEnd = s + len; p < pEnd; ++p)
for(p = s, pEnd = (unsigned char*)s + len; p < pEnd; ++p)
{
sprintf(pOutput, "%02X", *p);
pOutput += 2;