1 /* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25 26 #define DNS_MAX 96 /* Maximum host name */ 27 #define DNS_RECURSION_LIMIT 3 28 #define DNS_PACKET_LEN 1400 /* Buffer size for DNS packet */ 29 #define MAX_CACHE_ENTRIES 10 /* Dont cache more than that */ 30 #define DNS_QUERY_TIMEOUT 30 /* Query timeout, seconds */ 31 32 /* 33 * ... when we completed a query then the query object is destroyed and a 34 * cache object below is created with the results in getaddrinfo format 35 * appended to the allocation 36 */ 37 38 typedef struct lws_adns_cache { 39 lws_sorted_usec_list_t sul; /* for cache TTL management */ 40 lws_dll2_t list; 41 42 struct lws_adns_cache *firstcache; 43 struct lws_adns_cache *chain; 44 struct addrinfo *results; 45 const char *name; 46 uint8_t flags; /* b0 = has ipv4, b1 = has ipv6 */ 47 char refcount; 48 char incomplete; 49 /* addrinfo, lws_sa46, then name overallocated here */ 50 } lws_adns_cache_t; 51 52 /* 53 * these objects are used while a query is ongoing... 54 */ 55 56 typedef struct { 57 lws_sorted_usec_list_t sul; /* per-query write retry timer */ 58 lws_sorted_usec_list_t write_sul; /* fail if unable to write by this time */ 59 lws_dll2_t list; 60 61 lws_metrics_caliper_compose(metcal) 62 63 lws_dll2_owner_t wsi_adns; 64 lws_async_dns_cb_t standalone_cb; /* if not associated to wsi */ 65 struct lws_context *context; 66 void *opaque; 67 struct addrinfo **last; 68 lws_async_dns_t *dns; 69 70 lws_adns_cache_t *firstcache; 71 72 lws_async_dns_retcode_t ret; 73 uint16_t tid[3]; /* last 3 sent tid */ 74 uint16_t qtype; 75 uint16_t retry; 76 uint8_t tsi; 77 78 #if defined(LWS_WITH_IPV6) 79 uint8_t sent[2]; 80 #else 81 uint8_t sent[1]; 82 #endif 83 uint8_t asked; 84 uint8_t responded; 85 86 uint8_t recursion; 87 uint8_t tids; 88 uint8_t go_nogo; 89 90 uint8_t is_retry:1; 91 92 /* name overallocated here */ 93 } lws_adns_q_t; 94 95 #define LADNS_MOST_RECENT_TID(_q) \ 96 q->tid[(int)(_q->tids - 1) % (int)LWS_ARRAY_SIZE(q->tid)] 97 98 enum { 99 DHO_TID, 100 DHO_FLAGS = 2, 101 DHO_NQUERIES = 4, 102 DHO_NANSWERS = 6, 103 DHO_NAUTH = 8, 104 DHO_NOTHER = 10, 105 106 DHO_SIZEOF = 12 /* last */ 107 }; 108 109 void 110 lws_adns_q_destroy(lws_adns_q_t *q); 111 112 void 113 sul_cb_expire(struct lws_sorted_usec_list *sul); 114 115 void 116 lws_adns_cache_destroy(lws_adns_cache_t *c); 117 118 int 119 lws_async_dns_complete(lws_adns_q_t *q, lws_adns_cache_t *c); 120 121 lws_adns_cache_t * 122 lws_adns_get_cache(lws_async_dns_t *dns, const char *name); 123 124 void 125 lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len); 126 127 lws_adns_q_t * 128 lws_adns_get_query(lws_async_dns_t *dns, adns_query_type_t qtype, 129 lws_dll2_owner_t *owner, uint16_t tid, const char *name); 130 131 void 132 lws_async_dns_trim_cache(lws_async_dns_t *dns); 133 134 int 135 lws_async_dns_get_new_tid(struct lws_context *context, lws_adns_q_t *q); 136 137 138 #if defined(_DEBUG) 139 void 140 lws_adns_dump(lws_async_dns_t *dns); 141 #else 142 #define lws_adns_dump(_d) 143 #endif 144