[BUGFIX] allow multiple parallel connections by default

Use the original method of tracking connections by CIDs by default.
If zero-sized CID support is turned on, connections are tracked by
the address.  A new connection is not created if another connection
is using the same network address.
This commit is contained in:
Dmitri Tikhonov 2018-06-13 11:10:28 -04:00
parent 96f77e2060
commit cd7bc3834d
6 changed files with 55 additions and 12 deletions

View file

@ -1,3 +1,12 @@
2018-06-13
- [BUGFIX] allow multiple parallel connections by default
Use the original method of tracking connections by CIDs by default.
If zero-sized CID support is turned on, connections are tracked by
the address. A new connection is not created if another connection
is using the same network address
2018-05-30
- [FEATURE, API CHANGE] Support zero-sized CIDs in received packets

View file

@ -201,7 +201,7 @@ struct lsquic_stream_if {
/** Do not use NSTP by default */
#define LSQUIC_DF_SUPPORT_NSTP 0
#define LSQUIC_DF_SUPPORT_PUSH 1
#define LSQUIC_DF_SUPPORT_TCID0 1
#define LSQUIC_DF_SUPPORT_TCID0 0
/** By default, LSQUIC ignores Public Reset packets. */
#define LSQUIC_DF_HONOR_PRST 0
@ -319,7 +319,12 @@ struct lsquic_engine_settings {
* If set to true value, the server will not include connection ID in
* outgoing packets if client's CHLO specifies TCID=0.
*
* For client, this means including TCID=0 into CHLO message.
* For client, this means including TCID=0 into CHLO message. Note that
* in this case, the engine tracks connections by the
* (source-addr, dest-addr) tuple, thereby making it necessary to create
* a socket for each connection.
*
* The default is @ref LSQUIC_DF_SUPPORT_TCID0.
*/
int es_support_tcid0;

View file

@ -26,7 +26,7 @@
static const unsigned char *
conn2hash_server (const struct lsquic_conn *lconn, unsigned char *buf,
conn2hash_by_cid (const struct lsquic_conn *lconn, unsigned char *buf,
size_t *sz)
{
*sz = sizeof(lconn->cn_cid);
@ -63,7 +63,7 @@ sockaddr2hash (const struct sockaddr *sa, unsigned char *buf, size_t *sz)
static const unsigned char *
conn2hash_client (const struct lsquic_conn *lconn, unsigned char *buf,
conn2hash_by_addr (const struct lsquic_conn *lconn, unsigned char *buf,
size_t *sz)
{
sockaddr2hash((struct sockaddr *) &lconn->cn_local_addr, buf, sz);
@ -72,7 +72,7 @@ conn2hash_client (const struct lsquic_conn *lconn, unsigned char *buf,
int
conn_hash_init (struct conn_hash *conn_hash, int server)
conn_hash_init (struct conn_hash *conn_hash, enum conn_hash_flags flags)
{
unsigned n;
@ -84,10 +84,11 @@ conn_hash_init (struct conn_hash *conn_hash, int server)
return -1;
for (n = 0; n < n_buckets(conn_hash->ch_nbits); ++n)
TAILQ_INIT(&conn_hash->ch_buckets[n]);
if (server)
conn_hash->ch_conn2hash = conn2hash_server;
conn_hash->ch_flags = flags;
if (flags & CHF_USE_ADDR)
conn_hash->ch_conn2hash = conn2hash_by_addr;
else
conn_hash->ch_conn2hash = conn2hash_client;
conn_hash->ch_conn2hash = conn2hash_by_cid;
LSQ_INFO("initialized");
return 0;
}

View file

@ -20,6 +20,12 @@ struct sockaddr;
TAILQ_HEAD(lsquic_conn_head, lsquic_conn);
enum conn_hash_flags
{
CHF_USE_ADDR = 1 << 0,
};
struct conn_hash
{
struct lsquic_conn_head *ch_buckets;
@ -29,6 +35,7 @@ struct conn_hash
} ch_iter;
unsigned ch_count;
unsigned ch_nbits;
enum conn_hash_flags ch_flags;
const unsigned char * (*ch_conn2hash)(const struct lsquic_conn *,
unsigned char *, size_t *);
};
@ -37,7 +44,7 @@ struct conn_hash
/* Returns -1 if malloc fails */
int
conn_hash_init (struct conn_hash *, int server);
conn_hash_init (struct conn_hash *, enum conn_hash_flags);
void
conn_hash_cleanup (struct conn_hash *);
@ -76,4 +83,6 @@ conn_hash_first (struct conn_hash *);
struct lsquic_conn *
conn_hash_next (struct conn_hash *);
#define conn_hash_using_addr(h) ((h)->ch_flags & CHF_USE_ADDR)
#endif

View file

@ -323,7 +323,9 @@ lsquic_engine_new (unsigned flags,
engine->pub.enp_pmi_ctx = NULL;
}
engine->pub.enp_engine = engine;
conn_hash_init(&engine->conns_hash, flags & ENG_SERVER);
conn_hash_init(&engine->conns_hash,
!(flags & ENG_SERVER) && engine->pub.enp_settings.es_support_tcid0 ?
CHF_USE_ADDR : 0);
engine->attq = attq_create();
eng_hist_init(&engine->history);
engine->batch_size = INITIAL_OUT_BATCH_SIZE;
@ -419,7 +421,17 @@ find_conn (lsquic_engine_t *engine, lsquic_packet_in_t *packet_in,
{
lsquic_conn_t *conn;
conn = conn_hash_find_by_addr(&engine->conns_hash, sa_local);
if (conn_hash_using_addr(&engine->conns_hash))
conn = conn_hash_find_by_addr(&engine->conns_hash, sa_local);
else if (packet_in->pi_flags & PI_CONN_ID)
conn = conn_hash_find_by_cid(&engine->conns_hash,
packet_in->pi_conn_id);
else
{
LSQ_DEBUG("packet header does not have connection ID: discarding");
return NULL;
}
if (!conn)
return NULL;
@ -568,6 +580,13 @@ lsquic_engine_connect (lsquic_engine_t *engine, const struct sockaddr *local_sa,
goto err;
}
if (conn_hash_using_addr(&engine->conns_hash)
&& conn_hash_find_by_addr(&engine->conns_hash, local_sa))
{
LSQ_ERROR("cannot have more than one connection on the same port");
goto err;
}
if (0 == max_packet_size)
{
switch (peer_sa->sa_family)

View file

@ -48,7 +48,7 @@ main (int argc, char **argv)
lsquic_set_log_level("info");
malo = lsquic_malo_create(sizeof(*lconn));
s = conn_hash_init(&conn_hash, 1);
s = conn_hash_init(&conn_hash, 0);
assert(0 == s);
for (n = 0; n < nelems; ++n)