mirror of
				https://gitea.invidious.io/iv-org/litespeed-quic.git
				synced 2024-08-15 00:53:43 +00:00 
			
		
		
		
	Release 2.26.0
- [OPTIMIZATION] Adjust packet reordering threshold when spurious losses are detected. - [API] Pass pointer to local sockaddr to ea_get_ssl_ctx() callback.
This commit is contained in:
		
							parent
							
								
									7f96c7c7f3
								
							
						
					
					
						commit
						fcbdf653b6
					
				
					 11 changed files with 98 additions and 25 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,9 @@
 | 
			
		|||
2020-12-09
 | 
			
		||||
    - 2.26.0
 | 
			
		||||
    - [OPTIMIZATION] Adjust packet reordering threshold when spurious losses
 | 
			
		||||
      are detected.
 | 
			
		||||
    - [API] Pass pointer to local sockaddr to ea_get_ssl_ctx() callback.
 | 
			
		||||
 | 
			
		||||
2020-12-04
 | 
			
		||||
    - 2.25.0
 | 
			
		||||
    - [API, FEATURE] Add es_delay_onclose option to delay on_close until all
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@
 | 
			
		|||
 | 
			
		||||
static int prog_stopped;
 | 
			
		||||
 | 
			
		||||
static SSL_CTX * get_ssl_ctx (void *);
 | 
			
		||||
static SSL_CTX * get_ssl_ctx (void *, const struct sockaddr *);
 | 
			
		||||
 | 
			
		||||
