Skip to content

Commit

Permalink
Release 1.20.0
Browse files Browse the repository at this point in the history
[FEATURE] Add support for Q046.
  • Loading branch information
Dmitri Tikhonov committed Apr 1, 2019
1 parent 428530e commit c7d81ce
Show file tree
Hide file tree
Showing 29 changed files with 576 additions and 185 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2019-04-01
- 1.20.0
- [FEATURE] Add support for Q046.

2019-03-19
- 1.19.6
- [BUGFIX] Ensure that Largest Observed does not decrease in ACKs we
Expand Down
17 changes: 11 additions & 6 deletions include/lsquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ extern "C" {
#endif

#define LSQUIC_MAJOR_VERSION 1
#define LSQUIC_MINOR_VERSION 19
#define LSQUIC_PATCH_VERSION 6
#define LSQUIC_MINOR_VERSION 20
#define LSQUIC_PATCH_VERSION 0

/**
* Engine flags:
Expand Down Expand Up @@ -103,6 +103,11 @@ enum lsquic_version
*/
LSQVER_044,

/**
* Q046. Use IETF Draft-17 compatible packet headers.
*/
LSQVER_046,

#if LSQUIC_USE_Q098
/**
* Q098. This is a made-up, experimental version used to test version
Expand All @@ -119,7 +124,7 @@ enum lsquic_version
};

/**
* We currently support versions 35, 39, 43, and 44.
* We currently support versions 35, 39, 43, 44, and 46.
* @see lsquic_version
*/
#define LSQUIC_SUPPORTED_VERSIONS ((1 << N_LSQVER) - 1)
Expand All @@ -135,7 +140,7 @@ enum lsquic_version
/**
* List of versions in which the server never includes CID in short packets.
*/
#define LSQUIC_FORCED_TCID0_VERSIONS (1 << LSQVER_044)
#define LSQUIC_FORCED_TCID0_VERSIONS ((1 << LSQVER_044) | (1 << LSQVER_046))

enum lsquic_hsk_status
{
Expand Down Expand Up @@ -371,8 +376,8 @@ struct lsquic_engine_settings {
* (source-addr, dest-addr) tuple, thereby making it necessary to create
* a socket for each connection.
*
* This option has no effect in Q044, as the server never includes CIDs
* in the short packets.
* This option has no effect in Q044 or Q046, as the server never includes
* CIDs in the short packets.
*
* The default is @ref LSQUIC_DF_SUPPORT_TCID0.
*/
Expand Down
1 change: 1 addition & 0 deletions src/liblsquic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ SET(lsquic_STAT_SRCS
lsquic_min_heap.c
../lshpack/lshpack.c
lsquic_parse_Q044.c
lsquic_parse_Q046.c
lsquic_http1x_if.c
)

Expand Down
14 changes: 9 additions & 5 deletions src/liblsquic/lsquic_full_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1667,7 +1667,7 @@ process_stop_waiting_frame (struct full_conn *conn, lsquic_packet_in_t *packet_i
const unsigned char *p, size_t len)
{
lsquic_packno_t least, cutoff;
enum lsquic_packno_bits bits;
enum packno_bits bits;
int parsed_len;

bits = lsquic_packet_in_packno_bits(packet_in);
Expand Down Expand Up @@ -1948,12 +1948,14 @@ static void
reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in)
{
lsquic_packno_t cur_packno, max_packno;
enum lsquic_packno_bits bits;
enum packno_bits bits;
unsigned packet_len;

cur_packno = packet_in->pi_packno;
max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist);
bits = lsquic_packet_in_packno_bits(packet_in);
packet_in->pi_packno = restore_packno(cur_packno, bits, max_packno);
packet_len = conn->fc_conn.cn_pf->pf_packno_bits2len(bits);
packet_in->pi_packno = restore_packno(cur_packno, packet_len, max_packno);
LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") "
"to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno);
}
Expand Down Expand Up @@ -2377,14 +2379,16 @@ generate_stop_waiting_frame (struct full_conn *conn)
lsquic_packet_out_t *packet_out;

/* Get packet that has room for the minimum size STOP_WAITING frame: */
packet_out = get_writeable_packet(conn, 1 + packno_bits2len(PACKNO_LEN_1));
packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len(GQUIC_PACKNO_LEN_1);
packet_out = get_writeable_packet(conn, 1 + packnum_len);
if (!packet_out)
return;

/* Now calculate number of bytes we really need. If there is not enough
* room in the current packet, get a new one.
*/
packnum_len = packno_bits2len(lsquic_packet_out_packno_bits(packet_out));
packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len(
lsquic_packet_out_packno_bits(packet_out));
if ((unsigned) lsquic_packet_out_avail(packet_out) < 1 + packnum_len)
{
packet_out = get_writeable_packet(conn, 1 + packnum_len);
Expand Down
3 changes: 2 additions & 1 deletion src/liblsquic/lsquic_handshake.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,8 @@ lsquic_enc_session_gen_chlo (lsquic_enc_session_t *enc_session,

n_opts = 0;
/* CHLO is not regenerated during version negotiation. Hence we always
* include this option to cover the case when Q044 gets negotiated down.
* include this option to cover the case when Q044 or Q046 gets negotiated
* down.
*/
if (settings->es_support_nstp)
opts[ n_opts++ ] = QTAG_NSTP;
Expand Down
7 changes: 3 additions & 4 deletions src/liblsquic/lsquic_packet_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ lsquic_frame_types_to_str (char *buf, size_t bufsz,
}


enum lsquic_packno_bits
enum packno_bits
calc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked,
uint64_t n_in_flight)
{
Expand All @@ -65,14 +65,13 @@ calc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked,

lsquic_packno_t
restore_packno (lsquic_packno_t cur_packno,
enum lsquic_packno_bits cur_packno_bits,
unsigned len,
lsquic_packno_t max_packno)
{
lsquic_packno_t candidates[3], epoch_delta;
int64_t diffs[3];
unsigned min, len;
unsigned min;

len = packno_bits2len(cur_packno_bits);
epoch_delta = 1ULL << (len << 3);
candidates[1] = (max_packno & ~(epoch_delta - 1)) + cur_packno;
candidates[0] = candidates[1] - epoch_delta;
Expand Down
41 changes: 32 additions & 9 deletions src/liblsquic/lsquic_packet_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,36 @@ lsquic_frame_types_to_str (char *buf, size_t bufsz, enum quic_ft_bit);
#define QUIC_GOAWAY_FRAME_SZ 11 /* Type (1) + Error code (4) + Stream ID (4) +
Reason phrase length (2) */

/* Bitmask to be used as bits 4 and 5 (0x30) in common header's flag field: */
enum lsquic_packno_bits

/* This value represents a different number of bytes used to encode the packet
* length based on whether GQUIC or IQUIC is used.
*/
enum packno_bits
{
PACKNO_BITS_0 = 0,
PACKNO_BITS_1 = 1,
PACKNO_BITS_2 = 2,
PACKNO_BITS_3 = 3,
};


/* GQUIC maps 0, 1, 2, 3 -> 1, 2, 4, 6 */
enum
{
GQUIC_PACKNO_LEN_1 = PACKNO_BITS_0,
GQUIC_PACKNO_LEN_2 = PACKNO_BITS_1,
GQUIC_PACKNO_LEN_4 = PACKNO_BITS_2,
GQUIC_PACKNO_LEN_6 = PACKNO_BITS_3,
};


/* IQUIC maps 0, 1, 2, 3 -> 1, 2, 3, 4 (as of ID-17) */
enum
{
PACKNO_LEN_1 = 0,
PACKNO_LEN_2 = 1,
PACKNO_LEN_4 = 2,
PACKNO_LEN_6 = 3,
IQUIC_PACKNO_LEN_1 = PACKNO_BITS_0,
IQUIC_PACKNO_LEN_2 = PACKNO_BITS_1,
IQUIC_PACKNO_LEN_3 = PACKNO_BITS_2,
IQUIC_PACKNO_LEN_4 = PACKNO_BITS_3,
};


Expand All @@ -179,15 +202,15 @@ enum header_type

extern const char *const lsquic_hety2str[];

enum lsquic_packno_bits
enum packno_bits
calc_packno_bits (lsquic_packno_t packno, lsquic_packno_t least_unacked,
uint64_t n_in_flight);

#define packno_bits2len(b) (((b) << 1) + !(b))
#define gquic_packno_bits2len(b) (((b) << 1) + !(b))

lsquic_packno_t
restore_packno (lsquic_packno_t cur_packno,
enum lsquic_packno_bits cur_packno_bits,
unsigned packet_len,
lsquic_packno_t max_packno);

#endif
10 changes: 5 additions & 5 deletions src/liblsquic/lsquic_packet_in.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ typedef struct lsquic_packet_in
PI_ENC_LEV_BIT_0= (1 << 5), /* Encodes encryption level */
PI_ENC_LEV_BIT_1= (1 << 6), /* (see enum enc_level). */
PI_GQUIC = (1 << 7),
} pi_flags:8;
#define PIBIT_BITS_SHIFT 8
PI_BITS_BIT_0 = (1 << 8),
PI_BITS_BIT_1 = (1 << 9),
} pi_flags:16;
enum header_type pi_header_type:8;
/* If PI_OWN_DATA flag is not set, `pi_data' points to user-supplied
* packet data, which is NOT TO BE MODIFIED.
Expand All @@ -81,10 +84,7 @@ typedef struct lsquic_packet_in
(p)->pi_header_type == HETY_VERNEG)

#define lsquic_packet_in_packno_bits(p) \
(((p)->pi_flags & PI_GQUIC) ? \
((lsquic_packet_in_public_flags(p) >> 4) & 3) : \
((p)->pi_header_type == HETY_NOT_SET ? \
((p)->pi_data[0] & 3) : PACKNO_LEN_4))
(((p)->pi_flags >> PIBIT_BITS_SHIFT) & 3)

#define lsquic_packet_in_upref(p) (++(p)->pi_refcnt)

Expand Down
6 changes: 3 additions & 3 deletions src/liblsquic/lsquic_packet_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ lsquic_packet_out_add_stream (lsquic_packet_out_t *packet_out,

lsquic_packet_out_t *
lsquic_packet_out_new (struct lsquic_mm *mm, struct malo *malo, int use_cid,
const struct lsquic_conn *lconn, enum lsquic_packno_bits bits,
const struct lsquic_conn *lconn, enum packno_bits bits,
const lsquic_ver_tag_t *ver_tag, const unsigned char *nonce)
{
lsquic_packet_out_t *packet_out;
Expand All @@ -204,10 +204,10 @@ lsquic_packet_out_new (struct lsquic_mm *mm, struct malo *malo, int use_cid,
)
{
flags |= PO_LONGHEAD;
if (!((1 << lconn->cn_version) & LSQUIC_GQUIC_HEADER_VERSIONS))
if (lconn->cn_version == LSQVER_044)
{
flags &= ~(3 << POBIT_SHIFT);
flags |= PACKNO_LEN_4 << POBIT_SHIFT;
flags |= GQUIC_PACKNO_LEN_4 << POBIT_SHIFT;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/liblsquic/lsquic_packet_out.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ posi_next (struct packet_out_srec_iter *posi);

lsquic_packet_out_t *
lsquic_packet_out_new (struct lsquic_mm *, struct malo *, int use_cid,
const struct lsquic_conn *, enum lsquic_packno_bits,
const struct lsquic_conn *, enum packno_bits,
const lsquic_ver_tag_t *, const unsigned char *nonce);

void
Expand Down
26 changes: 21 additions & 5 deletions src/liblsquic/lsquic_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ typedef size_t (*gsf_read_f) (void *stream, void *buf, size_t len, int *fin);
/* This structure contains functions that parse and generate packets and
* frames in version-specific manner. To begin with, there is difference
* between GQUIC's little-endian (Q038 and lower) and big-endian formats
* (Q039 and higher). Q044 uses different format for packet headers.
* (Q039 and higher). Q044 and higher uses different format for packet headers.
*/
struct parse_funcs
{
Expand Down Expand Up @@ -96,14 +96,14 @@ struct parse_funcs
int *has_missing, lsquic_packno_t *largest_received);
int
(*pf_gen_stop_waiting_frame) (unsigned char *buf, size_t buf_len,
lsquic_packno_t cur_packno, enum lsquic_packno_bits,
lsquic_packno_t cur_packno, enum packno_bits,
lsquic_packno_t least_unacked_packno);
int
(*pf_parse_stop_waiting_frame) (const unsigned char *buf, size_t buf_len,
lsquic_packno_t cur_packno, enum lsquic_packno_bits,
lsquic_packno_t cur_packno, enum packno_bits,
lsquic_packno_t *least_unacked);
int
(*pf_skip_stop_waiting_frame) (size_t buf_len, enum lsquic_packno_bits);
(*pf_skip_stop_waiting_frame) (size_t buf_len, enum packno_bits);
int
(*pf_gen_window_update_frame) (unsigned char *buf, int buf_len,
uint32_t stream_id, uint64_t offset);
Expand Down Expand Up @@ -160,19 +160,28 @@ struct parse_funcs
size_t
(*pf_packout_header_size) (const struct lsquic_conn *,
enum packet_out_flags);

enum packno_bits
(*pf_calc_packno_bits) (lsquic_packno_t packno,
lsquic_packno_t least_unacked, uint64_t n_in_flight);
unsigned
(*pf_packno_bits2len) (enum packno_bits);
};

extern const struct parse_funcs lsquic_parse_funcs_gquic_le;
/* Q039 and later are big-endian: */
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q039;
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q044;
extern const struct parse_funcs lsquic_parse_funcs_gquic_Q046;

#define select_pf_by_ver(ver) ( \
((1 << (ver)) & (1 << LSQVER_035)) \
? &lsquic_parse_funcs_gquic_le \
: (ver) < LSQVER_044 \
? &lsquic_parse_funcs_gquic_Q039 \
: &lsquic_parse_funcs_gquic_Q044)
: (ver) < LSQVER_046 \
? &lsquic_parse_funcs_gquic_Q044 \
: &lsquic_parse_funcs_gquic_Q046)

