1 /* 2 * include/types/dns.h 3 * This file provides structures and types for DNS. 4 * 5 * Copyright (C) 2014 Baptiste Assmann <bedis9@gmail.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation, version 2.1 10 * exclusively. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22 #ifndef _TYPES_DNS_H 23 #define _TYPES_DNS_H 24 25 /*DNS maximum values */ 26 /* 27 * Maximum issued from RFC: 28 * RFC 1035: https://www.ietf.org/rfc/rfc1035.txt chapter 2.3.4 29 * RFC 2671: http://tools.ietf.org/html/rfc2671 30 */ 31 #define DNS_MAX_LABEL_SIZE 63 32 #define DNS_MAX_NAME_SIZE 255 33 #define DNS_MAX_UDP_MESSAGE 512 34 35 /* DNS minimun record size: 1 char + 1 NULL + type + class */ 36 #define DNS_MIN_RECORD_SIZE ( 1 + 1 + 2 + 2 ) 37 38 /* maximum number of query records in a DNS response 39 * For now, we allow only one */ 40 #define DNS_MAX_QUERY_RECORDS 1 41 42 /* maximum number of answer record in a DNS response */ 43 #define DNS_MAX_ANSWER_RECORDS ((DNS_MAX_UDP_MESSAGE - DNS_HEADER_SIZE) / DNS_MIN_RECORD_SIZE) 44 45 /* size of dns_buffer used to store responses from the buffer 46 * dns_buffer is used to store data collected from records found in a response. 47 * Before using it, caller will always check that there is at least DNS_MAX_NAME_SIZE bytes 48 * available */ 49 #define DNS_ANALYZE_BUFFER_SIZE DNS_MAX_UDP_MESSAGE + DNS_MAX_NAME_SIZE 50 51 /* DNS error messages */ 52 #define DNS_TOO_LONG_FQDN "hostname too long" 53 #define DNS_LABEL_TOO_LONG "one label too long" 54 #define DNS_INVALID_CHARACTER "found an invalid character" 55 56 /* dns query class */ 57 #define DNS_RCLASS_IN 1 /* internet class */ 58 59 /* dns record types (non exhaustive list) */ 60 #define DNS_RTYPE_A 1 /* IPv4 address */ 61 #define DNS_RTYPE_CNAME 5 /* canonical name */ 62 #define DNS_RTYPE_AAAA 28 /* IPv6 address */ 63 #define DNS_RTYPE_ANY 255 /* all records */ 64 65 /* dns rcode values */ 66 #define DNS_RCODE_NO_ERROR 0 /* no error */ 67 #define DNS_RCODE_NX_DOMAIN 3 /* non existent domain */ 68 #define DNS_RCODE_REFUSED 5 /* query refused */ 69 70 /* dns flags masks */ 71 #define DNS_FLAG_TRUNCATED 0x0200 /* mask for truncated flag */ 72 #define DNS_FLAG_REPLYCODE 0x000F /* mask for reply code */ 73 74 /* max number of network preference entries are avalaible from the 75 * configuration file. 76 */ 77 #define SRV_MAX_PREF_NET 5 78 79 /* DNS header size */ 80 #define DNS_HEADER_SIZE sizeof(struct dns_header) 81 82 /* DNS request or response header structure */ 83 struct dns_header { 84 uint16_t id; 85 uint16_t flags; 86 uint16_t qdcount; 87 uint16_t ancount; 88 uint16_t nscount; 89 uint16_t arcount; 90 } __attribute__ ((packed)); 91 92 /* short structure to describe a DNS question */ 93 /* NOTE: big endian structure */ 94 struct dns_question { 95 unsigned short qtype; /* question type */ 96 unsigned short qclass; /* query class */ 97 }; 98 99 /* NOTE: big endian structure */ 100 struct dns_query_item { 101 struct list list; 102 char name[DNS_MAX_NAME_SIZE]; /* query name */ 103 unsigned short type; /* question type */ 104 unsigned short class; /* query class */ 105 }; 106 107 /* NOTE: big endian structure */ 108 struct dns_answer_item { 109 struct list list; 110 char *name; /* answer name 111 * For SRV type, name also includes service 112 * and protocol value */ 113 int16_t type; /* question type */ 114 int16_t class; /* query class */ 115 int32_t ttl; /* response TTL */ 116 int16_t priority; /* SRV type priority */ 117 int16_t weight; /* SRV type weight */ 118 int16_t port; /* SRV type port */ 119 uint16_t data_len; /* number of bytes in target below */ 120 struct sockaddr address; /* IPv4 or IPv6, network format */ 121 char *target; /* Response data: SRV or CNAME type target */ 122 }; 123 124 struct dns_response_packet { 125 struct dns_header header; 126 struct list query_list; 127 struct list answer_list; 128 /* authority and additional_information ignored for now */ 129 }; 130 131 /* 132 * resolvers section and parameters. It is linked to the name servers 133 * servers points to it. 134 * current resolution are stored in a FIFO list. 135 */ 136 struct dns_resolvers { 137 struct list list; /* resolvers list */ 138 char *id; /* resolvers unique identifier */ 139 struct { 140 const char *file; /* file where the section appears */ 141 int line; /* line where the section appears */ 142 } conf; /* config information */ 143 struct list nameserver_list; /* dns server list */ 144 int count_nameservers; /* total number of nameservers in a resolvers section */ 145 int resolve_retries; /* number of retries before giving up */ 146 struct { /* time to: */ 147 int retry; /* wait for a response before retrying */ 148 } timeout; 149 struct { /* time to hold current data when */ 150 int valid; /* a response is valid */ 151 int nx; /* a response doesn't exist */ 152 int timeout; /* no answer was delivered */ 153 int refused; /* dns server refused to answer */ 154 int other; /* other dns response errors */ 155 } hold; 156 struct task *t; /* timeout management */ 157 struct list curr_resolution; /* current running resolutions */ 158 struct eb_root query_ids; /* tree to quickly lookup/retrieve query ids currently in use */ 159 /* used by each nameserver, but stored in resolvers since there must */ 160 /* be a unique relation between an eb_root and an eb_node (resolution) */ 161 }; 162 163 /* 164 * structure describing a name server used during name resolution. 165 * A name server belongs to a resolvers section. 166 */ 167 struct dns_nameserver { 168 struct list list; /* nameserver chained list */ 169 char *id; /* nameserver unique identifier */ 170 struct { 171 const char *file; /* file where the section appears */ 172 int line; /* line where the section appears */ 173 } conf; /* config information */ 174 struct dns_resolvers *resolvers; 175 struct dgram_conn *dgram; /* transport layer */ 176 struct sockaddr_storage addr; /* IP address */ 177 struct { /* numbers relted to this name server: */ 178 long int sent; /* - queries sent */ 179 long int valid; /* - valid response */ 180 long int update; /* - valid response used to update server's IP */ 181 long int cname; /* - CNAME response requiring new resolution */ 182 long int cname_error; /* - error when resolving CNAMEs */ 183 long int any_err; /* - void response (usually because ANY qtype) */ 184 long int nx; /* - NX response */ 185 long int timeout; /* - queries which reached timeout */ 186 long int refused; /* - queries refused */ 187 long int other; /* - other type of response */ 188 long int invalid; /* - malformed DNS response */ 189 long int too_big; /* - too big response */ 190 long int outdated; /* - outdated response (server slower than the other ones) */ 191 long int truncated; /* - truncated response */ 192 } counters; 193 }; 194 195 struct dns_options { 196 int family_prio; /* which IP family should the resolver use when both are returned */ 197 struct { 198 int family; 199 union { 200 struct in_addr in4; 201 struct in6_addr in6; 202 } addr; 203 union { 204 struct in_addr in4; 205 struct in6_addr in6; 206 } mask; 207 } pref_net[SRV_MAX_PREF_NET]; 208 int pref_net_nb; /* The number of registered prefered networks. */ 209 }; 210 211 /* 212 * resolution structure associated to single server and used to manage name resolution for 213 * this server. 214 * The only link between the resolution and a nameserver is through the query_id. 215 */ 216 struct dns_resolution { 217 struct list list; /* resolution list */ 218 struct dns_resolvers *resolvers; /* resolvers section associated to this resolution */ 219 void *requester; /* owner of this name resolution */ 220 int (*requester_cb)(struct dns_resolution *, struct dns_nameserver *, struct dns_response_packet *); 221 /* requester callback for valid response */ 222 int (*requester_error_cb)(struct dns_resolution *, int); 223 /* requester callback, for error management */ 224 char *hostname_dn; /* server hostname in domain name label format */ 225 int hostname_dn_len; /* server domain name label len */ 226 struct dns_options *opts; /* IP selection options inherited from the configuration file. */ 227 unsigned int last_resolution; /* time of the lastest valid resolution */ 228 unsigned int last_sent_packet; /* time of the latest DNS packet sent */ 229 unsigned int last_status_change; /* time of the latest DNS resolution status change */ 230 int query_id; /* DNS query ID dedicated for this resolution */ 231 struct eb32_node qid; /* ebtree query id */ 232 int query_type; 233 /* query type to send. By default DNS_RTYPE_A or DNS_RTYPE_AAAA depending on resolver_family_priority */ 234 int status; /* status of the resolution being processed RSLV_STATUS_* */ 235 int step; /* */ 236 int try; /* current resolution try */ 237 int try_cname; /* number of CNAME requests sent */ 238 int nb_responses; /* count number of responses received */ 239 }; 240 241 /* last resolution status code */ 242 enum { 243 RSLV_STATUS_NONE = 0, /* no resolution occured yet */ 244 RSLV_STATUS_VALID, /* no error */ 245 RSLV_STATUS_INVALID, /* invalid responses */ 246 RSLV_STATUS_ERROR, /* error */ 247 RSLV_STATUS_NX, /* NXDOMAIN */ 248 RSLV_STATUS_REFUSED, /* server refused our query */ 249 RSLV_STATUS_TIMEOUT, /* no response from DNS servers */ 250 RSLV_STATUS_OTHER, /* other errors */ 251 }; 252 253 /* current resolution step */ 254 enum { 255 RSLV_STEP_NONE = 0, /* nothing happening currently */ 256 RSLV_STEP_RUNNING, /* resolution is running */ 257 }; 258 259 /* return codes after analyzing a DNS response */ 260 enum { 261 DNS_RESP_VALID = 0, /* valid response */ 262 DNS_RESP_INVALID, /* invalid response (various type of errors can trigger it) */ 263 DNS_RESP_ERROR, /* DNS error code */ 264 DNS_RESP_NX_DOMAIN, /* resolution unsuccessful */ 265 DNS_RESP_REFUSED, /* DNS server refused to answer */ 266 DNS_RESP_ANCOUNT_ZERO, /* no answers in the response */ 267 DNS_RESP_WRONG_NAME, /* response does not match query name */ 268 DNS_RESP_CNAME_ERROR, /* error when resolving a CNAME in an atomic response */ 269 DNS_RESP_TIMEOUT, /* DNS server has not answered in time */ 270 DNS_RESP_TRUNCATED, /* DNS response is truncated */ 271 DNS_RESP_NO_EXPECTED_RECORD, /* No expected records were found in the response */ 272 DNS_RESP_QUERY_COUNT_ERROR, /* we did not get the expected number of queries in the response */ 273 }; 274 275 /* return codes after searching an IP in a DNS response buffer, using a family preference */ 276 enum { 277 DNS_UPD_NO = 1, /* provided IP was found and preference is matched 278 * OR provided IP found and preference is not matched, but no IP 279 * matching preference was found */ 280 DNS_UPD_SRVIP_NOT_FOUND, /* provided IP not found 281 * OR provided IP found and preference is not match and an IP 282 * matching preference was found */ 283 DNS_UPD_CNAME, /* CNAME without any IP provided in the response */ 284 DNS_UPD_NAME_ERROR, /* name in the response did not match the query */ 285 DNS_UPD_NO_IP_FOUND, /* no IP could be found in the response */ 286 }; 287 288 #endif /* _TYPES_DNS_H */ 289