1968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 2968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* Copyright 1998 by the Massachusetts Institute of Technology. 3968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 4968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Permission to use, copy, modify, and distribute this 5968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software and its documentation for any purpose and without 6968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * fee is hereby granted, provided that the above copyright 7968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice appear in all copies and that both that copyright 8968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice and this permission notice appear in supporting 9968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * documentation, and that the name of M.I.T. not be used in 10968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * advertising or publicity pertaining to distribution of the 11968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software without specific, written prior permission. 12968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * M.I.T. makes no representations about the suitability of 13968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * this software for any purpose. It is provided "as is" 14968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * without express or implied warranty. 15968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */ 16968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 17968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_setup.h" 18968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 19968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_SYS_SOCKET_H 20968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold# include <sys/socket.h> 21968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif 22968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_NETINET_IN_H 23968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold# include <netinet/in.h> 24968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif 25968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_H 26968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold# include <arpa/nameser.h> 27968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#else 28968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold# include "nameser.h" 29968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif 30968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_ARPA_NAMESER_COMPAT_H 31968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold# include <arpa/nameser_compat.h> 32968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif 33968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 34968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <stdlib.h> 35968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <string.h> 36968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares.h" 37968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_dns.h" 38968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_private.h" 39968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 40968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* Header format, from RFC 1035: 41968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 1 1 1 1 1 1 42968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 43968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 44968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | ID | 45968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 46968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * |QR| Opcode |AA|TC|RD|RA| Z | RCODE | 47968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 48968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | QDCOUNT | 49968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 50968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | ANCOUNT | 51968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 52968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | NSCOUNT | 53968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 54968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | ARCOUNT | 55968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 56968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 57968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * AA, TC, RA, and RCODE are only set in responses. Brief description 58968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * of the remaining fields: 59968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * ID Identifier to match responses with queries 60968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * QR Query (0) or response (1) 61968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Opcode For our purposes, always QUERY 62968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * RD Recursion desired 63968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Z Reserved (zero) 64968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * QDCOUNT Number of queries 65968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * ANCOUNT Number of answers 66968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * NSCOUNT Number of name server records 67968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * ARCOUNT Number of additional records 68968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 69968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Question format, from RFC 1035: 70968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 1 1 1 1 1 1 71968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 72968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 73968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | | 74968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * / QNAME / 75968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * / / 76968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 77968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | QTYPE | 78968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 79968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * | QCLASS | 80968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 81968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 82968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * The query name is encoded as a series of labels, each represented 83968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * as a one-byte length (maximum 63) followed by the text of the 84968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * label. The list is terminated by a label of length zero (which can 85968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * be thought of as the root domain). 86968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */ 87968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 88968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldint ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, 89968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold int rd, unsigned char **buf, int *buflen) 90968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{ 91968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold int len; 92968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold unsigned char *q; 93968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold const char *p; 94968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 95968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Set our results early, in case we bail out early with an error. */ 96968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *buflen = 0; 97968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *buf = NULL; 98968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 99968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Compute the length of the encoded name so we can check buflen. 100968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Start counting at 1 for the zero-length label at the end. */ 101968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold len = 1; 102968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold for (p = name; *p; p++) 103968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold { 104968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (*p == '\\' && *(p + 1) != 0) 105968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold p++; 106968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold len++; 107968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 108968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* If there are n periods in the name, there are n + 1 labels, and 109968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * thus n + 1 length fields, unless the name is empty or ends with a 110968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * period. So add 1 unless name is empty or ends with a period. 111968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */ 112968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (*name && *(p - 1) != '.') 113968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold len++; 114968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 115968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Immediately reject names that are longer than the maximum of 255 116968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * bytes that's specified in RFC 1035 ("To simplify implementations, 117968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * the total length of a domain name (i.e., label octets and label 118968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * length octets) is restricted to 255 octets or less."). We aren't 119968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * doing this just to be a stickler about RFCs. For names that are 120968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * too long, 'dnscache' closes its TCP connection to us immediately 121968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * (when using TCP) and ignores the request when using UDP, and 122968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * BIND's named returns ServFail (TCP or UDP). Sending a request 123968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * that we know will cause 'dnscache' to close the TCP connection is 124968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * painful, since that makes any other outstanding requests on that 125968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * connection fail. And sending a UDP request that we know 126968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * 'dnscache' will ignore is bad because resources will be tied up 127968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * until we time-out the request. 128968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */ 129968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (len > MAXCDNAME) 130968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold return ARES_EBADNAME; 131968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 132968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *buflen = len + HFIXEDSZ + QFIXEDSZ; 133968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *buf = malloc(*buflen); 134968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (!*buf) 135968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold return ARES_ENOMEM; 136968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 137968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Set up the header. */ 138968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold q = *buf; 139968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold memset(q, 0, HFIXEDSZ); 140968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_HEADER_SET_QID(q, id); 141968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_HEADER_SET_OPCODE(q, QUERY); 142968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (rd) { 143968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_HEADER_SET_RD(q, 1); 144968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 145968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold else { 146968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_HEADER_SET_RD(q, 0); 147968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 148968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_HEADER_SET_QDCOUNT(q, 1); 149968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 150968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* A name of "." is a screw case for the loop below, so adjust it. */ 151968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (strcmp(name, ".") == 0) 152968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold name++; 153968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 154968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Start writing out the name after the header. */ 155968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold q += HFIXEDSZ; 156968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold while (*name) 157968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold { 158968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (*name == '.') 159968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold return ARES_EBADNAME; 160968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 161968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Count the number of bytes in this label. */ 162968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold len = 0; 163968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold for (p = name; *p && *p != '.'; p++) 164968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold { 165968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (*p == '\\' && *(p + 1) != 0) 166968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold p++; 167968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold len++; 168968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 169968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (len > MAXLABEL) 170968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold return ARES_EBADNAME; 171968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 172968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Encode the length and copy the data. */ 173968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *q++ = (unsigned char)len; 174968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold for (p = name; *p && *p != '.'; p++) 175968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold { 176968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (*p == '\\' && *(p + 1) != 0) 177968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold p++; 178968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *q++ = *p; 179968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 180968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 181968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Go to the next label and repeat, unless we hit the end. */ 182968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold if (!*p) 183968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold break; 184968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold name = p + 1; 185968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold } 186968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 187968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Add the zero-length label at the end. */ 188968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *q++ = 0; 189968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 190968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold /* Finish off the question with the type and class. */ 191968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_QUESTION_SET_TYPE(q, type); 192968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold DNS_QUESTION_SET_CLASS(q, dnsclass); 193968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold 194968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold return ARES_SUCCESS; 195968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold} 196