int
lsquic_gquic_parse_packet_in_begin (struct lsquic_packet_in *, size_t length,
Expand Down Expand Up @@ -229,4 +238,11 @@ acki2str (const struct ack_info *acki, size_t *sz);
void
lsquic_turn_on_fin_Q035_thru_Q039 (unsigned char *);

enum packno_bits
lsquic_gquic_calc_packno_bits (lsquic_packno_t packno,
lsquic_packno_t least_unacked, uint64_t n_in_flight);

unsigned
lsquic_gquic_packno_bits2len (enum packno_bits);

#endif
10 changes: 6 additions & 4 deletions src/liblsquic/lsquic_parse_Q044.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ gen_short_pkt_header (const struct lsquic_conn *lconn,
size_t bufsz)
{
unsigned packno_len, need;
enum lsquic_packno_bits bits;
enum packno_bits bits;
uint32_t packno;

bits = (packet_out->po_flags >> POBIT_SHIFT) & 0x3;
packno_len = packno_bits2len(bits);
packno_len = gquic_packno_bits2len(bits);

need = 1 + 8 /* CID */ + packno_len;

Expand Down Expand Up @@ -138,13 +138,13 @@ static size_t
gquic_Q044_packout_header_size_short (const struct lsquic_conn *lconn,
enum packet_out_flags flags)
{
enum lsquic_packno_bits bits;
enum packno_bits bits;
size_t sz;

bits = (flags >> POBIT_SHIFT) & 0x3;
sz = 1; /* Type */
sz += 8; /* CID */
sz += packno_bits2len(bits);
sz += gquic_packno_bits2len(bits);

return sz;
}
Expand Down Expand Up @@ -210,4 +210,6 @@ const struct parse_funcs lsquic_parse_funcs_gquic_Q044 =
.pf_turn_on_fin = lsquic_turn_on_fin_Q035_thru_Q039,
.pf_packout_size = gquic_Q044_packout_size,
.pf_packout_header_size = gquic_Q044_packout_header_size,
.pf_calc_packno_bits = lsquic_gquic_calc_packno_bits,
.pf_packno_bits2len = lsquic_gquic_packno_bits2len,
};
Loading

0 comments on commit c7d81ce

Please sign in to comment.