1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-30 00:00:16 +01:00

adns: api-test: add synthetic result parsing

Add some exports so the api test can inject results into the parser for
live queries, suppressing asking the server but otherwise following the
flow.

Provide two new suspect responses for injection and parsing in ctest.

Add a --cos option to minimal-http-client to force a close after the
connection has started the async dns.
This commit is contained in:
Andy Green 2021-10-17 06:20:58 +01:00
parent a51def06a1
commit a3592cbe4f
8 changed files with 212 additions and 17 deletions

View file

@ -40,11 +40,17 @@ typedef enum {
LADNS_RET_CONTINUING LADNS_RET_CONTINUING
} lws_async_dns_retcode_t; } lws_async_dns_retcode_t;
#define LWS_ADNS_SYNTHETIC 0x10000 /* don't send, synthetic response will
* be injected for testing */
struct addrinfo; struct addrinfo;
typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads, typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
const struct addrinfo *result, int n, void *opaque); const struct addrinfo *result, int n, void *opaque);
struct lws_adns_q;
struct lws_async_dns;
/** /**
* lws_async_dns_query() - perform a dns lookup using async dns * lws_async_dns_query() - perform a dns lookup using async dns
* *
@ -54,6 +60,7 @@ typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
* \param qtype: type of query (A, AAAA etc) * \param qtype: type of query (A, AAAA etc)
* \param cb: query completion callback * \param cb: query completion callback
* \param wsi: wsi if the query is related to one * \param wsi: wsi if the query is related to one
* \param pq: NULL, or pointer to lws_adns_q query (used for testing)
* *
* Starts an asynchronous DNS lookup, on completion the \p cb callback will * Starts an asynchronous DNS lookup, on completion the \p cb callback will
* be called. * be called.
@ -68,7 +75,7 @@ typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
LWS_VISIBLE LWS_EXTERN lws_async_dns_retcode_t LWS_VISIBLE LWS_EXTERN lws_async_dns_retcode_t
lws_async_dns_query(struct lws_context *context, int tsi, const char *name, lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
adns_query_type_t qtype, lws_async_dns_cb_t cb, adns_query_type_t qtype, lws_async_dns_cb_t cb,
struct lws *wsi, void *opaque); struct lws *wsi, void *opaque, struct lws_adns_q **pq);
/** /**
* lws_async_dns_freeaddrinfo() - decrement refcount on cached addrinfo results * lws_async_dns_freeaddrinfo() - decrement refcount on cached addrinfo results
@ -83,4 +90,14 @@ lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
LWS_VISIBLE LWS_EXTERN void LWS_VISIBLE LWS_EXTERN void
lws_async_dns_freeaddrinfo(const struct addrinfo **ai); lws_async_dns_freeaddrinfo(const struct addrinfo **ai);
/* only needed for testing */
LWS_VISIBLE LWS_EXTERN uint16_t
lws_adns_get_tid(struct lws_adns_q *q);
LWS_VISIBLE LWS_EXTERN struct lws_async_dns *
lws_adns_get_async_dns(struct lws_adns_q *q);
LWS_VISIBLE LWS_EXTERN void
lws_adns_parse_udp(struct lws_async_dns *dns, const uint8_t *pkt, size_t len);
#endif #endif

View file