static const struct lsquic_packout_mem_if pmi = {
 | 
			
		||||
    .pmi_allocate = pba_allocate,
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +417,7 @@ prog_init_client (struct prog *prog)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
static SSL_CTX *
 | 
			
		||||
get_ssl_ctx (void *peer_ctx)
 | 
			
		||||
get_ssl_ctx (void *peer_ctx, const struct sockaddr *unused)
 | 
			
		||||
{
 | 
			
		||||
    const struct service_port *const sport = peer_ctx;
 | 
			
		||||
    return sport->sp_prog->prog_ssl_ctx;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -257,10 +257,10 @@ optional members.
 | 
			
		|||
 | 
			
		||||
        Look up certificate.  Mandatory in server mode.
 | 
			
		||||
 | 
			
		||||
    .. member:: struct ssl_ctx_st *                (*ea_get_ssl_ctx)(void *peer_ctx)
 | 
			
		||||
    .. member:: struct ssl_ctx_st *                (*ea_get_ssl_ctx)(void *peer_ctx, const struct sockaddr *local)
 | 
			
		||||
 | 
			
		||||
        Get SSL_CTX associated with a peer context.  Mandatory in server
 | 
			
		||||
        mode.  This is use for default values for SSL instantiation.
 | 
			
		||||
        mode.  This is used for default values for SSL instantiation.
 | 
			
		||||
 | 
			
		||||
    .. member:: const struct lsquic_hset_if         *ea_hsi_if
 | 
			
		||||
    .. member:: void                                *ea_hsi_ctx
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ copyright = u'2020, LiteSpeed Technologies'
 | 
			
		|||
author = u'LiteSpeed Technologies'
 | 
			
		||||
 | 
			
		||||
# The short X.Y version
 | 
			
		||||
version = u'2.25'
 | 
			
		||||
version = u'2.26'
 | 
			
		||||
# The full version, including alpha/beta/rc tags
 | 
			
		||||
release = u'2.25.0'
 | 
			
		||||
release = u'2.26.0'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# -- General configuration ---------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -863,7 +863,8 @@ The server requires SSL callbacks to be present.  The basic required callback is
 | 
			
		|||
  struct lsquic_engine_api {
 | 
			
		||||
    lsquic_lookup_cert_f   ea_lookup_cert;
 | 
			
		||||
    void                  *ea_cert_lu_ctx;
 | 
			
		||||
    struct ssl_ctx_st *  (*ea_get_ssl_ctx)(void *peer_ctx);
 | 
			
		||||
    struct ssl_ctx_st *  (*ea_get_ssl_ctx)(void *peer_ctx,
 | 
			
		||||
                                            const struct sockaddr *local);
 | 
			
		||||
    /* (Other members of the struct are not shown) */
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSQUIC_MAJOR_VERSION 2
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 25
 | 
			
		||||
#define LSQUIC_MINOR_VERSION 26
 | 
			
		||||
#define LSQUIC_PATCH_VERSION 0
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -1274,7 +1274,8 @@ struct lsquic_engine_api
 | 
			
		|||
    lsquic_lookup_cert_f                 ea_lookup_cert;
 | 
			
		||||
    void                                *ea_cert_lu_ctx;
 | 
			
		||||
    /** Mandatory callback for server, optional for client. */
 | 
			
		||||
    struct ssl_ctx_st *                (*ea_get_ssl_ctx)(void *peer_ctx);
 | 
			
		||||
    struct ssl_ctx_st *                (*ea_get_ssl_ctx)(void *peer_ctx,
 | 
			
		||||
                                                const struct sockaddr *local);
 | 
			
		||||
    /**
 | 
			
		||||
     * Shared hash interface is optional.  If set to zero, performance of
 | 
			
		||||
     * multiple LSQUIC instances will be degraded.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -888,11 +888,20 @@ iquic_esfi_create_client (const char *hostname,
 | 
			
		|||
        enc_sess->esi_alpn = am->alpn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (enc_sess->esi_enpub->enp_get_ssl_ctx
 | 
			
		||||
                && (ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(peer_ctx)))
 | 
			
		||||
        set_app_ctx = 1;
 | 
			
		||||
    if (enc_sess->esi_enpub->enp_get_ssl_ctx)
 | 
			
		||||
    {
 | 
			
		||||
        struct network_path *const path =
 | 
			
		||||
            enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
 | 
			
		||||
        ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(peer_ctx,
 | 
			
		||||
                                                            NP_LOCAL_SA(path));
 | 
			
		||||
        if (ssl_ctx)
 | 
			
		||||
            set_app_ctx = 1;
 | 
			
		||||
        else
 | 
			
		||||
            goto create_new_ssl_ctx;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
  create_new_ssl_ctx:
 | 
			
		||||
        LSQ_DEBUG("Create new SSL_CTX");
 | 
			
		||||
        ssl_ctx = SSL_CTX_new(TLS_method());
 | 
			
		||||
        if (!ssl_ctx)
 | 
			
		||||
| 
						 | 
				
			
			@ -1363,6 +1372,7 @@ static int
 | 
			
		|||
iquic_esfi_init_server (enc_session_t *enc_session_p)
 | 
			
		||||
{
 | 
			
		||||
    struct enc_sess_iquic *const enc_sess = enc_session_p;
 | 
			
		||||
    struct network_path *path;
 | 
			
		||||
    const struct alpn_map *am;
 | 
			
		||||
    unsigned quic_ctx_idx;
 | 
			
		||||
    int transpa_len;
 | 
			
		||||
| 
						 | 
				
			
			@ -1390,8 +1400,9 @@ iquic_esfi_init_server (enc_session_t *enc_session_p)
 | 
			
		|||
  ok:   enc_sess->esi_alpn = am->alpn;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(
 | 
			
		||||
                    lsquic_conn_get_peer_ctx(enc_sess->esi_conn, NULL));
 | 
			
		||||
    path = enc_sess->esi_conn->cn_if->ci_get_path(enc_sess->esi_conn, NULL);
 | 
			
		||||
    ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx(path->np_peer_ctx,
 | 
			
		||||
                                                            NP_LOCAL_SA(path));
 | 
			
		||||
    if (!ssl_ctx)
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_ERROR("fetching SSL context associated with peer context failed");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ struct ssl_ctx_st;
 | 
			
		|||
struct crand;
 | 
			
		||||
struct evp_aead_ctx_st;
 | 
			
		||||
struct lsquic_server_config;
 | 
			
		||||
struct sockaddr;
 | 
			
		||||
 | 
			
		||||
enum warning_type
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +38,8 @@ struct lsquic_engine_public {
 | 
			
		|||
    struct token_generator         *enp_tokgen;
 | 
			
		||||
    lsquic_lookup_cert_f            enp_lookup_cert;
 | 
			
		||||
    void                           *enp_cert_lu_ctx;
 | 
			
		||||
    struct ssl_ctx_st *           (*enp_get_ssl_ctx)(void *peer_ctx);
 | 
			
		||||
    struct ssl_ctx_st *           (*enp_get_ssl_ctx)(void *peer_ctx,
 | 
			
		||||
                                                     const struct sockaddr *);
 | 
			
		||||
    const struct lsquic_shared_hash_if
 | 
			
		||||
                                   *enp_shi;
 | 
			
		||||
    void                           *enp_shi_ctx;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -166,6 +166,7 @@ typedef struct lsquic_packet_out
 | 
			
		|||
        POL_HEADER_PROT = 1 << 9,       /* Header protection applied */
 | 
			
		||||
#endif
 | 
			
		||||
        POL_LIMITED     = 1 << 10,      /* Used to credit sc_next_limit if needed. */
 | 
			
		||||
        POL_FACKED   = 1 << 11,         /* Lost due to FACK check */
 | 
			
		||||
    }                  po_lflags:16;
 | 
			
		||||
    unsigned char     *po_data;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -417,6 +417,13 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
 | 
			
		|||
        ctl->sc_can_send = send_ctl_can_send_pre_hsk;
 | 
			
		||||
    else
 | 
			
		||||
        ctl->sc_can_send = send_ctl_can_send;
 | 
			
		||||
    ctl->sc_reord_thresh = N_NACKS_BEFORE_RETX;
 | 
			
		||||
#if LSQUIC_DEVEL
 | 
			
		||||
    const char *s;
 | 
			
		||||
    s = getenv("LSQUIC_DYN_PTHRESH");
 | 
			
		||||
    if (s == NULL || atoi(s))
 | 
			
		||||
        ctl->sc_flags |= SC_DYN_PTHRESH;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -884,7 +891,7 @@ send_ctl_destroy_chain (struct lsquic_send_ctl *ctl,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
static struct lsquic_packet_out *
 | 
			
		||||
send_ctl_record_loss (struct lsquic_send_ctl *ctl,
 | 
			
		||||
                                        struct lsquic_packet_out *packet_out)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -909,16 +916,21 @@ send_ctl_record_loss (struct lsquic_send_ctl *ctl,
 | 
			
		|||
         * remove from the list:
 | 
			
		||||
         */
 | 
			
		||||
        TAILQ_INSERT_BEFORE(packet_out, loss_record, po_next);
 | 
			
		||||
        return loss_record;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LSQ_INFO("cannot allocate memory for loss record");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
static struct lsquic_packet_out *
 | 
			
		||||
send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
 | 
			
		||||
            lsquic_packet_out_t *packet_out, struct lsquic_packet_out **next)
 | 
			
		||||
{
 | 
			
		||||
    struct lsquic_packet_out *loss_record;
 | 
			
		||||
    unsigned packet_sz;
 | 
			
		||||
 | 
			
		||||
    assert(ctl->sc_n_in_flight_all);
 | 
			
		||||
| 
						 | 
				
			
			@ -952,11 +964,11 @@ send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
 | 
			
		|||
    {
 | 
			
		||||
        LSQ_DEBUG("lost retransmittable packet %"PRIu64,
 | 
			
		||||
                                                    packet_out->po_packno);
 | 
			
		||||
        send_ctl_record_loss(ctl, packet_out);
 | 
			
		||||
        loss_record = send_ctl_record_loss(ctl, packet_out);
 | 
			
		||||
        send_ctl_unacked_remove(ctl, packet_out, packet_sz);
 | 
			
		||||
        TAILQ_INSERT_TAIL(&ctl->sc_lost_packets, packet_out, po_next);
 | 
			
		||||
        packet_out->po_flags |= PO_LOST;
 | 
			
		||||
        return 1;
 | 
			
		||||
        return loss_record;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -965,7 +977,7 @@ send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
 | 
			
		|||
        send_ctl_unacked_remove(ctl, packet_out, packet_sz);
 | 
			
		||||
        send_ctl_destroy_chain(ctl, packet_out, next);
 | 
			
		||||
        send_ctl_destroy_packet(ctl, packet_out);
 | 
			
		||||
        return 0;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -993,7 +1005,7 @@ send_ctl_handle_lost_packet (struct lsquic_send_ctl *ctl,
 | 
			
		|||
        struct lsquic_packet_out *packet_out, struct lsquic_packet_out **next)
 | 
			
		||||
{
 | 
			
		||||
    if (0 == (packet_out->po_flags & PO_MTU_PROBE))
 | 
			
		||||
        return send_ctl_handle_regular_lost_packet(ctl, packet_out, next);
 | 
			
		||||
        return send_ctl_handle_regular_lost_packet(ctl, packet_out, next) != NULL;
 | 
			
		||||
    else
 | 
			
		||||
        return send_ctl_handle_lost_mtu_probe(ctl, packet_out);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1031,7 +1043,7 @@ static int
 | 
			
		|||
send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
 | 
			
		||||
                                                            lsquic_time_t time)
 | 
			
		||||
{
 | 
			
		||||
    lsquic_packet_out_t *packet_out, *next;
 | 
			
		||||
    struct lsquic_packet_out *packet_out, *next, *loss_record;
 | 
			
		||||
    lsquic_packno_t largest_retx_packno, largest_lost_packno;
 | 
			
		||||
 | 
			
		||||
    largest_retx_packno = largest_retx_packet_number(ctl, pns);
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,14 +1059,22 @@ send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
 | 
			
		|||
        if (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        if (packet_out->po_packno + N_NACKS_BEFORE_RETX <
 | 
			
		||||
        if (packet_out->po_packno + ctl->sc_reord_thresh <
 | 
			
		||||
                                                ctl->sc_largest_acked_packno)
 | 
			
		||||
        {
 | 
			
		||||
            LSQ_DEBUG("loss by FACK detected, packet %"PRIu64,
 | 
			
		||||
            LSQ_DEBUG("loss by FACK detected (dist: %"PRIu64"), packet %"PRIu64,
 | 
			
		||||
                ctl->sc_largest_acked_packno - packet_out->po_packno,
 | 
			
		||||
                                                    packet_out->po_packno);
 | 
			
		||||
            if (0 == (packet_out->po_flags & PO_MTU_PROBE))
 | 
			
		||||
            {
 | 
			
		||||
                largest_lost_packno = packet_out->po_packno;
 | 
			
		||||
            (void) send_ctl_handle_lost_packet(ctl, packet_out, &next);
 | 
			
		||||
                loss_record = send_ctl_handle_regular_lost_packet(ctl,
 | 
			
		||||
                                                        packet_out, &next);
 | 
			
		||||
                if (loss_record)
 | 
			
		||||
                    loss_record->po_lflags |= POL_FACKED;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                send_ctl_handle_lost_mtu_probe(ctl, packet_out);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1120,6 +1140,26 @@ send_ctl_mtu_probe_acked (struct lsquic_send_ctl *ctl,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_ctl_maybe_increase_reord_thresh (struct lsquic_send_ctl *ctl,
 | 
			
		||||
                            const struct lsquic_packet_out *loss_record,
 | 
			
		||||
                            lsquic_packno_t prev_largest_acked)
 | 
			
		||||
{
 | 
			
		||||
#if LSQUIC_DEVEL
 | 
			
		||||
    if (ctl->sc_flags & SC_DYN_PTHRESH)
 | 
			
		||||
#endif
 | 
			
		||||
    if ((loss_record->po_lflags & POL_FACKED)
 | 
			
		||||
            && loss_record->po_packno + ctl->sc_reord_thresh
 | 
			
		||||
                < prev_largest_acked)
 | 
			
		||||
    {
 | 
			
		||||
        ctl->sc_reord_thresh = prev_largest_acked - loss_record->po_packno;
 | 
			
		||||
        LSQ_DEBUG("packet %"PRIu64" was a spurious loss by FACK, increase "
 | 
			
		||||
            "reordering threshold to %u", loss_record->po_packno,
 | 
			
		||||
            ctl->sc_reord_thresh);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
 | 
			
		||||
                         const struct ack_info *acki,
 | 
			
		||||
| 
						 | 
				
			
			@ -1129,6 +1169,7 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
 | 
			
		|||
                                    &acki->ranges[ acki->n_ranges - 1 ];
 | 
			
		||||
    lsquic_packet_out_t *packet_out, *next;
 | 
			
		||||
    lsquic_packno_t smallest_unacked;
 | 
			
		||||
    lsquic_packno_t prev_largest_acked;
 | 
			
		||||
    lsquic_packno_t ack2ed[2];
 | 
			
		||||
    unsigned packet_sz;
 | 
			
		||||
    int app_limited, losses_detected;
 | 
			
		||||
| 
						 | 
				
			
			@ -1190,6 +1231,7 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
 | 
			
		|||
        ctl->sc_cur_rt_end = lsquic_senhist_largest(&ctl->sc_senhist);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    prev_largest_acked = ctl->sc_largest_acked_packno;
 | 
			
		||||
    do_rtt = 0, skip_checks = 0;
 | 
			
		||||
    app_limited = -1;
 | 
			
		||||
    do
 | 
			
		||||
| 
						 | 
				
			
			@ -1234,6 +1276,8 @@ lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
 | 
			
		|||
                                                                    po_next);
 | 
			
		||||
                LSQ_DEBUG("acking via loss record %"PRIu64,
 | 
			
		||||
                                                        packet_out->po_packno);
 | 
			
		||||
                send_ctl_maybe_increase_reord_thresh(ctl, packet_out,
 | 
			
		||||
                                                            prev_largest_acked);
 | 
			
		||||
#if LSQUIC_CONN_STATS
 | 
			
		||||
                ++ctl->sc_conn_pub->conn_stats->out.acked_via_loss;
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,6 +54,9 @@ enum send_ctl_flags {
 | 
			
		|||
    SC_ACK_RECV_HSK =  SC_ACK_RECV_INIT << PNS_HSK,
 | 
			
		||||
    SC_ACK_RECV_APP =  SC_ACK_RECV_INIT << PNS_APP,
 | 
			
		||||
    SC_ROUGH_RTT    =  1 << 22,
 | 
			
		||||
#if LSQUIC_DEVEL
 | 
			
		||||
    SC_DYN_PTHRESH  =  1 << 31u,    /* dynamic packet threshold enabled */
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct lsquic_send_ctl {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +113,9 @@ typedef struct lsquic_send_ctl {
 | 
			
		|||
     * This information is used to drop stale ACK frames from packets in
 | 
			
		||||
     * buffered queues.
 | 
			
		||||
     */
 | 
			
		||||
    /* XXX We have both sc_largest_acked_packno and sc_largest_acked.  Rename
 | 
			
		||||
     * the latter to make the code more readable.
 | 
			
		||||
     */
 | 
			
		||||
    lsquic_packno_t                 sc_largest_acked;
 | 
			
		||||
    lsquic_time_t                   sc_loss_to;
 | 
			
		||||
    uint64_t                        sc_ecn_total_acked[N_PNS];
 | 
			
		||||
| 
						 | 
				
			
			@ -137,6 +143,7 @@ typedef struct lsquic_send_ctl {
 | 
			
		|||
    lsquic_packno_t                 sc_gap;
 | 
			
		||||
    unsigned                        sc_loss_count;  /* Used to set loss bit */
 | 
			
		||||
    unsigned                        sc_square_count;/* Used to set square bit */
 | 
			
		||||
    unsigned                        sc_reord_thresh;
 | 
			
		||||
    signed char                     sc_cidlen;      /* For debug purposes */
 | 
			
		||||
} lsquic_send_ctl_t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue