mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
Release 1.19.3
- [BUGFIX] Q044: don't encode packet number in 6 bytes. Six-byte packet number encoding does not exist in Q044. This fixes a regression introduced in '[BUGFIX] Buffered packets can contain ACK frames' -- we need to keep QUIC version in mind when selecting the longest possible packet number encoding used for the buffered packet that carries the ACK. - [BUGFIX] Do not increase CWND when timeout occurs. - http_client: support setting handshake timeout on command line. Use -o handshake_to=timeout. - http_client: use -k to connect UDP socket to pick up ICMP errors. - http_client: allow pathless mode, when only handshake is performed without issuing any requests. This can be done by simply not specifying a -p flag on the command line.
This commit is contained in:
parent
3329170846
commit
9c4445241e
12 changed files with 113 additions and 20 deletions
16
CHANGELOG
16
CHANGELOG
|
@ -1,3 +1,19 @@
|
||||||
|
2019-02-18
|
||||||
|
- 1.19.3
|
||||||
|
- [BUGFIX] Q044: don't encode packet number in 6 bytes. Six-byte
|
||||||
|
packet number encoding does not exist in Q044. This fixes a
|
||||||
|
regression introduced in '[BUGFIX] Buffered packets can contain
|
||||||
|
ACK frames' -- we need to keep QUIC version in mind when selecting
|
||||||
|
the longest possible packet number encoding used for the buffered
|
||||||
|
packet that carries the ACK.
|
||||||
|
- [BUGFIX] Do not increase CWND when timeout occurs.
|
||||||
|
- http_client: support setting handshake timeout on command line.
|
||||||
|
Use -o handshake_to=timeout.
|
||||||
|
- http_client: use -k to connect UDP socket to pick up ICMP errors.
|
||||||
|
- http_client: allow pathless mode, when only handshake is performed
|
||||||
|
without issuing any requests. This can be done by simply not
|
||||||
|
specifying a -p flag on the command line.
|
||||||
|
|
||||||
2019-02-11
|
2019-02-11
|
||||||
- 1.19.2
|
- 1.19.2
|
||||||
- [BUGFIX] Begin negotiation with version provided in 0-RTT info.
|
- [BUGFIX] Begin negotiation with version provided in 0-RTT info.
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
|
|
||||||
#define LSQUIC_MAJOR_VERSION 1
|
#define LSQUIC_MAJOR_VERSION 1
|
||||||
#define LSQUIC_MINOR_VERSION 19
|
#define LSQUIC_MINOR_VERSION 19
|
||||||
#define LSQUIC_PATCH_VERSION 2
|
#define LSQUIC_PATCH_VERSION 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine flags:
|
* Engine flags:
|
||||||
|
|
|
@ -183,10 +183,14 @@ lsquic_cubic_loss (struct lsquic_cubic *cubic)
|
||||||
void
|
void
|
||||||
lsquic_cubic_timeout (struct lsquic_cubic *cubic)
|
lsquic_cubic_timeout (struct lsquic_cubic *cubic)
|
||||||
{
|
{
|
||||||
|
unsigned long cwnd;
|
||||||
|
|
||||||
|
cwnd = cubic->cu_cwnd;
|
||||||
LSQ_DEBUG("%s(cubic)", __func__);
|
LSQ_DEBUG("%s(cubic)", __func__);
|
||||||
cubic_reset(cubic);
|
cubic_reset(cubic);
|
||||||
cubic->cu_ssthresh = cubic->cu_cwnd;
|
cubic->cu_ssthresh = cwnd / 2;
|
||||||
cubic->cu_tcp_cwnd = cubic->cu_cwnd;
|
cubic->cu_tcp_cwnd = 2 * TCP_MSS;
|
||||||
|
cubic->cu_cwnd = 2 * TCP_MSS;
|
||||||
LSQ_INFO("timeout, cwnd: %lu", cubic->cu_cwnd);
|
LSQ_INFO("timeout, cwnd: %lu", cubic->cu_cwnd);
|
||||||
LOG_CWND(cubic);
|
LOG_CWND(cubic);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2106,6 +2106,7 @@ process_incoming_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
|
||||||
}
|
}
|
||||||
LSQ_DEBUG("end of version negotiation: agreed upon %s",
|
LSQ_DEBUG("end of version negotiation: agreed upon %s",
|
||||||
lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
|
lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
|
||||||
|
lsquic_send_ctl_verneg_done(&conn->fc_send_ctl);
|
||||||
}
|
}
|
||||||
return process_regular_packet(conn, packet_in);
|
return process_regular_packet(conn, packet_in);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1923,7 +1923,7 @@ lsquic_enc_session_get_zero_rtt (lsquic_enc_session_t *enc_session,
|
||||||
sz += sizeof(struct lsquic_zero_rtt_storage);
|
sz += sizeof(struct lsquic_zero_rtt_storage);
|
||||||
if (len < sz)
|
if (len < sz)
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("client provided buf is too small %lu < %lu", len, sz);
|
LSQ_DEBUG("client provided buf is too small %zu < %zu", len, sz);
|
||||||
errno = ENOBUFS;
|
errno = ENOBUFS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,7 @@ lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
|
||||||
for (i = 0; i < sizeof(ctl->sc_buffered_packets) /
|
for (i = 0; i < sizeof(ctl->sc_buffered_packets) /
|
||||||
sizeof(ctl->sc_buffered_packets[0]); ++i)
|
sizeof(ctl->sc_buffered_packets[0]); ++i)
|
||||||
TAILQ_INIT(&ctl->sc_buffered_packets[i].bpq_packets);
|
TAILQ_INIT(&ctl->sc_buffered_packets[i].bpq_packets);
|
||||||
|
ctl->sc_max_packno_bits = PACKNO_LEN_4; /* Safe value before verneg */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1698,7 +1699,7 @@ send_ctl_get_buffered_packet (lsquic_send_ctl_t *ctl,
|
||||||
{
|
{
|
||||||
LSQ_DEBUG("steal ACK frame from low-priority buffered queue");
|
LSQ_DEBUG("steal ACK frame from low-priority buffered queue");
|
||||||
ack_action = AA_STEAL;
|
ack_action = AA_STEAL;
|
||||||
bits = PACKNO_LEN_6;
|
bits = ctl->sc_max_packno_bits;
|
||||||
}
|
}
|
||||||
/* If ACK can be generated, write it to the first buffered packet. */
|
/* If ACK can be generated, write it to the first buffered packet. */
|
||||||
else if (lconn->cn_if->ci_can_write_ack(lconn))
|
else if (lconn->cn_if->ci_can_write_ack(lconn))
|
||||||
|
@ -1709,7 +1710,7 @@ send_ctl_get_buffered_packet (lsquic_send_ctl_t *ctl,
|
||||||
/* Packet length is set to the largest possible size to guarantee
|
/* Packet length is set to the largest possible size to guarantee
|
||||||
* that buffered packet with the ACK will not need to be split.
|
* that buffered packet with the ACK will not need to be split.
|
||||||
*/
|
*/
|
||||||
bits = PACKNO_LEN_6;
|
bits = ctl->sc_max_packno_bits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto no_ack_action;
|
goto no_ack_action;
|
||||||
|
@ -1781,12 +1782,17 @@ enum lsquic_packno_bits
|
||||||
lsquic_send_ctl_calc_packno_bits (lsquic_send_ctl_t *ctl)
|
lsquic_send_ctl_calc_packno_bits (lsquic_send_ctl_t *ctl)
|
||||||
{
|
{
|
||||||
lsquic_packno_t smallest_unacked;
|
lsquic_packno_t smallest_unacked;
|
||||||
|
enum lsquic_packno_bits bits;
|
||||||
unsigned n_in_flight;
|
unsigned n_in_flight;
|
||||||
|
|
||||||
smallest_unacked = lsquic_send_ctl_smallest_unacked(ctl);
|
smallest_unacked = lsquic_send_ctl_smallest_unacked(ctl);
|
||||||
n_in_flight = lsquic_cubic_get_cwnd(&ctl->sc_cubic) / ctl->sc_pack_size;
|
n_in_flight = lsquic_cubic_get_cwnd(&ctl->sc_cubic) / ctl->sc_pack_size;
|
||||||
return calc_packno_bits(ctl->sc_cur_packno + 1, smallest_unacked,
|
bits = calc_packno_bits(ctl->sc_cur_packno + 1, smallest_unacked,
|
||||||
n_in_flight);
|
n_in_flight);
|
||||||
|
if (bits <= ctl->sc_max_packno_bits)
|
||||||
|
return bits;
|
||||||
|
else
|
||||||
|
return ctl->sc_max_packno_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1929,3 +1935,18 @@ lsquic_send_ctl_mem_used (const struct lsquic_send_ctl *ctl)
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_verneg_done (struct lsquic_send_ctl *ctl)
|
||||||
|
{
|
||||||
|
if ((1 << ctl->sc_conn_pub->lconn->cn_version) &
|
||||||
|
LSQUIC_GQUIC_HEADER_VERSIONS)
|
||||||
|
ctl->sc_max_packno_bits = PACKNO_LEN_6;
|
||||||
|
else
|
||||||
|
/* Assuming Q044 */
|
||||||
|
ctl->sc_max_packno_bits = PACKNO_LEN_4;
|
||||||
|
LSQ_DEBUG("version negotiation done (%s): max packno bits: %u",
|
||||||
|
lsquic_ver2str[ ctl->sc_conn_pub->lconn->cn_version ],
|
||||||
|
ctl->sc_max_packno_bits);
|
||||||
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ typedef struct lsquic_send_ctl {
|
||||||
} sc_cached_bpt;
|
} sc_cached_bpt;
|
||||||
unsigned sc_next_limit;
|
unsigned sc_next_limit;
|
||||||
unsigned sc_n_scheduled;
|
unsigned sc_n_scheduled;
|
||||||
|
enum lsquic_packno_bits sc_max_packno_bits;
|
||||||
#if LSQUIC_SEND_STATS
|
#if LSQUIC_SEND_STATS
|
||||||
struct {
|
struct {
|
||||||
unsigned n_total_sent,
|
unsigned n_total_sent,
|
||||||
|
@ -283,4 +284,7 @@ int
|
||||||
lsquic_send_ctl_buffered_and_same_prio_as_headers (struct lsquic_send_ctl *,
|
lsquic_send_ctl_buffered_and_same_prio_as_headers (struct lsquic_send_ctl *,
|
||||||
const struct lsquic_stream *);
|
const struct lsquic_stream *);
|
||||||
|
|
||||||
|
void
|
||||||
|
lsquic_send_ctl_verneg_done (struct lsquic_send_ctl *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -231,7 +231,7 @@ create_connections (struct http_client_ctx *client_ctx)
|
||||||
{
|
{
|
||||||
zero_rtt = client_ctx->hcc_zero_rtt;
|
zero_rtt = client_ctx->hcc_zero_rtt;
|
||||||
zero_rtt_len = client_ctx->hcc_zero_rtt_len;
|
zero_rtt_len = client_ctx->hcc_zero_rtt_len;
|
||||||
LSQ_INFO("create connection zero_rtt %ld bytes", zero_rtt_len);
|
LSQ_INFO("create connection zero_rtt %zu bytes", zero_rtt_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (client_ctx->hcc_n_open_conns < client_ctx->hcc_concurrency &&
|
while (client_ctx->hcc_n_open_conns < client_ctx->hcc_concurrency &&
|
||||||
|
@ -268,7 +268,8 @@ http_client_on_new_conn (void *stream_if_ctx, lsquic_conn_t *conn)
|
||||||
client_ctx->hcc_total_n_reqs -= conn_h->ch_n_reqs;
|
client_ctx->hcc_total_n_reqs -= conn_h->ch_n_reqs;
|
||||||
TAILQ_INSERT_TAIL(&client_ctx->conn_ctxs, conn_h, next_ch);
|
TAILQ_INSERT_TAIL(&client_ctx->conn_ctxs, conn_h, next_ch);
|
||||||
++conn_h->client_ctx->hcc_n_open_conns;
|
++conn_h->client_ctx->hcc_n_open_conns;
|
||||||
create_streams(client_ctx, conn_h);
|
if (!TAILQ_EMPTY(&client_ctx->hcc_path_elems))
|
||||||
|
create_streams(client_ctx, conn_h);
|
||||||
conn_h->ch_created = lsquic_time_now();
|
conn_h->ch_created = lsquic_time_now();
|
||||||
return conn_h;
|
return conn_h;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +366,7 @@ http_client_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
client_ctx->hcc_zero_rtt_len = ret;
|
client_ctx->hcc_zero_rtt_len = ret;
|
||||||
LSQ_INFO("get zero_rtt %ld bytes", client_ctx->hcc_zero_rtt_len);
|
LSQ_INFO("get zero_rtt %zu bytes", client_ctx->hcc_zero_rtt_len);
|
||||||
client_ctx->hcc_flags |= HCC_RTT_INFO;
|
client_ctx->hcc_flags |= HCC_RTT_INFO;
|
||||||
/* clear file and prepare to write */
|
/* clear file and prepare to write */
|
||||||
if (client_ctx->hcc_zero_rtt_file)
|
if (client_ctx->hcc_zero_rtt_file)
|
||||||
|
@ -392,7 +393,7 @@ http_client_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
|
||||||
size_t ret2 = fwrite(client_ctx->hcc_zero_rtt, 1,
|
size_t ret2 = fwrite(client_ctx->hcc_zero_rtt, 1,
|
||||||
client_ctx->hcc_zero_rtt_len,
|
client_ctx->hcc_zero_rtt_len,
|
||||||
client_ctx->hcc_zero_rtt_file);
|
client_ctx->hcc_zero_rtt_file);
|
||||||
LSQ_DEBUG("wrote %ld bytes to zero_rtt file", ret2);
|
LSQ_DEBUG("wrote %zu bytes to zero_rtt file", ret2);
|
||||||
if (ret2 == client_ctx->hcc_zero_rtt_len)
|
if (ret2 == client_ctx->hcc_zero_rtt_len)
|
||||||
{
|
{
|
||||||
fclose(client_ctx->hcc_zero_rtt_file);
|
fclose(client_ctx->hcc_zero_rtt_file);
|
||||||
|
@ -419,6 +420,11 @@ http_client_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
|
||||||
++s_stat_conns_ok;
|
++s_stat_conns_ok;
|
||||||
update_sample_stats(&s_stat_to_conn,
|
update_sample_stats(&s_stat_to_conn,
|
||||||
lsquic_time_now() - conn_h->ch_created);
|
lsquic_time_now() - conn_h->ch_created);
|
||||||
|
if (TAILQ_EMPTY(&client_ctx->hcc_path_elems))
|
||||||
|
{
|
||||||
|
LSQ_INFO("no paths mode: close connection");
|
||||||
|
lsquic_conn_close(conn_h->conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++s_stat_conns_failed;
|
++s_stat_conns_failed;
|
||||||
|
@ -762,7 +768,9 @@ usage (const char *prog)
|
||||||
"Usage: %s [opts]\n"
|
"Usage: %s [opts]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -p PATH Path to request. May be specified more than once.\n"
|
" -p PATH Path to request. May be specified more than once. If no\n"
|
||||||
|
" path is specified, the connection is closed as soon as\n"
|
||||||
|
" handshake succeeds.\n"
|
||||||
" -n CONNS Number of concurrent connections. Defaults to 1.\n"
|
" -n CONNS Number of concurrent connections. Defaults to 1.\n"
|
||||||
" -r NREQS Total number of requests to send. Defaults to 1.\n"
|
" -r NREQS Total number of requests to send. Defaults to 1.\n"
|
||||||
" -R MAXREQS Maximum number of requests per single connection. Some\n"
|
" -R MAXREQS Maximum number of requests per single connection. Some\n"
|
||||||
|
@ -1180,16 +1188,11 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
client_ctx.hcc_flags |= HCC_RTT_INFO;
|
client_ctx.hcc_flags |= HCC_RTT_INFO;
|
||||||
client_ctx.hcc_zero_rtt_len = ret;
|
client_ctx.hcc_zero_rtt_len = ret;
|
||||||
LSQ_DEBUG("read %ld bytes from zero_rtt file", ret);
|
LSQ_DEBUG("read %zu bytes from zero_rtt file", ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LSQ_DEBUG("zero_rtt file is empty");
|
LSQ_DEBUG("zero_rtt file is empty");
|
||||||
}
|
}
|
||||||
if (TAILQ_EMPTY(&client_ctx.hcc_path_elems))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Specify at least one path using -p option\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
start_time = lsquic_time_now();
|
start_time = lsquic_time_now();
|
||||||
if (0 != prog_prep(&prog))
|
if (0 != prog_prep(&prog))
|
||||||
|
|
10
test/prog.c
10
test/prog.c
|
@ -152,6 +152,8 @@ prog_print_common_options (const struct prog *prog, FILE *out)
|
||||||
|
|
||||||
|
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
|
" -k Connect UDP socket. Only meant to be used with clients\n"
|
||||||
|
" to pick up ICMP errors.\n"
|
||||||
" -i USECS Clock granularity in microseconds. Defaults to %u.\n",
|
" -i USECS Clock granularity in microseconds. Defaults to %u.\n",
|
||||||
LSQUIC_DF_CLOCK_GRANULARITY
|
LSQUIC_DF_CLOCK_GRANULARITY
|
||||||
);
|
);
|
||||||
|
@ -239,6 +241,14 @@ prog_set_opt (struct prog *prog, int opt, const char *arg)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case 'k':
|
||||||
|
{
|
||||||
|
struct service_port *sport = TAILQ_LAST(prog->prog_sports, sport_head);
|
||||||
|
if (!sport)
|
||||||
|
sport = &prog->prog_dummy_sport;
|
||||||
|
sport->sp_flags |= SPORT_CONNECT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ prog_init (struct prog *, unsigned lsquic_engine_flags, struct sport_head *,
|
||||||
# define IP_DONTFRAG_FLAG ""
|
# define IP_DONTFRAG_FLAG ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PROG_OPTS "i:m:c:y:L:l:o:H:s:S:Y:z:" IP_DONTFRAG_FLAG
|
#define PROG_OPTS "i:km:c:y:L:l:o:H:s:S:Y:z:" IP_DONTFRAG_FLAG
|
||||||
|
|
||||||
/* Returns:
|
/* Returns:
|
||||||
* 0 Applied
|
* 0 Applied
|
||||||
|
|
|
@ -545,6 +545,13 @@ read_one_packet (struct read_iter *iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if __GNUC__
|
||||||
|
# define UNLIKELY(cond) __builtin_expect(cond, 0)
|
||||||
|
#else
|
||||||
|
# define UNLIKELY(cond) cond
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_handler (evutil_socket_t fd, short flags, void *ctx)
|
read_handler (evutil_socket_t fd, short flags, void *ctx)
|
||||||
{
|
{
|
||||||
|
@ -570,6 +577,14 @@ read_handler (evutil_socket_t fd, short flags, void *ctx)
|
||||||
rop = read_one_packet(&iter);
|
rop = read_one_packet(&iter);
|
||||||
while (ROP_OK == rop);
|
while (ROP_OK == rop);
|
||||||
|
|
||||||
|
if (UNLIKELY(ROP_ERROR == rop && (sport->sp_flags & SPORT_CONNECT)
|
||||||
|
&& errno == ECONNREFUSED))
|
||||||
|
{
|
||||||
|
LSQ_ERROR("connection refused: exit program");
|
||||||
|
prog_cleanup(sport->sp_prog);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
n_batches += iter.ri_idx > 0;
|
n_batches += iter.ri_idx > 0;
|
||||||
|
|
||||||
for (n = 0; n < iter.ri_idx; ++n)
|
for (n = 0; n < iter.ri_idx; ++n)
|
||||||
|
@ -623,7 +638,7 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine,
|
||||||
int flags;
|
int flags;
|
||||||
#endif
|
#endif
|
||||||
SOCKET_TYPE sockfd;
|
SOCKET_TYPE sockfd;
|
||||||
socklen_t socklen;
|
socklen_t socklen, peer_socklen;
|
||||||
union {
|
union {
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct sockaddr_in6 sin6;
|
struct sockaddr_in6 sin6;
|
||||||
|
@ -663,6 +678,19 @@ sport_init_client (struct service_port *sport, struct lsquic_engine *engine,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sport->sp_flags & SPORT_CONNECT)
|
||||||
|
{
|
||||||
|
peer_socklen = AF_INET == sa_peer->sa_family
|
||||||
|
? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||||
|
if (0 != connect(sockfd, sa_peer, peer_socklen))
|
||||||
|
{
|
||||||
|
saved_errno = errno;
|
||||||
|
CLOSE_SOCKET(sockfd);
|
||||||
|
errno = saved_errno;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Make socket non-blocking */
|
/* Make socket non-blocking */
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
flags = fcntl(sockfd, F_GETFL);
|
flags = fcntl(sockfd, F_GETFL);
|
||||||
|
@ -1079,6 +1107,11 @@ set_engine_option (struct lsquic_engine_settings *settings,
|
||||||
settings->es_pace_packets = atoi(val);
|
settings->es_pace_packets = atoi(val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (0 == strncmp(name, "handshake_to", 12))
|
||||||
|
{
|
||||||
|
settings->es_handshake_to = atoi(val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
if (0 == strncmp(name, "support_tcid0", 13))
|
if (0 == strncmp(name, "support_tcid0", 13))
|
||||||
|
|
|
@ -28,6 +28,7 @@ enum sport_flags
|
||||||
SPORT_SET_SNDBUF = (1 << 1), /* SO_SNDBUF */
|
SPORT_SET_SNDBUF = (1 << 1), /* SO_SNDBUF */
|
||||||
SPORT_SET_RCVBUF = (1 << 2), /* SO_RCVBUF */
|
SPORT_SET_RCVBUF = (1 << 2), /* SO_RCVBUF */
|
||||||
SPORT_SERVER = (1 << 3),
|
SPORT_SERVER = (1 << 3),
|
||||||
|
SPORT_CONNECT = (1 << 4),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct service_port {
|
struct service_port {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue