Skip to content

Commit 4907ab7

Browse files
committed
adns: multi server broadside
This changes the approach of Async DNS vs multiple DNS servers... - we will take all the platform tells us about - initially we will broadside the queries on all the servers - we'll measure the response performce over time, with decay - nonresponsive servers will get ignored and responsive ones will round-robin
1 parent 7bb9268 commit 4907ab7

File tree

9 files changed

+148
-107
lines changed

9 files changed

+148
-107
lines changed

READMEs/README.async-dns.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ Other features
3838
- Uses CNAME resolution inside the same response if present, otherwise
3939
recurses to resolve the CNAME (up to 3 deep)
4040
- ipv6 pieces only built if cmake `LWS_IPV6` enabled
41+
- **Multi-server support**: automatically parses multiple nameservers from `/etc/resolv.conf`.
42+
- **Adaptive server selection**: tracks DNS server response latencies using exponential weighted moving averages.
43+
- **Parallel broadsiding**: initially sends queries to all configured servers simultaneously to determine the fastest responder.
44+
- **Round-robin fallback**: utilizes the fastest server for subsequent queries or round-robins between equally performant servers.
4145

4246
## Api
4347

include/libwebsockets/lws-async-dns.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ typedef struct lws * (*lws_async_dns_cb_t)(struct lws *wsi, const char *ads,
6666

6767
struct lws_adns_q;
6868
struct lws_async_dns;
69+
struct lws_async_dns_server;
6970

7071
/**
7172
* lws_async_dns_query() - perform a dns lookup using async dns
@@ -156,8 +157,12 @@ lws_adns_get_tid(struct lws_adns_q *q);
156157
LWS_VISIBLE LWS_EXTERN struct lws_async_dns *
157158
lws_adns_get_async_dns(struct lws_adns_q *q);
158159

160+
LWS_VISIBLE LWS_EXTERN struct lws_async_dns_server *
161+
lws_adns_get_server(struct lws_adns_q *q);
162+
159163
LWS_VISIBLE LWS_EXTERN void
160-
lws_adns_parse_udp(struct lws_async_dns *dns, const uint8_t *pkt, size_t len);
164+
lws_adns_parse_udp(struct lws_async_dns *dns, const uint8_t *pkt, size_t len,
165+
struct lws_async_dns_server *dsrv);
161166

162167
/**
163168
* lws_plat_asyncdns_get_server() - Get system DNS server address

lib/core-net/private-lib-core-net.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,9 @@ typedef struct lws_async_dns_server {
251251
lws_dll2_t list;
252252
lws_sockaddr46 sa46; /* nameserver */
253253

254-
lws_dll2_owner_t waiting;
254+
struct lws_adapt *adapt; /* tracks ping latency */
255+
lws_usec_t last_queried_us;
256+
lws_usec_t last_responded_us;
255257

256258
int refcount;
257259

@@ -264,6 +266,7 @@ typedef struct lws_async_dns_server {
264266
typedef struct lws_async_dns {
265267
lws_dll2_owner_t nameservers; /* lws_async_dns_server_t */
266268
lws_dll2_owner_t cached;
269+
lws_dll2_owner_t waiting; /* queries waiting for a server */
267270

268271
struct lws_context *cx;
269272

lib/system/async-dns/async-dns-parse.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ lws_adns_parse_label(const uint8_t *pkt, int len, const uint8_t *ls, int budget,
134134
* it has no 00 terminator afterwards
135135
*/
136136

137-
return consumed;
137+
return consumed;
138138
}
139139

140140

@@ -607,7 +607,8 @@ lws_async_dns_store(const char *name, void *opaque, uint32_t ttl,
607607
*/
608608

609609
void
610-
lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len)
610+
lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len,
611+
lws_async_dns_server_t *dsrv)
611612
{
612613
const char *nm, *nmcname;
613614
lws_adns_cache_t *c;
@@ -665,6 +666,14 @@ lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len)
665666
return;
666667
}
667668

669+
if (dsrv && q->broadsiding && q->issue_time) {
670+
/* Record response time for the server that won the race! */
671+
lws_adapt_report_val(dsrv->adapt, (uint64_t)(lws_now_usecs() - q->issue_time), lws_now_usecs());
672+
} else if (q->dsrv && q->issue_time) {
673+
/* Record response time for the pre-selected server */
674+
lws_adapt_report_val(q->dsrv->adapt, (uint64_t)(lws_now_usecs() - q->issue_time), lws_now_usecs());
675+
}
676+
668677
q->responded = (uint8_t)(q->responded | n);
669678

670679
/* did we get truncated? */
@@ -834,6 +843,7 @@ lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len)
834843
* addrinfo results, if any, to all interested wsi, if any...
835844
*/
836845

846+
lwsl_notice("%s: Calling lws_async_dns_complete for %s\n", __func__, q->firstcache ? q->firstcache->name : "NULL");
837847
c->incomplete = 0;
838848
lws_async_dns_complete(q, q->firstcache);
839849

0 commit comments

Comments
 (0)