@ -878,7 +878,7 @@ lws_create_adopt_udp(struct lws_vhost *vhost, const char *ads, int port,
n = lws_async_dns_query(vhost->context, 0, ads, n = lws_async_dns_query(vhost->context, 0, ads,
LWS_ADNS_RECORD_A, LWS_ADNS_RECORD_A,
lws_create_adopt_udp2, wsi, lws_create_adopt_udp2, wsi,
(void *)ifname); (void *)ifname, NULL);
// lwsl_notice("%s: dns query returned %d\n", __func__, n); // lwsl_notice("%s: dns query returned %d\n", __func__, n);
if (n == LADNS_RET_FAILED) { if (n == LADNS_RET_FAILED) {
lwsl_err("%s: async dns failed\n", __func__); lwsl_err("%s: async dns failed\n", __func__);

View file

@ -365,7 +365,7 @@ solo:
else else
n = lws_async_dns_query(wsi->a.context, wsi->tsi, adsin, n = lws_async_dns_query(wsi->a.context, wsi->tsi, adsin,
LWS_ADNS_RECORD_A, lws_client_connect_3_connect, LWS_ADNS_RECORD_A, lws_client_connect_3_connect,
wsi, NULL); wsi, NULL, NULL);
if (n == LADNS_RET_FAILED_WSI_CLOSED) if (n == LADNS_RET_FAILED_WSI_CLOSED)
return NULL; return NULL;

View file

@ -405,6 +405,7 @@ skip:
q->sent[1] = 0; q->sent[1] = 0;
#endif #endif
q->sent[0] = 0; q->sent[0] = 0;
q->is_synthetic = 0;
q->recursion++; q->recursion++;
if (q->recursion == DNS_RECURSION_LIMIT) { if (q->recursion == DNS_RECURSION_LIMIT) {
lwsl_err("%s: recursion overflow\n", __func__); lwsl_err("%s: recursion overflow\n", __func__);

View file

@ -314,6 +314,7 @@ callback_async_dns(struct lws *wsi, enum lws_callback_reasons reason,
list); list);
if (//lws_dll2_is_detached(&q->sul.list) && if (//lws_dll2_is_detached(&q->sul.list) &&
!q->is_synthetic &&
(!q->asked || q->responded != q->asked)) (!q->asked || q->responded != q->asked))
lws_async_dns_writeable(wsi, q); lws_async_dns_writeable(wsi, q);
} lws_end_foreach_dll_safe(d, d1); } lws_end_foreach_dll_safe(d, d1);
@ -563,6 +564,11 @@ lws_async_dns_deinit(lws_async_dns_t *dns)
} }
} }
void
lws_async_dns_detach_query_wsi(struct lws *wsi)
{
}
static int static int
cancel(struct lws_dll2 *d, void *user) cancel(struct lws_dll2 *d, void *user)
@ -574,6 +580,14 @@ cancel(struct lws_dll2 *d, void *user)
struct lws *w = lws_container_of(d3, struct lws, adns); struct lws *w = lws_container_of(d3, struct lws, adns);
if (user == w) { if (user == w) {
/*
* This is an ongoing query that our wsi was involved
* in... detach it from the query, and if nothing left
* interested in the query, destroy it.
*
* Since the wsi can only be running one query at a time
* currently, we can bail if we got a hit.
*/
lws_dll2_remove(d3); lws_dll2_remove(d3);
if (!q->wsi_adns.count) if (!q->wsi_adns.count)
lws_adns_q_destroy(q); lws_adns_q_destroy(q);
@ -584,6 +598,11 @@ cancel(struct lws_dll2 *d, void *user)
return 0; return 0;
} }
/*
* Let's go through all ongoing async dns queries, detaching wsi from any it
* is involved in, and destroying the query if that was the only consumer.
*/
void void
lws_async_dns_cancel(struct lws *wsi) lws_async_dns_cancel(struct lws *wsi)
{ {
@ -639,6 +658,19 @@ lws_async_dns_get_new_tid(struct lws_context *context, lws_adns_q_t *q)
return -1; return -1;
} }
uint16_t
lws_adns_get_tid(struct lws_adns_q *q)
{
return LADNS_MOST_RECENT_TID(q);
}
struct lws_async_dns *
lws_adns_get_async_dns(struct lws_adns_q *q)
{
return q->dns;
}
struct temp_q { struct temp_q {
lws_adns_q_t tq; lws_adns_q_t tq;
char name[48]; char name[48];
@ -647,7 +679,7 @@ struct temp_q {
lws_async_dns_retcode_t lws_async_dns_retcode_t
lws_async_dns_query(struct lws_context *context, int tsi, const char *name, lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
adns_query_type_t qtype, lws_async_dns_cb_t cb, adns_query_type_t qtype, lws_async_dns_cb_t cb,
struct lws *wsi, void *opaque) struct lws *wsi, void *opaque, struct lws_adns_q **pq)
{ {
lws_async_dns_t *dns = &context->async_dns; lws_async_dns_t *dns = &context->async_dns;
size_t nlen = strlen(name); size_t nlen = strlen(name);
@ -845,6 +877,8 @@ lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
lws_dll2_add_head(&wsi->adns, &q->wsi_adns); lws_dll2_add_head(&wsi->adns, &q->wsi_adns);
q->qtype = (uint16_t)qtype; q->qtype = (uint16_t)qtype;
if (qtype & LWS_ADNS_SYNTHETIC)
q->is_synthetic = 1;
if (lws_async_dns_get_new_tid(context, q)) { if (lws_async_dns_get_new_tid(context, q)) {
lwsl_cx_err(context, "tid fail"); lwsl_cx_err(context, "tid fail");
@ -852,6 +886,10 @@ lws_async_dns_query(struct lws_context *context, int tsi, const char *name,
} }
LADNS_MOST_RECENT_TID(q) &= 0xfffe; LADNS_MOST_RECENT_TID(q) &= 0xfffe;
if (pq)
*pq = q;
q->context = context; q->context = context;
q->tsi = (uint8_t)tsi; q->tsi = (uint8_t)tsi;
q->opaque = opaque; q->opaque = opaque;

View file

@ -53,7 +53,7 @@ typedef struct lws_adns_cache {
* these objects are used while a query is ongoing... * these objects are used while a query is ongoing...
*/ */
typedef struct { typedef struct lws_adns_q {
lws_sorted_usec_list_t sul; /* per-query write retry timer */ lws_sorted_usec_list_t sul; /* per-query write retry timer */
lws_sorted_usec_list_t write_sul; /* fail if unable to write by this time */ lws_sorted_usec_list_t write_sul; /* fail if unable to write by this time */
lws_dll2_t list; lws_dll2_t list;
@ -88,6 +88,7 @@ typedef struct {
uint8_t go_nogo; uint8_t go_nogo;
uint8_t is_retry:1; uint8_t is_retry:1;
uint8_t is_synthetic:1; /* test will deliver canned */
/* name overallocated here */ /* name overallocated here */
} lws_adns_q_t; } lws_adns_q_t;
@ -121,9 +122,6 @@ lws_async_dns_complete(lws_adns_q_t *q, lws_adns_cache_t *c);
lws_adns_cache_t * lws_adns_cache_t *
lws_adns_get_cache(lws_async_dns_t *dns, const char *name); lws_adns_get_cache(lws_async_dns_t *dns, const char *name);
void
lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len);
lws_adns_q_t * lws_adns_q_t *
lws_adns_get_query(lws_async_dns_t *dns, adns_query_type_t qtype, lws_adns_get_query(lws_async_dns_t *dns, adns_query_type_t qtype,
lws_dll2_owner_t *owner, uint16_t tid, const char *name); lws_dll2_owner_t *owner, uint16_t tid, const char *name);

View file

@ -12,7 +12,7 @@
#include <libwebsockets.h> #include <libwebsockets.h>
#include <signal.h> #include <signal.h>
static int interrupted, dtest, ok, fail, _exp = 26; static int interrupted, dtest, ok, fail, _exp = 33;
struct lws_context *context; struct lws_context *context;
/* /*
@ -67,12 +67,17 @@ static const struct ipparser_tests {
{ "1.2.3.4", 4, "1.2.3.4", 7, { 1, 2, 3, 4 } }, { "1.2.3.4", 4, "1.2.3.4", 7, { 1, 2, 3, 4 } },
}; };
#define TEST_FLAG_NOCHECK_RESULT_IP 0x100000
static const struct async_dns_tests { static const struct async_dns_tests {
const char *dns_name; const char *dns_name;
int recordtype; int recordtype;
int addrlen; int addrlen;
uint8_t ads[16]; uint8_t ads[16];
} adt[] = { } adt[] = {
{ "warmcat.com", LWS_ADNS_RECORD_A, 4,
{ 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
/* test coming from cache */
{ "warmcat.com", LWS_ADNS_RECORD_A, 4, { "warmcat.com", LWS_ADNS_RECORD_A, 4,
{ 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } }, { 46, 105, 127, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "libwebsockets.org", LWS_ADNS_RECORD_A, 4, { "libwebsockets.org", LWS_ADNS_RECORD_A, 4,
@ -93,17 +98,97 @@ static const struct async_dns_tests {
{ 0x20, 0x01, 0x41, 0xd0, 0x00, 0x02, 0xee, 0x93, { 0x20, 0x01, 0x41, 0xd0, 0x00, 0x02, 0xee, 0x93,
0, 0, 0, 0, 0, 0, 0, 1, } }, 0, 0, 0, 0, 0, 0, 0, 1, } },
#endif #endif
{ "c.msn.com", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 4,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "assets.msn.com", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 4,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "e28578.d.akamaiedge.net", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 0,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "a-0003.a-msedge.net", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 0,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "c-msn-com-europe-vip.trafficmanager.net", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 0,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
{ "c-msn-com-europe-vip.trafficmanager.net", TEST_FLAG_NOCHECK_RESULT_IP |
LWS_ADNS_SYNTHETIC | LWS_ADNS_RECORD_A, 0,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } },
}; };
static lws_sorted_usec_list_t sul; static uint8_t canned_c_msn_com[] = {
0x12, 0x34, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
0x00, 0x01, 0x00, 0x00, 0x01, 0x63, 0x03, 0x6D,
0x73, 0x6E, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00,
0x1C, 0x00, 0x01, 0xC0, 0x0C, 0x00, 0x05, 0x00,
0x01, 0x00, 0x00, 0x54, 0x5E, 0x00, 0x24, 0x0F,
0x63, 0x2D, 0x6D, 0x73, 0x6E, 0x2D, 0x63, 0x6F,
0x6D, 0x2D, 0x6E, 0x73, 0x61, 0x74, 0x63, 0x0E,
0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x6D,
0x61, 0x6E, 0x61, 0x67, 0x65, 0x72, 0x03, 0x6E,
0x65, 0x74, 0x00, 0xC0, 0x27, 0x00, 0x05, 0x00,
0x01, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x17, 0x14,
0x63, 0x2D, 0x6D, 0x73, 0x6E, 0x2D, 0x63, 0x6F,
0x6D, 0x2D, 0x65, 0x75, 0x72, 0x6F, 0x70, 0x65,
0x2D, 0x76, 0x69, 0x70, 0xC0, 0x37, 0xC0, 0x37,
0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C,
0x00, 0x2E, 0x03, 0x74, 0x6D, 0x31, 0x06, 0x64,
0x6E, 0x73, 0x2D, 0x74, 0x6D, 0xC0, 0x12, 0x0A,
0x68, 0x6F, 0x73, 0x74, 0x6D, 0x61, 0x73, 0x74,
0x65, 0x72, 0xC0, 0x37, 0x77, 0x64, 0x96, 0x60,
0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x01, 0x2C,
0x00, 0x24, 0xEA, 0x00, 0x00, 0x00, 0x00, 0x1E,
}, canned_assets_msn_com[] = {
219,29,129,128,0,1,0,2,0,1,0,0,6,97,115,115,101,116,115,3,109,115,
110,3,99,111,109,0,0,28,0,1,192,12,0,5,0,1,0,0,81,199,0,28,6,97,115,
115,101,116,115,3,109,115,110,3,99,111,109,7,101,100,103,101,107,101,
121,3,110,101,116,0,192,44,0,5,0,1,0,0,0,235,0,22,6,101,50,56,53,55,
56,1,100,10,97,107,97,109,97,105,101,100,103,101,192,67,192,91,0,6,
0,1,0,0,1,79,0,46,3,110,48,100,192,93,10,104,111,115,116,109,97,115,
116,101,114,6,97,107,97,109,97,105,192,23,97,106,246,231,0,0,3,232,0,
0,3,232,0,0,3,232,0,0,7,8,
}, canned_e28578_d_akamaiedge_net[] = {
20,191,129,128,0,1,0,0,0,1,0,0,6,101,50,56,53,55,56,1,100,10,97,107,97,
109,97,105,101,100,103,101,3,110,101,116,0,0,28,0,1,192,19,0,6,0,1,0,0,
1,17,0,49,3,110,48,100,192,21,10,104,111,115,116,109,97,115,116,101,114,
6,97,107,97,109,97,105,3,99,111,109,0,97,107,217,31,0,0,3,232,0,0,3,232,
0,0,3,232,0,0,7,8
}, canned_a_0003_a_msedge_net[] = {
126,215,129,128,0,1,0,0,0,1,0,0,6,97,45,48,48,48,51,8,97,45,109,115,101,
100,103,101,3,110,101,116,0,0,28,0,1,192,19,0,6,0,1,0,0,0,172,0,48,3,
110,115,49,192,19,6,109,115,110,104,115,116,9,109,105,99,114,111,115,
111,102,116,3,99,111,109,0,120,43,34,229,0,0,7,8,0,0,3,132,0,36,234,0,
0,0,0,240
}, canned_c_msn_com_europe_vip_trafficmanager_net[] = {
73,87,129,128,0,1,0,0,0,1,0,0,20,99,45,109,115,110,45,99,111,109,45,101,
117,114,111,112,101,45,118,105,112,14,116,114,97,102,102,105,99,109,97,
110,97,103,101,114,3,110,101,116,0,0,28,0,1,192,33,0,6,0,1,0,0,0,30,0,
49,3,116,109,49,6,100,110,115,45,116,109,3,99,111,109,0,10,104,111,115,
116,109,97,115,116,101,114,192,33,7,11,234,133,0,0,3,132,0,0,1,44,0,36,
234,0,0,0,0,30,
};
static lws_sorted_usec_list_t sul, sul_timeout;
struct lws * struct lws *
cb1(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n, cb1(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n,
void *opaque); void *opaque);
static int first = 1;
static void
timeout_cb(lws_sorted_usec_list_t *sul)
{
interrupted = 1;
lws_cancel_service(context);
}
static void static void
next_test_cb(lws_sorted_usec_list_t *sul) next_test_cb(lws_sorted_usec_list_t *sul)
{ {
struct lws_adns_q *q;
int m; int m;
lwsl_notice("%s: querying %s\n", __func__, adt[dtest].dns_name); lwsl_notice("%s: querying %s\n", __func__, adt[dtest].dns_name);
@ -111,11 +196,58 @@ next_test_cb(lws_sorted_usec_list_t *sul)
m = lws_async_dns_query(context, 0, m = lws_async_dns_query(context, 0,
adt[dtest].dns_name, adt[dtest].dns_name,
(adns_query_type_t)adt[dtest].recordtype, cb1, NULL, (adns_query_type_t)adt[dtest].recordtype, cb1, NULL,
context); context, &q);
if (m != LADNS_RET_CONTINUING && m != LADNS_RET_FOUND && m != LADNS_RET_FAILED_WSI_CLOSED) { if (m != LADNS_RET_CONTINUING && m != LADNS_RET_FOUND && m != LADNS_RET_FAILED_WSI_CLOSED) {
lwsl_err("%s: adns 1: %s failed: %d\n", __func__, adt[dtest].dns_name, m); lwsl_err("%s: adns 1: %s failed: %d\n", __func__, adt[dtest].dns_name, m);
interrupted = 1; interrupted = 1;
} }
if (adt[dtest].recordtype & LWS_ADNS_SYNTHETIC) {
lwsl_notice("%s: injecting result\n", __func__);
if (!strcmp(adt[dtest].dns_name, "c.msn.com")) {
canned_c_msn_com[0] = (uint8_t)(lws_adns_get_tid(q) >> 8);
canned_c_msn_com[1] = (uint8_t)lws_adns_get_tid(q);
lws_adns_parse_udp(lws_adns_get_async_dns(q),
canned_c_msn_com,
sizeof(canned_c_msn_com));
}
if (!strcmp(adt[dtest].dns_name, "assets.msn.com")) {
canned_assets_msn_com[0] = (uint8_t)(lws_adns_get_tid(q) >> 8);
canned_assets_msn_com[1] = (uint8_t)lws_adns_get_tid(q);
lws_adns_parse_udp(lws_adns_get_async_dns(q),
canned_assets_msn_com,
sizeof(canned_assets_msn_com));
}
if (!strcmp(adt[dtest].dns_name, "e28578.d.akamaiedge.net")) {
canned_e28578_d_akamaiedge_net[0] = (uint8_t)(lws_adns_get_tid(q) >> 8);
canned_e28578_d_akamaiedge_net[1] = (uint8_t)lws_adns_get_tid(q);
lws_adns_parse_udp(lws_adns_get_async_dns(q),
canned_e28578_d_akamaiedge_net,
sizeof(canned_e28578_d_akamaiedge_net));
}
if (!strcmp(adt[dtest].dns_name, "a-0003.a-msedge.net")) {
canned_a_0003_a_msedge_net[0] = (uint8_t)(lws_adns_get_tid(q) >> 8);
canned_a_0003_a_msedge_net[1] = (uint8_t)lws_adns_get_tid(q);
lws_adns_parse_udp(lws_adns_get_async_dns(q),
canned_a_0003_a_msedge_net,
sizeof(canned_a_0003_a_msedge_net));
}
if (first &&
!strcmp(adt[dtest].dns_name, "c-msn-com-europe-vip.trafficmanager.net")) {
first = 0;
canned_c_msn_com_europe_vip_trafficmanager_net[0] =
(uint8_t)(lws_adns_get_tid(q) >> 8);
canned_c_msn_com_europe_vip_trafficmanager_net[1] =
(uint8_t)lws_adns_get_tid(q);
lws_adns_parse_udp(lws_adns_get_async_dns(q),
canned_c_msn_com_europe_vip_trafficmanager_net,
sizeof(canned_c_msn_com_europe_vip_trafficmanager_net));
}
}
} }
struct lws * struct lws *
@ -167,8 +299,9 @@ cb1(struct lws *wsi_unused, const char *ads, const struct addrinfo *a, int n,
goto again; goto again;
#endif #endif
} }
if (alen == adt[dtest - 1].addrlen && if ((adt[dtest - 1].recordtype & TEST_FLAG_NOCHECK_RESULT_IP) ||
!memcmp(adt[dtest - 1].ads, addr, (unsigned int)alen)) { (alen == adt[dtest - 1].addrlen &&
!memcmp(adt[dtest - 1].ads, addr, (unsigned int)alen))) {
ok++; ok++;
goto next; goto next;
} }
@ -190,9 +323,10 @@ again:
next: next:
lws_async_dns_freeaddrinfo(&a); lws_async_dns_freeaddrinfo(&a);
if (dtest == (int)LWS_ARRAY_SIZE(adt)) if (dtest == (int)LWS_ARRAY_SIZE(adt)) {
interrupted = 1; interrupted = 1;
else lws_cancel_service(context);
} else
lws_sul_schedule(context, 0, &sul, next_test_cb, 1); lws_sul_schedule(context, 0, &sul, next_test_cb, 1);
return NULL; return NULL;
@ -225,7 +359,7 @@ sul_retry_l(struct lws_sorted_usec_list *sul)
m = lws_async_dns_query(context, 0, "warmcat.com", m = lws_async_dns_query(context, 0, "warmcat.com",
(adns_query_type_t)LWS_ADNS_RECORD_A, (adns_query_type_t)LWS_ADNS_RECORD_A,
cb_loop, NULL, context); cb_loop, NULL, context, NULL);
switch (m) { switch (m) {
case LADNS_RET_FAILED_WSI_CLOSED: case LADNS_RET_FAILED_WSI_CLOSED:
lwsl_warn("%s: LADNS_RET_FAILED_WSI_CLOSED " lwsl_warn("%s: LADNS_RET_FAILED_WSI_CLOSED "
@ -352,6 +486,7 @@ main(int argc, const char **argv)
/* kick off the async dns tests */ /* kick off the async dns tests */
lws_sul_schedule(context, 0, &sul, next_test_cb, 1); lws_sul_schedule(context, 0, &sul, next_test_cb, 1);
lws_sul_schedule(context, 0, &sul_timeout, timeout_cb, 45 * LWS_USEC_PER_SEC);
evloop: evloop:
/* the usual lws event loop */ /* the usual lws event loop */

View file

@ -16,7 +16,7 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
static int interrupted, bad = 1, status, conmon; static int interrupted, bad = 1, status, conmon, close_after_start;
#if defined(LWS_WITH_HTTP2) #if defined(LWS_WITH_HTTP2)
static int long_poll; static int long_poll;
#endif #endif
@ -332,6 +332,9 @@ system_notify_cb(lws_state_manager_t *mgr, lws_state_notify_link_t *link,
return 1; return 1;
} }
if (close_after_start)
lws_wsi_close(client_wsi, LWS_TO_KILL_SYNC);
return 0; return 0;
} }
@ -380,6 +383,9 @@ int main(int argc, const char **argv)
*/ */
info.fd_limit_per_thread = 1 + 1 + 1; info.fd_limit_per_thread = 1 + 1 + 1;
if (lws_cmdline_option(argc, argv, "--cos"))
close_after_start = 1;
#if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL) #if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL)
/* /*
* OpenSSL uses the system trust store. mbedTLS has to be told which * OpenSSL uses the system trust store. mbedTLS has to be told which