mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Release 2.29.3
- [BUGFIX] Do not send RESET_STREAM if writing to stream is already finished. - perf_client: wait for all ACKs before exiting. - Improve how generated RESET_STREAM is logged. - Fix compilation in different combos of adv_tick/conn_stats flags. - Move qpack warning disablement into src/liblsquic/CMakeLists.txt.
This commit is contained in:
		
							parent
							
								
									f1d5a1a4de
								
							
						
					
					
						commit
						99a1ad0f24
					
				
					 20 changed files with 209 additions and 302 deletions
				
			
		| 
						 | 
					@ -1,3 +1,12 @@
 | 
				
			||||||
 | 
					2021-03-03
 | 
				
			||||||
 | 
					    - 2.29.3
 | 
				
			||||||
 | 
					    - [BUGFIX] Do not send RESET_STREAM if writing to stream is already
 | 
				
			||||||
 | 
					      finished.
 | 
				
			||||||
 | 
					    - perf_client: wait for all ACKs before exiting.
 | 
				
			||||||
 | 
					    - Improve how generated RESET_STREAM is logged.
 | 
				
			||||||
 | 
					    - Fix compilation in different combos of adv_tick/conn_stats flags.
 | 
				
			||||||
 | 
					    - Move qpack warning disablement into src/liblsquic/CMakeLists.txt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2021-02-23
 | 
					2021-02-23
 | 
				
			||||||
    - 2.29.2
 | 
					    - 2.29.2
 | 
				
			||||||
    - Fix regression in gQUIC server: bug #234.
 | 
					    - Fix regression in gQUIC server: bug #234.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,11 +45,6 @@ IF (NOT MSVC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter")
 | 
					SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wall -Wextra -Wno-unused-parameter")
 | 
				
			||||||
SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer")
 | 
					SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -fno-omit-frame-pointer")
 | 
				
			||||||
INCLUDE(CheckCCompilerFlag)
 | 
					 | 
				
			||||||
CHECK_C_COMPILER_FLAG(-Wno-implicit-fallthrough HAS_NO_IMPLICIT_FALLTHROUGH)
 | 
					 | 
				
			||||||
IF (HAS_NO_IMPLICIT_FALLTHROUGH)
 | 
					 | 
				
			||||||
    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-implicit-fallthrough")
 | 
					 | 
				
			||||||
