1 /* Copyright (c) 2014, Vsevolod Stakhov 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution. 11 * 12 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY 13 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY 16 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 17 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 18 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 19 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 21 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 */ 23 24 #ifndef DNS_PRIVATE_H_ 25 #define DNS_PRIVATE_H_ 26 27 #include "config.h" 28 #include "uthash.h" 29 #include "utlist.h" 30 #include "rdns.h" 31 #include "upstream.h" 32 #include "ref.h" 33 34 static const int dns_port = 53; 35 static const int default_io_cnt = 8; 36 37 #define UDP_PACKET_SIZE 4096 38 39 #define DNS_COMPRESSION_BITS 0xC0 40 41 #define DNS_D_MAXLABEL 63 /* + 1 '\0' */ 42 #define DNS_D_MAXNAME 255 /* + 1 '\0' */ 43 44 #define RESOLV_CONF "/etc/resolv.conf" 45 46 /** 47 * Represents DNS server 48 */ 49 struct rdns_server { 50 char *name; 51 unsigned int port; 52 unsigned int io_cnt; 53 54 struct rdns_io_channel **io_channels; 55 void *ups_elt; 56 upstream_entry_t up; 57 }; 58 59 enum rdns_request_state { 60 RDNS_REQUEST_NEW = 0, 61 RDNS_REQUEST_REGISTERED = 1, 62 RDNS_REQUEST_WAIT_SEND, 63 RDNS_REQUEST_WAIT_REPLY, 64 RDNS_REQUEST_REPLIED, 65 RDNS_REQUEST_FAKE, 66 }; 67 68 struct rdns_request { 69 struct rdns_resolver *resolver; 70 struct rdns_async_context *async; 71 struct rdns_io_channel *io; 72 struct rdns_reply *reply; 73 enum rdns_request_type type; 74 75 double timeout; 76 unsigned int retransmits; 77 78 int id; 79 struct rdns_request_name *requested_names; 80 unsigned int qcount; 81 enum rdns_request_state state; 82 83 uint8_t *packet; 84 off_t pos; 85 unsigned int packet_len; 86 87 dns_callback_type func; 88 void *arg; 89 90 void *async_event; 91 92 #if defined(TWEETNACL) || defined(USE_RSPAMD_CRYPTOBOX) 93 void *curve_plugin_data; 94 #endif 95 96 UT_hash_handle hh; 97 ref_entry_t ref; 98 }; 99 100 101 /** 102 * IO channel for a specific DNS server 103 */ 104 struct rdns_io_channel { 105 struct rdns_server *srv; 106 struct rdns_resolver *resolver; 107 struct sockaddr *saddr; 108 socklen_t slen; 109 int sock; /**< persistent socket */ 110 bool active; 111 bool connected; 112 void *async_io; /** async opaque ptr */ 113 struct rdns_request *requests; /**< requests in flight */ 114 uint64_t uses; 115 ref_entry_t ref; 116 }; 117 118 struct rdns_fake_reply_idx { 119 enum rdns_request_type type; 120 unsigned len; 121 char request[0]; 122 }; 123 124 struct rdns_fake_reply { 125 enum dns_rcode rcode; 126 struct rdns_reply_entry *result; 127 UT_hash_handle hh; 128 struct rdns_fake_reply_idx key; 129 }; 130 131 132 struct rdns_resolver { 133 struct rdns_server *servers; 134 struct rdns_io_channel *io_channels; /**< hash of io chains indexed by socket */ 135 struct rdns_async_context *async; /** async callbacks */ 136 void *periodic; /** periodic event for resolver */ 137 struct rdns_upstream_context *ups; 138 struct rdns_plugin *curve_plugin; 139 struct rdns_fake_reply *fake_elts; 140 141 #ifdef __GNUC__ 142 __attribute__((format(printf, 4, 0))) 143 #endif 144 rdns_log_function logger; 145 void *log_data; 146 enum rdns_log_level log_level; 147 148 uint64_t max_ioc_uses; 149 void *refresh_ioc_periodic; 150 151 bool async_binded; 152 bool initialized; 153 bool enable_dnssec; 154 int flags; 155 ref_entry_t ref; 156 }; 157 158 struct dns_header; 159 struct dns_query; 160 161 /* Internal DNS structs */ 162 163 struct dns_header { 164 unsigned int qid :16; 165 166 #if BYTE_ORDER == BIG_ENDIAN 167 unsigned int qr:1; 168 unsigned int opcode:4; 169 unsigned int aa:1; 170 unsigned int tc:1; 171 unsigned int rd:1; 172 173 unsigned int ra:1; 174 unsigned int cd : 1; 175 unsigned int ad : 1; 176 unsigned int z : 1; 177 unsigned int rcode:4; 178 #else 179 unsigned int rd :1; 180 unsigned int tc :1; 181 unsigned int aa :1; 182 unsigned int opcode :4; 183 unsigned int qr :1; 184 185 unsigned int rcode :4; 186 unsigned int z : 1; 187 unsigned int ad : 1; 188 unsigned int cd : 1; 189 unsigned int ra :1; 190 #endif 191 192 unsigned int qdcount :16; 193 unsigned int ancount :16; 194 unsigned int nscount :16; 195 unsigned int arcount :16; 196 }; 197 198 enum dns_section { 199 DNS_S_QD = 0x01, 200 #define DNS_S_QUESTION DNS_S_QD 201 202 DNS_S_AN = 0x02, 203 #define DNS_S_ANSWER DNS_S_AN 204 205 DNS_S_NS = 0x04, 206 #define DNS_S_AUTHORITY DNS_S_NS 207 208 DNS_S_AR = 0x08, 209 #define DNS_S_ADDITIONAL DNS_S_AR 210 211 DNS_S_ALL = 0x0f 212 }; 213 /* enum dns_section */ 214 215 enum dns_opcode { 216 DNS_OP_QUERY = 0, 217 DNS_OP_IQUERY = 1, 218 DNS_OP_STATUS = 2, 219 DNS_OP_NOTIFY = 4, 220 DNS_OP_UPDATE = 5, 221 }; 222 /* dns_opcode */ 223 224 enum dns_class { 225 DNS_C_IN = 1, 226 227 DNS_C_ANY = 255 228 }; 229 /* enum dns_class */ 230 231 struct dns_query { 232 char *qname; 233 unsigned int qtype :16; 234 unsigned int qclass :16; 235 }; 236 237 enum dns_type { 238 DNS_T_A = RDNS_REQUEST_A, 239 DNS_T_NS = RDNS_REQUEST_NS, 240 DNS_T_CNAME = 5, 241 DNS_T_SOA = RDNS_REQUEST_SOA, 242 DNS_T_PTR = RDNS_REQUEST_PTR, 243 DNS_T_MX = RDNS_REQUEST_MX, 244 DNS_T_TXT = RDNS_REQUEST_TXT, 245 DNS_T_AAAA = RDNS_REQUEST_AAAA, 246 DNS_T_SRV = RDNS_REQUEST_SRV, 247 DNS_T_OPT = 41, 248 DNS_T_SSHFP = 44, 249 DNS_T_TLSA = RDNS_REQUEST_TLSA, 250 DNS_T_SPF = RDNS_REQUEST_SPF, 251 DNS_T_ALL = RDNS_REQUEST_ANY 252 }; 253 /* enum dns_type */ 254 255 static const char dns_rcodes[][32] = { 256 [RDNS_RC_NOERROR] = "no error", 257 [RDNS_RC_FORMERR] = "query format error", 258 [RDNS_RC_SERVFAIL] = "server fail", 259 [RDNS_RC_NXDOMAIN] = "no records with this name", 260 [RDNS_RC_NOTIMP] = "not implemented", 261 [RDNS_RC_REFUSED] = "query refused", 262 [RDNS_RC_YXDOMAIN] = "YXDOMAIN", 263 [RDNS_RC_YXRRSET] = "YXRRSET", 264 [RDNS_RC_NXRRSET] = "NXRRSET", 265 [RDNS_RC_NOTAUTH] = "not authorized", 266 [RDNS_RC_NOTZONE] = "no such zone", 267 [RDNS_RC_TIMEOUT] = "query timed out", 268 [RDNS_RC_NETERR] = "network error", 269 [RDNS_RC_NOREC] = "requested record is not found" 270 }; 271 272 static const char dns_types[][16] = { 273 [RDNS_REQUEST_A] = "A request", 274 [RDNS_REQUEST_NS] = "NS request", 275 [RDNS_REQUEST_PTR] = "PTR request", 276 [RDNS_REQUEST_MX] = "MX request", 277 [RDNS_REQUEST_TXT] = "TXT request", 278 [RDNS_REQUEST_SRV] = "SRV request", 279 [RDNS_REQUEST_SPF] = "SPF request", 280 [RDNS_REQUEST_AAAA] = "AAAA request", 281 [RDNS_REQUEST_TLSA] = "TLSA request", 282 [RDNS_REQUEST_ANY] = "ANY request" 283 }; 284 285 286 #endif /* DNS_PRIVATE_H_ */ 287