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 uint8_t flags; /* b0 = has ipv4, b1 = has ipv6 */ 46 char refcount; 47 char incomplete; 48 /* name, and then result struct addrinfos overallocated here */ 49 } lws_adns_cache_t; 50 51 /* 52 * these objects are used while a query is ongoing... 53 */ 54 55 typedef struct { 56 lws_sorted_usec_list_t sul; /* per-query write retry timer */ 57 lws_dll2_t list; 58 59 lws_dll2_owner_t wsi_adns; 60 lws_async_dns_cb_t standalone_cb; /* if not associated to wsi */ 61 struct lws_context *context; 62 void *opaque; 63 struct addrinfo **last; 64 lws_async_dns_t *dns; 65 66 lws_adns_cache_t *firstcache; 67 68 lws_async_dns_retcode_t ret; 69 uint16_t tid; 70 uint16_t qtype; 71 uint16_t retry; 72 uint8_t tsi; 73 74 #if defined(LWS_WITH_IPV6) 75 uint8_t sent[2]; 76 #else 77 uint8_t sent[1]; 78 #endif 79 uint8_t asked; 80 uint8_t responded; 81 82 uint8_t recursion; 83 84 /* name overallocated here */ 85 } lws_adns_q_t; 86 87 enum { 88 DHO_TID, 89 DHO_FLAGS = 2, 90 DHO_NQUERIES = 4, 91 DHO_NANSWERS = 6, 92 DHO_NAUTH = 8, 93 DHO_NOTHER = 10, 94 95 DHO_SIZEOF = 12 /* last */ 96 }; 97 98 void 99 lws_adns_q_destroy(lws_adns_q_t *q); 100 101 void 102 sul_cb_expire(struct lws_sorted_usec_list *sul); 103 104 void 105 lws_adns_cache_destroy(lws_adns_cache_t *c); 106 107 int 108 lws_async_dns_complete(lws_adns_q_t *q, lws_adns_cache_t *c); 109 110 lws_adns_cache_t * 111 lws_adns_get_cache(lws_async_dns_t *dns, const char *name); 112 113 void 114 lws_adns_parse_udp(lws_async_dns_t *dns, const uint8_t *pkt, size_t len); 115 116 lws_adns_q_t * 117 lws_adns_get_query(lws_async_dns_t *dns, adns_query_type_t qtype, 118 lws_dll2_owner_t *owner, uint16_t tid, const char *name); 119 120 void 121 lws_async_dns_trim_cache(lws_async_dns_t *dns); 122 123 int 124 lws_async_dns_get_new_tid(struct lws_context *context, lws_adns_q_t *q); 125