diff --git a/BUILD-WINDOWS.md b/BUILD-WINDOWS.md index 288017a..26c5b7c 100644 --- a/BUILD-WINDOWS.md +++ b/BUILD-WINDOWS.md @@ -1,14 +1,14 @@ -LiteSpeed QUIC (LSQUIC) Client Library - Building for Windows -============================================================= +LiteSpeed QUIC (LSQUIC) Library - Building for Windows +====================================================== Description ----------- This document is intended to supplement the document README.md at the -root of the distribution of the LiteSpeed QUIC (LSQUIC) Client Library +root of the distribution of the LiteSpeed QUIC (LSQUIC) Library to build the library and programs in a Windows environment. -The addition of Windows support to the LSQUIC Client was a contribution +The addition of Windows support to the LSQUIC was a contribution from the user community and this document was based on our experiences of validating the code. As for the overall implementation, do not hesitate to report bugs back to us. Even better, continue to send us fixes and @@ -30,7 +30,7 @@ Some open source code required to be installed to build the code include: version appropriate for the development/target platform (32 vs 64-bits, etc.). - The Windows vcpkg package manager. It can be cloned from [here](https://github.com/Microsoft/vcpkg). - Clone it at the same level to be used to clone/develop the lsquic-client. + Clone it at the same level to be used to clone/develop the lsquic. The package must be compiled following the instructions on the git repository. - Perform builds using the _Developer Command Prompt for Visual Studio_ instead @@ -48,7 +48,7 @@ Some open source code required to be installed to build the code include: - From the command line, once the variable above has been defined, install both *zlib* and *libevent*. Note that libevent may also automatically install *openssl*. If it does not, it may need to be manually specified - to properly link the lsquic-client executables. + to properly link the lsquic executables. ``` vcpkg install zlib:x64-windows-static vcpkg install libevent:x64-windows-static @@ -68,15 +68,15 @@ Some open source code required to be installed to build the code include: platform to *64-bit*. Compile the project. - Repeat the cmake and compile steps replacing *Debug* with *Release*. -Make and Compile LSQUIC-Client ------------------------------- +Make and Compile LSQUIC +----------------------- -Clone lsquic-client: +Clone lsquic: ``` - git clone https://github.com/litespeedtech/lsquic-client.git --recurse-submodules - cd lsquic-client + git clone https://github.com/litespeedtech/lsquic.git --recurse-submodules + cd lsquic ``` Configure the build using cmake (you can specify `Release` instead of `Debug` @@ -107,4 +107,4 @@ Have fun, LiteSpeed QUIC Team. -Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc +Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc diff --git a/CHANGELOG b/CHANGELOG index 831c496..20bc12f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +2020-12-17 + - 2.26.1 + - [BUGFIX] Migration corner cases: drop or pad over path challenge + and response frames when necessary. + - Fix stream unit test. + 2020-12-09 - 2.26.0 - [OPTIMIZATION] Adjust packet reordering threshold when spurious losses diff --git a/CMakeLists.txt b/CMakeLists.txt index c70ee2b..23cb540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -271,6 +271,7 @@ ELSE() MESSAGE(STATUS "pcreposix not found: http_server won't work") ENDIF() LIST(APPEND LIBS ws2_32) +LIST(APPEND LIBS iphlpapi) ENDIF() ENDIF() # LSQUIC_BIN OR LSQUIC_TESTS diff --git a/docs/conf.py b/docs/conf.py index 9d37bd0..25d7d25 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies' # The short X.Y version version = u'2.26' # The full version, including alpha/beta/rc tags -release = u'2.26.0' +release = u'2.26.1' # -- General configuration --------------------------------------------------- diff --git a/include/lsquic.h b/include/lsquic.h index 1612d45..ea47754 100644 --- a/include/lsquic.h +++ b/include/lsquic.h @@ -25,7 +25,7 @@ extern "C" { #define LSQUIC_MAJOR_VERSION 2 #define LSQUIC_MINOR_VERSION 26 -#define LSQUIC_PATCH_VERSION 0 +#define LSQUIC_PATCH_VERSION 1 /** * Engine flags: diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index fe12561..f53d3bd 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -728,6 +728,8 @@ path_chal_alarm_expired (enum alarm_id al_id, void *ctx, { LSQ_INFO("migration to path #%u failed after none of %u path " "challenges received responses", path_id, copath->cop_n_chals); + /* There may be a lingering challenge if its generation is delayed */ + lsquic_send_ctl_cancel_chals(&conn->ifc_send_ctl, &copath->cop_path); wipe_path(conn, path_id); } else diff --git a/src/liblsquic/lsquic_packet_out.c b/src/liblsquic/lsquic_packet_out.c index e6610e8..1bfc7b8 100644 --- a/src/liblsquic/lsquic_packet_out.c +++ b/src/liblsquic/lsquic_packet_out.c @@ -527,3 +527,24 @@ lsquic_packet_out_equal_dcids (const struct lsquic_packet_out *a, return sizes[0] == sizes[1] && 0 == memcmp(dcids[0], dcids[1], sizes[0]); } + + +void +lsquic_packet_out_pad_over (struct lsquic_packet_out *packet_out, + enum quic_ft_bit frame_types) +{ + struct packet_out_frec_iter pofi; + struct frame_rec *frec; + + for (frec = lsquic_pofi_first(&pofi, packet_out); frec; + frec = lsquic_pofi_next(&pofi)) + { + if ((1 << frec->fe_frame_type) & frame_types) + { + memset(packet_out->po_data + frec->fe_off, 0, frec->fe_len); + frec->fe_frame_type = QUIC_FRAME_PADDING; + } + } + + packet_out->po_frame_types &= ~frame_types; +} diff --git a/src/liblsquic/lsquic_packet_out.h b/src/liblsquic/lsquic_packet_out.h index f5c692c..3c7245e 100644 --- a/src/liblsquic/lsquic_packet_out.h +++ b/src/liblsquic/lsquic_packet_out.h @@ -351,4 +351,9 @@ lsquic_packet_out_turn_on_fin (struct lsquic_packet_out *, int lsquic_packet_out_equal_dcids (const struct lsquic_packet_out *, const struct lsquic_packet_out *); + +void +lsquic_packet_out_pad_over (struct lsquic_packet_out *packet_out, + enum quic_ft_bit frame_types); + #endif diff --git a/src/liblsquic/lsquic_send_ctl.c b/src/liblsquic/lsquic_send_ctl.c index db7881e..c26bb65 100644 --- a/src/liblsquic/lsquic_send_ctl.c +++ b/src/liblsquic/lsquic_send_ctl.c @@ -3578,6 +3578,14 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl, packet_out->po_path = new; if (packet_out->po_flags & PO_ENCRYPTED) send_ctl_return_enc_data(ctl, packet_out); + if (packet_out->po_frame_types + & (QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_PATH_RESPONSE)) + /* This is a corner case, we just want to avoid protocol + * violation. No optimization is done. If we happen to + * send a packet of padding, oh well. + */ + lsquic_packet_out_pad_over(packet_out, + QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_PATH_RESPONSE); } LSQ_DEBUG("repathed %u packet%.*s", count, count != 1, "s"); @@ -3594,6 +3602,32 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl, } +/* Drop PATH_CHALLENGE packets for path `path'. */ +void +lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *ctl, + const struct network_path *path) +{ + struct lsquic_packet_out *packet_out, *next; + + /* We need only to examine the scheduled queue as lost challenges are + * not retransmitted. + */ + for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out; + packet_out = next) + { + next = TAILQ_NEXT(packet_out, po_next); + if (packet_out->po_path == path + && packet_out->po_frame_types == QUIC_FTBIT_PATH_CHALLENGE) + { + send_ctl_maybe_renumber_sched_to_right(ctl, packet_out); + send_ctl_sched_remove(ctl, packet_out); + assert(packet_out->po_loss_chain == packet_out); + send_ctl_destroy_packet(ctl, packet_out); + } + } +} + + /* Examine packets in scheduled and buffered queues and resize packets if * they exceed path MTU. */ diff --git a/src/liblsquic/lsquic_send_ctl.h b/src/liblsquic/lsquic_send_ctl.h index 73df974..401c14f 100644 --- a/src/liblsquic/lsquic_send_ctl.h +++ b/src/liblsquic/lsquic_send_ctl.h @@ -386,6 +386,10 @@ lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl, const struct network_path *old, const struct network_path *new, int keep_path_properties); +void +lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *, + const struct network_path *); + void lsquic_send_ctl_resize (struct lsquic_send_ctl *); diff --git a/tests/test_stream.c b/tests/test_stream.c index 7874830..7e103d4 100644 --- a/tests/test_stream.c +++ b/tests/test_stream.c @@ -1077,10 +1077,10 @@ test_loc_data_rem_RST (struct test_objs *tobjs) assert((stream->sm_qflags & SMQF_SERVICE_FLAGS) == SMQF_FREE_STREAM); } + const unsigned expected_nread = stream->sm_bflags & SMBF_IETF ? 100 : 200; lsquic_stream_destroy(stream); assert(TAILQ_EMPTY(&tobjs->conn_pub.service_streams)); - const unsigned expected_nread = stream->sm_bflags & SMBF_IETF ? 100 : 200; assert(expected_nread == tobjs->conn_pub.cfcw.cf_max_recv_off); assert(expected_nread == tobjs->conn_pub.cfcw.cf_read_off); }