ENDIF()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
 | 
					IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9.3)
 | 
				
			||||||
    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers")
 | 
					    SET(MY_CMAKE_FLAGS "${MY_CMAKE_FLAGS} -Wno-missing-field-initializers")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -785,7 +785,7 @@ http_client_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
 | 
				
			||||||
            if (client_ctx->hcc_reset_after_nbytes &&
 | 
					            if (client_ctx->hcc_reset_after_nbytes &&
 | 
				
			||||||
                s_stat_downloaded_bytes > client_ctx->hcc_reset_after_nbytes)
 | 
					                s_stat_downloaded_bytes > client_ctx->hcc_reset_after_nbytes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                lsquic_stream_reset(stream, 0x1);
 | 
					                lsquic_stream_maybe_reset(stream, 0x1, 1);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            /* test retire_cid after some number of read bytes */
 | 
					            /* test retire_cid after some number of read bytes */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -273,7 +273,9 @@ client_file_on_write_buf (lsquic_stream_ctx_t *st_h)
 | 
				
			||||||
    if (g_reset_stream.stream_id == lsquic_stream_id(st_h->stream) &&
 | 
					    if (g_reset_stream.stream_id == lsquic_stream_id(st_h->stream) &&
 | 
				
			||||||
        lseek(st_h->file->fd, 0, SEEK_CUR) >= g_reset_stream.offset)
 | 
					        lseek(st_h->file->fd, 0, SEEK_CUR) >= g_reset_stream.offset)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        lsquic_stream_reset(st_h->stream, 0x01    /* QUIC_INTERNAL_ERROR */);
 | 
					        /* Note: this is an internal function */
 | 
				
			||||||
 | 
					        lsquic_stream_maybe_reset(st_h->stream,
 | 
				
			||||||
 | 
					                0x01 /* QUIC_INTERNAL_ERROR */, 1);
 | 
				
			||||||
        g_reset_stream.stream_id = 0;   /* Reset only once */
 | 
					        g_reset_stream.stream_id = 0;   /* Reset only once */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,6 +335,7 @@ main (int argc, char **argv)
 | 
				
			||||||
    TAILQ_INIT(&sports);
 | 
					    TAILQ_INIT(&sports);
 | 
				
			||||||
    prog_init(&s_prog, 0, &sports, &perf_stream_if, NULL);
 | 
					    prog_init(&s_prog, 0, &sports, &perf_stream_if, NULL);
 | 
				
			||||||
    s_prog.prog_api.ea_alpn = "perf";
 | 
					    s_prog.prog_api.ea_alpn = "perf";
 | 
				
			||||||
 | 
					    s_prog.prog_settings.es_delay_onclose = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (-1 != (opt = getopt(argc, argv, PROG_OPTS "hp:T:")))
 | 
					    while (-1 != (opt = getopt(argc, argv, PROG_OPTS "hp:T:")))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ author = u'LiteSpeed Technologies'
 | 
				
			||||||
# The short X.Y version
 | 
					# The short X.Y version
 | 
				
			||||||
version = u'2.29'
 | 
					version = u'2.29'
 | 
				
			||||||
# The full version, including alpha/beta/rc tags
 | 
					# The full version, including alpha/beta/rc tags
 | 
				
			||||||
release = u'2.29.2'
 | 
					release = u'2.29.3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# -- General configuration ---------------------------------------------------
 | 
					# -- General configuration ---------------------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										37
									
								
								docs/devel.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								docs/devel.rst
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					Developing lsquic
 | 
				
			||||||
 | 
					=================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Generating Tags
 | 
				
			||||||
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Over the years, we have developed a wrapper around `Universal Ctags`_
 | 
				
			||||||
 | 
					to generate convenient tags so that, for example, ``ci_packet_in`` will
 | 
				
			||||||
 | 
					be able to take you to any of its implementations such as
 | 
				
			||||||
 | 
					``full_conn_ci_packet_in()``, ``evanescent_conn_ci_packet_in()``, and
 | 
				
			||||||
 | 
					others.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_Exuberant_ Ctags will work, too, but the more recent and maintained fork
 | 
				
			||||||
 | 
					of it, the _Universal_ Ctags, is preferred.  (If you are on Ubuntu, you
 | 
				
			||||||
 | 
					should clone Universal Ctags from GitHub and compiled it yourself.  The
 | 
				
			||||||
 | 
					version that comes in the Ubuntu package -- at the time of this writing
 | 
				
			||||||
 | 
					-- is so slow as to be considered broken).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The wrapper is ``tools/gen-tags.pl``.  Run it in the source directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. highlight:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sh$ cd lsquic
 | 
				
			||||||
 | 
					    sh$ ./tools/gen-tags.pl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Maintaining Documentation
 | 
				
			||||||
 | 
					-------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Documentation -- the ``*.rst`` files under ``docs/`` should be kept up-to-date
 | 
				
			||||||
 | 
					with changes in the API in ``include/lsquic.h``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For convenience, tags for the documentation files can be generated by passing
 | 
				
			||||||
 | 
					the ``--docs`` argument to ``tools/gen-tags.pl``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _`Universal Ctags`: https://ctags.io/
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,7 @@ Contents
 | 
				
			||||||
   tutorial
 | 
					   tutorial
 | 
				
			||||||
   apiref
 | 
					   apiref
 | 
				
			||||||
   internals
 | 
					   internals
 | 
				
			||||||
 | 
					   devel
 | 
				
			||||||
   faq
 | 
					   faq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Indices and tables
 | 
					Indices and tables
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ extern "C" {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LSQUIC_MAJOR_VERSION 2
 | 
					#define LSQUIC_MAJOR_VERSION 2
 | 
				
			||||||
#define LSQUIC_MINOR_VERSION 29
 | 
					#define LSQUIC_MINOR_VERSION 29
 | 
				
			||||||
#define LSQUIC_PATCH_VERSION 2
 | 
					#define LSQUIC_PATCH_VERSION 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Engine flags:
 | 
					 * Engine flags:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,7 +85,13 @@ SET(lsquic_STAT_SRCS
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IF(NOT MSVC)
 | 
					IF(NOT MSVC)
 | 
				
			||||||
set_source_files_properties(ls-qpack/lsqpack.c PROPERTIES COMPILE_FLAGS -Wno-uninitialized)
 | 
					    SET(QPACK_FLAGS "-Wno-uninitialized")
 | 
				
			||||||
 | 
					    INCLUDE(CheckCCompilerFlag)
 | 
				
			||||||
 | 
					    CHECK_C_COMPILER_FLAG(-Wno-implicit-fallthrough HAS_NO_IMPLICIT_FALLTHROUGH)
 | 
				
			||||||
 | 
					    IF (HAS_NO_IMPLICIT_FALLTHROUGH)
 | 
				
			||||||
 | 
					        SET(QPACK_FLAGS "${QPACK_FLAGS} -Wno-implicit-fallthrough")
 | 
				
			||||||
 | 
					    ENDIF()
 | 
				
			||||||
 | 
					set_source_files_properties(ls-qpack/lsqpack.c PROPERTIES COMPILE_FLAGS ${QPACK_FLAGS})
 | 
				
			||||||
ENDIF()
 | 
					ENDIF()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include_directories(ls-qpack)
 | 
					include_directories(ls-qpack)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,7 +96,7 @@
 | 
				
			||||||
#define LSQUIC_DEBUG_NEXT_ADV_TICK 1
 | 
					#define LSQUIC_DEBUG_NEXT_ADV_TICK 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK
 | 
					#if LSQUIC_DEBUG_NEXT_ADV_TICK || LSQUIC_CONN_STATS
 | 
				
			||||||
#include "lsquic_alarmset.h"
 | 
					#include "lsquic_alarmset.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3161,6 +3161,8 @@ lsquic_engine_earliest_adv_tick (lsquic_engine_t *engine, int *diff)
 | 
				
			||||||
    lsquic_time_t now, next_time;
 | 
					    lsquic_time_t now, next_time;
 | 
				
			||||||
#if LSQUIC_DEBUG_NEXT_ADV_TICK || LSQUIC_CONN_STATS
 | 
					#if LSQUIC_DEBUG_NEXT_ADV_TICK || LSQUIC_CONN_STATS
 | 
				
			||||||
    struct lsquic_conn *conn;
 | 
					    struct lsquic_conn *conn;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if LSQUIC_DEBUG_NEXT_ADV_TICK
 | 
				
			||||||
    const enum lsq_log_level L = LSQ_LOG_DEBUG;  /* Easy toggle */
 | 
					    const enum lsq_log_level L = LSQ_LOG_DEBUG;  /* Easy toggle */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3807,7 +3807,7 @@ full_conn_ci_close (struct lsquic_conn *lconn)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            stream = lsquic_hashelem_getdata(el);
 | 
					            stream = lsquic_hashelem_getdata(el);
 | 
				
			||||||
            if (!lsquic_stream_is_critical(stream))
 | 
					            if (!lsquic_stream_is_critical(stream))
 | 
				
			||||||
                lsquic_stream_reset(stream, 0);
 | 
					                lsquic_stream_maybe_reset(stream, 0, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        conn->fc_flags |= FC_CLOSING;
 | 
					        conn->fc_flags |= FC_CLOSING;
 | 
				
			||||||
        if (!(conn->fc_flags & FC_GOAWAY_SENT))
 | 
					        if (!(conn->fc_flags & FC_GOAWAY_SENT))
 | 
				
			||||||
| 
						 | 
					@ -3933,7 +3933,7 @@ headers_stream_on_stream_error (void *ctx, lsquic_stream_id_t stream_id)
 | 
				
			||||||
         * errors.  There does not seem to be a good reason to figure out
 | 
					         * errors.  There does not seem to be a good reason to figure out
 | 
				
			||||||
         * and send more specific error codes.
 | 
					         * and send more specific error codes.
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        lsquic_stream_reset_ext(stream, 1, 0);
 | 
					        lsquic_stream_maybe_reset(stream, 1, 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2581,8 +2581,11 @@ generate_rst_stream_frame (struct ietf_full_conn *conn,
 | 
				
			||||||
    lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, sz);
 | 
					    lsquic_send_ctl_incr_pack_sz(&conn->ifc_send_ctl, packet_out, sz);
 | 
				
			||||||
    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
 | 
					    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
 | 
				
			||||||
    lsquic_stream_rst_frame_sent(stream);
 | 
					    lsquic_stream_rst_frame_sent(stream);
 | 
				
			||||||
    LSQ_DEBUG("wrote RST: stream %"PRIu64"; offset 0x%"PRIX64"; error code "
 | 
					    LSQ_DEBUG("wrote RST: stream %"PRIu64"; offset %"PRIu64"; error code "
 | 
				
			||||||
              "%"PRIu64, stream->id, stream->tosend_off, stream->error_code);
 | 
					              "%"PRIu64, stream->id, stream->tosend_off, stream->error_code);
 | 
				
			||||||
 | 
					    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "generated RESET_STREAM: stream "
 | 
				
			||||||
 | 
					        "%"PRIu64"; offset %"PRIu64"; error code %"PRIu64, stream->id,
 | 
				
			||||||
 | 
					        stream->tosend_off, stream->error_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2919,7 +2922,7 @@ ietf_full_conn_ci_close (struct lsquic_conn *lconn)
 | 
				
			||||||
            stream = lsquic_hashelem_getdata(el);
 | 
					            stream = lsquic_hashelem_getdata(el);
 | 
				
			||||||
            sd = (stream->id >> SD_SHIFT) & 1;
 | 
					            sd = (stream->id >> SD_SHIFT) & 1;
 | 
				
			||||||
            if (SD_BIDI == sd)
 | 
					            if (SD_BIDI == sd)
 | 
				
			||||||
                lsquic_stream_reset(stream, 0);
 | 
					                lsquic_stream_maybe_reset(stream, 0, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        conn->ifc_flags |= IFC_CLOSING;
 | 
					        conn->ifc_flags |= IFC_CLOSING;
 | 
				
			||||||
        conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
 | 
					        conn->ifc_send_flags |= SF_SEND_CONN_CLOSE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,6 +144,9 @@ stream_readable_http_ietf (struct lsquic_stream *stream);
 | 
				
			||||||
static ssize_t
 | 
					static ssize_t
 | 
				
			||||||
stream_write_buf (struct lsquic_stream *stream, const void *buf, size_t sz);
 | 
					stream_write_buf (struct lsquic_stream *stream, const void *buf, size_t sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					stream_reset (struct lsquic_stream *, uint64_t error_code, int do_close);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t
 | 
					static size_t
 | 
				
			||||||
active_hq_frame_sizes (const struct lsquic_stream *);
 | 
					active_hq_frame_sizes (const struct lsquic_stream *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1284,7 +1287,7 @@ lsquic_stream_rst_in (lsquic_stream_t *stream, uint64_t offset,
 | 
				
			||||||
                        (STREAM_RST_SENT|STREAM_SS_SENT|STREAM_FIN_SENT))
 | 
					                        (STREAM_RST_SENT|STREAM_SS_SENT|STREAM_FIN_SENT))
 | 
				
			||||||
                            && !(stream->sm_bflags & SMBF_IETF)
 | 
					                            && !(stream->sm_bflags & SMBF_IETF)
 | 
				
			||||||
                                    && !(stream->sm_qflags & SMQF_SEND_RST))
 | 
					                                    && !(stream->sm_qflags & SMQF_SEND_RST))
 | 
				
			||||||
        lsquic_stream_reset_ext(stream, 7 /* QUIC_RST_ACKNOWLEDGEMENT */, 0);
 | 
					        stream_reset(stream, 7 /* QUIC_RST_ACKNOWLEDGEMENT */, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    stream->stream_flags |= STREAM_RST_RECVD;
 | 
					    stream->stream_flags |= STREAM_RST_RECVD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1324,7 +1327,7 @@ lsquic_stream_stop_sending_in (struct lsquic_stream *stream,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(stream->stream_flags & (STREAM_RST_SENT|STREAM_FIN_SENT))
 | 
					    if (!(stream->stream_flags & (STREAM_RST_SENT|STREAM_FIN_SENT))
 | 
				
			||||||
                                    && !(stream->sm_qflags & SMQF_SEND_RST))
 | 
					                                    && !(stream->sm_qflags & SMQF_SEND_RST))
 | 
				
			||||||
        lsquic_stream_reset_ext(stream, 0, 0);
 | 
					        stream_reset(stream, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    maybe_finish_stream(stream);
 | 
					    maybe_finish_stream(stream);
 | 
				
			||||||
    maybe_schedule_call_on_close(stream);
 | 
					    maybe_schedule_call_on_close(stream);
 | 
				
			||||||
| 
						 | 
					@ -1767,7 +1770,7 @@ handle_early_read_shutdown_gquic (struct lsquic_stream *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!(stream->stream_flags & STREAM_RST_SENT))
 | 
					    if (!(stream->stream_flags & STREAM_RST_SENT))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        lsquic_stream_reset_ext(stream, 7 /* QUIC_STREAM_CANCELLED */, 0);
 | 
					        stream_reset(stream, 7 /* QUIC_STREAM_CANCELLED */, 0);
 | 
				
			||||||
        stream->sm_qflags |= SMQF_WAIT_FIN_OFF;
 | 
					        stream->sm_qflags |= SMQF_WAIT_FIN_OFF;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1848,7 +1851,7 @@ stream_shutdown_write (lsquic_stream_t *stream)
 | 
				
			||||||
                && !(stream->stream_flags & STREAM_HEADERS_SENT))
 | 
					                && !(stream->stream_flags & STREAM_HEADERS_SENT))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LSQ_DEBUG("headers not sent, send a reset");
 | 
					            LSQ_DEBUG("headers not sent, send a reset");
 | 
				
			||||||
            lsquic_stream_reset(stream, 0);
 | 
					            stream_reset(stream, 0, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (stream->sm_n_buffered == 0)
 | 
					        else if (stream->sm_n_buffered == 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -4244,15 +4247,22 @@ lsquic_stream_set_max_send_off (lsquic_stream_t *stream, uint64_t offset)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
lsquic_stream_reset (lsquic_stream_t *stream, uint64_t error_code)
 | 
					lsquic_stream_maybe_reset (struct lsquic_stream *stream, uint64_t error_code,
 | 
				
			||||||
 | 
					                           int do_close)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    lsquic_stream_reset_ext(stream, error_code, 1);
 | 
					    if (!((stream->stream_flags
 | 
				
			||||||
 | 
					            & (STREAM_RST_SENT|STREAM_FIN_SENT|STREAM_U_WRITE_DONE))
 | 
				
			||||||
 | 
					        || (stream->sm_qflags & SMQF_SEND_RST)))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        stream_reset(stream, error_code, do_close);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (do_close)
 | 
				
			||||||
 | 
					        stream_shutdown_read(stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					static void
 | 
				
			||||||
lsquic_stream_reset_ext (lsquic_stream_t *stream, uint64_t error_code,
 | 
					stream_reset (struct lsquic_stream *stream, uint64_t error_code, int do_close)
 | 
				
			||||||
                         int do_close)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if ((stream->stream_flags & STREAM_RST_SENT)
 | 
					    if ((stream->stream_flags & STREAM_RST_SENT)
 | 
				
			||||||
                                    || (stream->sm_qflags & SMQF_SEND_RST))
 | 
					                                    || (stream->sm_qflags & SMQF_SEND_RST))
 | 
				
			||||||
| 
						 | 
					@ -4599,7 +4609,7 @@ lsquic_stream_refuse_push (lsquic_stream_t *stream)
 | 
				
			||||||
            && !(stream->stream_flags & STREAM_RST_SENT))
 | 
					            && !(stream->stream_flags & STREAM_RST_SENT))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        LSQ_DEBUG("refusing pushed stream: send reset");
 | 
					        LSQ_DEBUG("refusing pushed stream: send reset");
 | 
				
			||||||
        lsquic_stream_reset_ext(stream, 8 /* QUIC_REFUSED_STREAM */, 1);
 | 
					        stream_reset(stream, 8 /* QUIC_REFUSED_STREAM */, 1);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -510,10 +510,7 @@ void
 | 
				
			||||||
lsquic_stream_stream_frame_sent (lsquic_stream_t *);
 | 
					lsquic_stream_stream_frame_sent (lsquic_stream_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
lsquic_stream_reset (lsquic_stream_t *, uint64_t error_code);
 | 
					lsquic_stream_maybe_reset (struct lsquic_stream *, uint64_t error_code, int);
 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					 | 
				
			||||||
lsquic_stream_reset_ext (lsquic_stream_t *, uint64_t error_code, int close);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
lsquic_stream_call_on_close (lsquic_stream_t *);
 | 
					lsquic_stream_call_on_close (lsquic_stream_t *);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1242,7 +1242,7 @@ test_loc_RST_rem_FIN (struct test_objs *tobjs)
 | 
				
			||||||
    sss = lsquic_stream_sending_state(stream);
 | 
					    sss = lsquic_stream_sending_state(stream);
 | 
				
			||||||
    assert(SSS_SEND == sss);
 | 
					    assert(SSS_SEND == sss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lsquic_stream_reset(stream, 0);
 | 
					    lsquic_stream_maybe_reset(stream, 0, 1);
 | 
				
			||||||
    ++stream->n_unacked;    /* Fake sending of packet with RST_STREAM */
 | 
					    ++stream->n_unacked;    /* Fake sending of packet with RST_STREAM */
 | 
				
			||||||
    assert(!TAILQ_EMPTY(&tobjs->conn_pub.sending_streams));
 | 
					    assert(!TAILQ_EMPTY(&tobjs->conn_pub.sending_streams));
 | 
				
			||||||
    assert((stream->sm_qflags & SMQF_SENDING_FLAGS) == SMQF_SEND_RST);
 | 
					    assert((stream->sm_qflags & SMQF_SENDING_FLAGS) == SMQF_SEND_RST);
 | 
				
			||||||
| 
						 | 
					@ -1535,7 +1535,7 @@ test_unlimited_stream_flush_data (struct test_objs *tobjs)
 | 
				
			||||||
    lsquic_stream_flush(stream);
 | 
					    lsquic_stream_flush(stream);
 | 
				
			||||||
    assert(0x4000 == lsquic_conn_cap_avail(cap));
 | 
					    assert(0x4000 == lsquic_conn_cap_avail(cap));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lsquic_stream_reset(stream, 0xF00DF00D);
 | 
					    lsquic_stream_maybe_reset(stream, 0xF00DF00D, 1);
 | 
				
			||||||
    assert(0x4000 == lsquic_conn_cap_avail(cap));   /* Still unchanged */
 | 
					    assert(0x4000 == lsquic_conn_cap_avail(cap));   /* Still unchanged */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    lsquic_stream_destroy(stream);
 | 
					    lsquic_stream_destroy(stream);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,188 +0,0 @@
 | 
				
			||||||
#!/bin/bash
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Benchmark QUIC using LSQUIC http_client and other HTTP Benchmark tools.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Variables
 | 
					 | 
				
			||||||
CLIENT_TYPE=''
 | 
					 | 
				
			||||||
CLIENT_PATH='http_client'
 | 
					 | 
				
			||||||
CLIENTS='1'
 | 
					 | 
				
			||||||
TRIALS='1'
 | 
					 | 
				
			||||||
HOST='www.example.com'
 | 
					 | 
				
			||||||
IP='192.168.0.1'
 | 
					 | 
				
			||||||
IP_PORT='192.168.0.1:8000'
 | 
					 | 
				
			||||||
REQ_PATH='/'
 | 
					 | 
				
			||||||
QUIC_VERSION='Q043'
 | 
					 | 
				
			||||||
CLIENT_OPTIONS='none'
 | 
					 | 
				
			||||||
IGNORE_OUT=''
 | 
					 | 
				
			||||||
REQUESTS='1'
 | 
					 | 
				
			||||||
CONNS='1'
 | 
					 | 
				
			||||||
MAXREQS='1'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function usage() {
 | 
					 | 
				
			||||||
cat <<EOF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Usage: lsqb-master.sh [-hTtCHSPpqlKrcmw]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Benchmark QUIC using LSQUIC http_client and other HTTP Benchmark tools.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Arguments:
 | 
					 | 
				
			||||||
 -h, --help             Show this help message and exit
 | 
					 | 
				
			||||||
 -T, --trials           Number of trials. (Default: 1)
 | 
					 | 
				
			||||||
 -t, --client_type      Type of client.
 | 
					 | 
				
			||||||
                        Supported QUIC options: http_client.
 | 
					 | 
				
			||||||
                        Supported HTTP options: curl, curl-caddy, ab, h2load.
 | 
					 | 
				
			||||||
                        (Default: http_client)
 | 
					 | 
				
			||||||
 -a, --client_path      Path to http_client. (Default: http_client)
 | 
					 | 
				
			||||||
 -C, --clients          Number of concurrent clients. (Default: 1)
 | 
					 | 
				
			||||||
 -H  --host             Name of server. (Default: www.example.com)
 | 
					 | 
				
			||||||
 -S, --ip_port          IP:PORT of domain. (Default: 192.168.0.1:8000)
 | 
					 | 
				
			||||||
 -P, --ip               IP of domain for curl-caddy. (Default: 192.168.0.1)
 | 
					 | 
				
			||||||
 -p, --path             Path of file. (Default: /)
 | 
					 | 
				
			||||||
 -q, --quic_version     QUIC version. (Default: Q043)
 | 
					 | 
				
			||||||
 -l, --options          Options for http_client. (Default: none)
 | 
					 | 
				
			||||||
 -K, --ignore_out       Ignore output for http_client. (Default: off)
 | 
					 | 
				
			||||||
 -r, --requests         Number of requests. (Default: 1)
 | 
					 | 
				
			||||||
 -c, --conns            Number of concurrent connections. (Default: 1)
 | 
					 | 
				
			||||||
 -m, --maxreqs          Maximum number of requests per connection. (Default: 1)
 | 
					 | 
				
			||||||
 -w, --concur           Maximum number of concurrent streams
 | 
					 | 
				
			||||||
                        within a single connection. (Default: 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
EOF
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function check_input() {
 | 
					 | 
				
			||||||
  while [[ "$1" != '' ]]; do
 | 
					 | 
				
			||||||
    case $1 in
 | 
					 | 
				
			||||||
      -T | --trials )       shift
 | 
					 | 
				
			||||||
                            TRIALS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -t | --client_type)   shift
 | 
					 | 
				
			||||||
                            CLIENT_TYPE="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -a | --client_path)   shift
 | 
					 | 
				
			||||||
                            CLIENT_PATH="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -C | --clients )      shift
 | 
					 | 
				
			||||||
                            CLIENTS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -H | --host )         shift
 | 
					 | 
				
			||||||
                            HOST="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -S | --ip_port )      shift
 | 
					 | 
				
			||||||
                            IP_PORT="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -P | --ip )           shift
 | 
					 | 
				
			||||||
                            IP="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -p | --path )         shift
 | 
					 | 
				
			||||||
                            PATH_STRING="$1"
 | 
					 | 
				
			||||||
                            REQ_PATH="${PATH_STRING//,/ }"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -q | --quic_version ) shift
 | 
					 | 
				
			||||||
                            QUIC_VERSION="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -l | --options )      shift
 | 
					 | 
				
			||||||
                            CLIENT_OPTIONS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -K | --ignore_out)    
 | 
					 | 
				
			||||||
                            IGNORE_OUT="-K"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -r | --requests )     shift
 | 
					 | 
				
			||||||
                            REQUESTS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -c | --conns )        shift
 | 
					 | 
				
			||||||
                            CONNS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -m | --maxreqs )      shift
 | 
					 | 
				
			||||||
                            MAXREQS="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      -w | --concur )       shift
 | 
					 | 
				
			||||||
                            CONCUR="$1"
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
      * )                   usage
 | 
					 | 
				
			||||||
                            exit 1
 | 
					 | 
				
			||||||
                            ;;
 | 
					 | 
				
			||||||
    esac
 | 
					 | 
				
			||||||
    shift
 | 
					 | 
				
			||||||
  done
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_curl() {
 | 
					 | 
				
			||||||
  for (( i = 0; i < ${REQUESTS}; i++ )); do
 | 
					 | 
				
			||||||
    curl --header 'Host:$HOST' \
 | 
					 | 
				
			||||||
      -k https://${IP_PORT}/${REQ_PATH} \
 | 
					 | 
				
			||||||
      --output /dev/null --silent
 | 
					 | 
				
			||||||
  done
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_curl_caddy() {
 | 
					 | 
				
			||||||
  for (( i = 0; i < ${REQUESTS}; i++ )); do
 | 
					 | 
				
			||||||
    curl --resolve ${HOST}:443:${IP} \
 | 
					 | 
				
			||||||
      -k https://${HOST}/${REQ_PATH} --output \
 | 
					 | 
				
			||||||
      /dev/null --silent
 | 
					 | 
				
			||||||
  done
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_ab() {
 | 
					 | 
				
			||||||
  ab -n ${REQUESTS} -c ${CONNS} -k -X ${IP_PORT} \
 | 
					 | 
				
			||||||
  https://${HOST}/${REQ_PATH} &> /dev/null
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_h2load() {
 | 
					 | 
				
			||||||
  h2load -n ${REQUESTS} -c ${CONNS} -m ${CONNS} \
 | 
					 | 
				
			||||||
  https://${IP_PORT}/${REQ_PATH} > /dev/null
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_client() {
 | 
					 | 
				
			||||||
  if [[ "${CLIENT_OPTIONS}" == 'none' ]]; then
 | 
					 | 
				
			||||||
    CLIENT_OPTIONS=''
 | 
					 | 
				
			||||||
  fi
 | 
					 | 
				
			||||||
  ${CLIENT_PATH} ${IGNORE_OUT} \
 | 
					 | 
				
			||||||
    -H ${HOST} -s ${IP_PORT} \
 | 
					 | 
				
			||||||
    -p ${REQ_PATH} \
 | 
					 | 
				
			||||||
    -S rcvbuf=$[2000 * 2048] \
 | 
					 | 
				
			||||||
    -o support_tcid0=0 \
 | 
					 | 
				
			||||||
    -o version=${QUIC_VERSION} \
 | 
					 | 
				
			||||||
    ${CLIENT_OPTIONS} \
 | 
					 | 
				
			||||||
    -n ${CONNS} -r ${REQUESTS} -R ${MAXREQS} -w ${CONCUR}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function run_trials() {
 | 
					 | 
				
			||||||
  printf '\n'
 | 
					 | 
				
			||||||
  for (( i = 0; i < ${TRIALS}; i++ )); do
 | 
					 | 
				
			||||||
    START_TIME=$(date +%s.%3N)
 | 
					 | 
				
			||||||
    if [[ "${CLIENT_TYPE}" == 'curl' ]]; then
 | 
					 | 
				
			||||||
      for (( j = 0; j < ${CLIENTS}; j++ )); do
 | 
					 | 
				
			||||||
        run_curl &
 | 
					 | 
				
			||||||
      done
 | 
					 | 
				
			||||||
    elif [[ "${CLIENT_TYPE}" == 'curl-caddy' ]]; then
 | 
					 | 
				
			||||||
      for (( j = 0; j < ${CLIENTS}; j++ )); do
 | 
					 | 
				
			||||||
        run_curl_caddy &
 | 
					 | 
				
			||||||
      done
 | 
					 | 
				
			||||||
    elif [[ "${CLIENT_TYPE}" == 'ab' ]]; then
 | 
					 | 
				
			||||||
      for (( j = 0; j < ${CLIENTS}; j++ )); do
 | 
					 | 
				
			||||||
        run_ab &
 | 
					 | 
				
			||||||
      done
 | 
					 | 
				
			||||||
    elif [[ "${CLIENT_TYPE}" == 'h2load' ]]; then
 | 
					 | 
				
			||||||
      for (( j = 0; j < ${CLIENTS}; j++ )); do
 | 
					 | 
				
			||||||
        run_h2load &
 | 
					 | 
				
			||||||
      done
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      for (( j = 0; j < ${CLIENTS}; j++ )); do
 | 
					 | 
				
			||||||
        run_client &
 | 
					 | 
				
			||||||
      done
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
    wait
 | 
					 | 
				
			||||||
    END_TIME=$(date +%s.%3N)
 | 
					 | 
				
			||||||
    ELAPSED_TIME=$(awk "BEGIN {print ${END_TIME}-${START_TIME}}")
 | 
					 | 
				
			||||||
    printf ' %s, ' "${ELAPSED_TIME}"
 | 
					 | 
				
			||||||
  done
 | 
					 | 
				
			||||||
  printf '\n\n'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function main() {
 | 
					 | 
				
			||||||
  check_input "$@"
 | 
					 | 
				
			||||||
  run_trials
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
main "$@"
 | 
					 | 
				
			||||||
							
								
								
									
										48
									
								
								tools/gen-rst-tags.pl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tools/gen-rst-tags.pl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env perl
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Parse .rst files and generate tags.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use strict;
 | 
				
			||||||
 | 
					use warnings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					my $id = '[a-zA-Z_0-9]';
 | 
				
			||||||
 | 
					my @tags;
 | 
				
			||||||
 | 
					for my $file (@ARGV) {
 | 
				
			||||||
 | 
					    open my $fh, '<', $file
 | 
				
			||||||
 | 
					        or die "Cannot open $file for reading: $!";
 | 
				
			||||||
 | 
					    while (<$fh>) {
 | 
				
			||||||
 | 
					        chomp;
 | 
				
			||||||
 | 
					        if (m/^(\.\. function:: )(.+)/) {
 | 
				
			||||||
 | 
					            my ($pfx, $val) = ($1, $2);
 | 
				
			||||||
 | 
					            if ($val =~ m/($id+) \(/o) {
 | 
				
			||||||
 | 
					                push @tags, "$1\t$file\t/^$pfx$val/\n";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                warn "unknown pattern in $file:$.: $_\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } elsif (m/^(\s*\.\. (?:type|member):: )(.+)/) {
 | 
				
			||||||
 | 
					            my ($pfx, $val) = ($1, $2);
 | 
				
			||||||
 | 
					            if ($val =~ m/\(\*([^\)]+)\)/) {
 | 
				
			||||||
 | 
					                push @tags, "$1\t$file\t/^$pfx$val/\n";
 | 
				
			||||||
 | 
					            } elsif ($val =~ m/($id+)(?::\d+)?\s*$/o) {
 | 
				
			||||||
 | 
					                push @tags, "$1\t$file\t/^$pfx$val/\n";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                warn "unknown pattern in $file:$.: $_\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } elsif (m/^(\s*\.\. var:: )(.+)/) {
 | 
				
			||||||
 | 
					            my ($pfx, $val) = ($1, $2);
 | 
				
			||||||
 | 
					            if ($val =~ m/($id+)(?:\[[^\]]*\])?\s*$/o) {
 | 
				
			||||||
 | 
					                push @tags, "$1\t$file\t/^$pfx$val/\n";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                warn "unknown pattern in $file:$.: $_\n";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } elsif (m/^(\s*\.\. macro::\s+)(\S+)\s*$/) {
 | 
				
			||||||
 | 
					            push @tags, "$2\t$file\t/^$1$2/\n";
 | 
				
			||||||
 | 
					        } elsif (m/^\s*\.\. (?:toctree|image|highlight|code-block)::/) {
 | 
				
			||||||
 | 
					            # Skip
 | 
				
			||||||
 | 
					        } elsif (m/^\s*\.\.\s*\S+::/) {
 | 
				
			||||||
 | 
					            warn "unknown pattern in $file:$.: $_\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print sort @tags;
 | 
				
			||||||
							
								
								
									
										67
									
								
								tools/gen-tags.pl
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								tools/gen-tags.pl
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,67 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env perl
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Generate tags for lsquic project
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# If your `ctags' is not Universal Ctags, set UCTAGS environment variable to
 | 
				
			||||||
 | 
					# point to it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use warnings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Getopt::Long;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GetOptions("docs!" => \my $do_docs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$tmpfile = '.tags.' . $$ . rand;
 | 
				
			||||||
 | 
					$ctags = $ENV{UCTAGS} || 'ctags';
 | 
				
			||||||
 | 
					$queue_h = '/usr/include/sys/queue.h';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@dirs = qw(include bin tests src/lshpack src/liblsquic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					system($ctags, '-f', $tmpfile,
 | 
				
			||||||
 | 
					    ('--kinds-c=+p') x !!$do_docs,  # Index function prototypes
 | 
				
			||||||
 | 
					    qw(-R -I SLIST_ENTRY+=void -I LIST_ENTRY+=void
 | 
				
			||||||
 | 
					    -I STAILQ_ENTRY+=void -I TAILQ_ENTRY+=void -I CIRCLEQ_ENTRY+=void
 | 
				
			||||||
 | 
					    -I TAILQ_ENTRY+=void -I SLIST_HEAD+=void -I LIST_HEAD+=void
 | 
				
			||||||
 | 
					    -I STAILQ_HEAD+=void -I TAILQ_HEAD+=void -I CIRCLEQ_HEAD+=void
 | 
				
			||||||
 | 
					    -I TAILQ_HEAD+=void), @dirs)
 | 
				
			||||||
 | 
					        and die "ctags failed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-f $queue_h
 | 
				
			||||||
 | 
					    and system($ctags, '-f', $tmpfile, '-a', $queue_h)
 | 
				
			||||||
 | 
					    and die "ctags $queue_h failed";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ($do_docs) {
 | 
				
			||||||
 | 
					    @rst = glob("docs/*.rst");
 | 
				
			||||||
 | 
					    if (@rst) {
 | 
				
			||||||
 | 
					        system("$^X tools/gen-rst-tags.pl @rst >> $tmpfile")
 | 
				
			||||||
 | 
					            and die "cannot run tools/gen-rst-tags.pl";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					END { unlink $tmpfile }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					open TMPFILE, "<", $tmpfile
 | 
				
			||||||
 | 
					        or die "cannot open $tmpfile for reading: $!";
 | 
				
			||||||
 | 
					while (<TMPFILE>)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    push @lines, $_;
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					        s/^(mini|full|ietf_full|ietf_mini|evanescent)_conn_ci_/ci_/
 | 
				
			||||||
 | 
					     or s/^(nocopy|hash|error)_di_/di_/
 | 
				
			||||||
 | 
					     or s/^(gquic)_(be|Q046|Q050)_/pf_/
 | 
				
			||||||
 | 
					     or s/^ietf_v[0-9][0-9]*_/pf_/
 | 
				
			||||||
 | 
					     or s/^stock_shi_/shi_/
 | 
				
			||||||
 | 
					     or s/^iquic_esf_/esf_/
 | 
				
			||||||
 | 
					     or s/^gquic[0-9]?_esf_/esf_/
 | 
				
			||||||
 | 
					     or s/^iquic_esfi_/esfi_/
 | 
				
			||||||
 | 
					     or s/^(lsquic_cubic|lsquic_bbr)_/cci_/
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        push @lines, $_;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					open TMPFILE, ">", $tmpfile
 | 
				
			||||||
 | 
					        or die "cannot open $tmpfile for writing: $!";
 | 
				
			||||||
 | 
					print TMPFILE sort @lines;
 | 
				
			||||||
 | 
					close TMPFILE;
 | 
				
			||||||
 | 
					rename $tmpfile, 'tags';
 | 
				
			||||||
| 
						 | 
					@ -1,83 +0,0 @@
 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import json
 | 
					 | 
				
			||||||
import re
 | 
					 | 
				
			||||||
import argparse
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_ev_time = 0
 | 
					 | 
				
			||||||
_ev_cate = 1
 | 
					 | 
				
			||||||
_ev_type = 2
 | 
					 | 
				
			||||||
_ev_trig = 3
 | 
					 | 
				
			||||||
_ev_data = 4
 | 
					 | 
				
			||||||
_conn_base = {
 | 
					 | 
				
			||||||
    'qlog_version': '0.1',
 | 
					 | 
				
			||||||
    'vantagepoint': 'NETWORK',
 | 
					 | 
				
			||||||
    'connectionid': '0',
 | 
					 | 
				
			||||||
    'starttime': '0',
 | 
					 | 
				
			||||||
    'fields': [
 | 
					 | 
				
			||||||
        'time',
 | 
					 | 
				
			||||||
        'category',
 | 
					 | 
				
			||||||
        'type',
 | 
					 | 
				
			||||||
        'trigger',
 | 
					 | 
				
			||||||
        'data',
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    'events': [],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
arg_parser = argparse.ArgumentParser(description='Test the ExploreParser.')
 | 
					 | 
				
			||||||
arg_parser.add_argument('qlog_path', type=str, help='path to QLog file')
 | 
					 | 
				
			||||||
args = arg_parser.parse_args()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    with open(args.qlog_path, 'r') as file:
 | 
					 | 
				
			||||||
        text = file.read()
 | 
					 | 
				
			||||||
except IOError:
 | 
					 | 
				
			||||||
    print('ERROR: QLog not found at given path.')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
events = {}
 | 
					 | 
				
			||||||
event_times = {}
 | 
					 | 
				
			||||||
start_time = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
qlog = {
 | 
					 | 
				
			||||||
    'qlog_version': '0.1',
 | 
					 | 
				
			||||||
    'description': 'test with local log file',
 | 
					 | 
				
			||||||
    'connections': [],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
lines = text.split('\n')
 | 
					 | 
				
			||||||
for line in lines:
 | 
					 | 
				
			||||||
    if 'qlog' in line:
 | 
					 | 
				
			||||||
        i = line.find('[QUIC:')
 | 
					 | 
				
			||||||
        j = line.find(']', i)
 | 
					 | 
				
			||||||
        k = line.find('qlog: ')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cid = line[i+6:j]
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            event = json.loads(line[k+6:])
 | 
					 | 
				
			||||||
        except json.JSONDecodeError:
 | 
					 | 
				
			||||||
            continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not cid in events:
 | 
					 | 
				
			||||||
            events[cid] = [event]
 | 
					 | 
				
			||||||
            event_times[cid] = [event[_ev_time]]
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            events[cid].append(event)
 | 
					 | 
				
			||||||
            event_times[cid].append(event[_ev_time])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for cid, times in event_times.items():
 | 
					 | 
				
			||||||
    new_events = []
 | 
					 | 
				
			||||||
    start_time[cid] = min(times)
 | 
					 | 
				
			||||||
    times = [t - min(times) for t in times]
 | 
					 | 
				
			||||||
    for t, i in sorted(((t, i) for i, t in enumerate(times))):
 | 
					 | 
				
			||||||
        events[cid][i][0] = t
 | 
					 | 
				
			||||||
        new_events.append(events[cid][i])
 | 
					 | 
				
			||||||
    events[cid] = new_events
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for cid, event_list in events.items():
 | 
					 | 
				
			||||||
    conn = _conn_base.copy()
 | 
					 | 
				
			||||||
    conn['connectionid'] = cid
 | 
					 | 
				
			||||||
    conn['starttime'] = start_time[cid]
 | 
					 | 
				
			||||||
    conn['events'] = event_list
 | 
					 | 
				
			||||||
    qlog['connections'].append(conn)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print(json.dumps(qlog, indent=2))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue