rfc3596.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #include "squid.h"
10 #include "dns/rfc2671.h"
11 #include "dns/rfc3596.h"
12 #include "SquidConfig.h"
13 #include "util.h"
14 
15 #if HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #if HAVE_MEMORY_H
19 #include <memory.h>
20 #endif
21 #include <cassert>
22 #if HAVE_NETINET_IN_H
23 #include <netinet/in.h>
24 #endif
25 #if HAVE_STRINGS_H
26 #include <strings.h>
27 #endif
28 
29 #if !defined(RFC1035_MAXHOSTNAMESZ)
30 #error RFC3596 Library depends on RFC1035
31 #endif
32 
33 /*
34  * Low level DNS protocol routines
35  *
36  * Provides RFC3596 functions to handle purely IPv6 DNS.
37  * Adds AAAA and IPv6 PTR records.
38  * Other IPv6 records are not mentioned by this RFC.
39  *
40  * IPv4 equivalents are taken care of by the RFC1035 library.
41  * Where one protocol lookup must be followed by another, the caller
42  * is responsible for the order and handling of the lookups.
43  *
44  * KNOWN BUGS:
45  *
46  * UDP replies with TC set should be retried via TCP
47  */
48 
57 ssize_t
58 rfc3596BuildHostQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query, int qtype)
59 {
60  static rfc1035_message h;
61  size_t offset = 0;
62  memset(&h, '\0', sizeof(h));
63  h.id = qid;
64  h.qr = 0;
65  h.rd = 1;
66  h.opcode = 0; /* QUERY */
67  h.qdcount = (unsigned int) 1;
68 
69  const auto edns_sz = Config.dns.packet_max;
70  h.arcount = (edns_sz > 0 ? 1 : 0);
71 
72  offset += rfc1035HeaderPack(buf + offset, sz - offset, &h);
73  offset += rfc1035QuestionPack(buf + offset,
74  sz - offset,
75  hostname,
76  qtype,
78  if (edns_sz > 0)
79  offset += rfc2671RROptPack(buf + offset, sz - offset, edns_sz);
80 
81  if (query) {
82  query->qtype = qtype;
83  query->qclass = RFC1035_CLASS_IN;
84  xstrncpy(query->name, hostname, sizeof(query->name));
85  }
86 
87  assert(offset <= sz);
88  return offset;
89 }
90 
99 ssize_t
100 rfc3596BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query)
101 {
102  return rfc3596BuildHostQuery(hostname, buf, sz, qid, query, RFC1035_TYPE_A);
103 }
104 
113 ssize_t
114 rfc3596BuildAAAAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query)
115 {
116  return rfc3596BuildHostQuery(hostname, buf, sz, qid, query, RFC1035_TYPE_AAAA);
117 }
118 
127 ssize_t
128 rfc3596BuildPTRQuery4(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query)
129 {
130  static char rev[RFC1035_MAXHOSTNAMESZ];
131  unsigned int i;
132 
133  i = (unsigned int) ntohl(addr.s_addr);
134  snprintf(rev, RFC1035_MAXHOSTNAMESZ, "%u.%u.%u.%u.in-addr.arpa.",
135  i & 255,
136  (i >> 8) & 255,
137  (i >> 16) & 255,
138  (i >> 24) & 255);
139 
140  return rfc3596BuildHostQuery(rev, buf, sz, qid, query, RFC1035_TYPE_PTR);
141 }
142 
143 ssize_t
144 rfc3596BuildPTRQuery6(const struct in6_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query)
145 {
146  static char rev[RFC1035_MAXHOSTNAMESZ];
147  const uint8_t* r = addr.s6_addr;
148  char* p = rev;
149  int i; /* NP: MUST allow signed for loop termination. */
150 
151  /* work from the raw addr field. anything else may have representation changes. */
152  /* The sin6_port and sin6_addr members shall be in network byte order. */
153  for (i = 15; i >= 0; i--, p+=4) {
154  snprintf(p, 5, "%1x.%1x.", ((r[i])&0xf), (r[i]>>4)&0xf );
155  }
156 
157  snprintf(p,10,"ip6.arpa.");
158 
159  return rfc3596BuildHostQuery(rev, buf, sz, qid, query, RFC1035_TYPE_PTR);
160 }
161 
ssize_t rfc3596BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition: rfc3596.cc:100
unsigned int opcode
Definition: rfc1035.h:58
int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz)
Definition: rfc2671.cc:14
int rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message *hdr)
Definition: rfc1035.cc:56
char * xstrncpy(char *dst, const char *src, size_t n)
Definition: xstring.cc:37
unsigned short qdcount
Definition: rfc1035.h:64
#define RFC1035_TYPE_A
Definition: rfc1035.h:93
#define RFC1035_MAXHOSTNAMESZ
Definition: rfc1035.h:32
#define RFC1035_TYPE_PTR
Definition: rfc1035.h:95
ssize_t rfc3596BuildPTRQuery4(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition: rfc3596.cc:128
ssize_t rfc3596BuildPTRQuery6(const struct in6_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition: rfc3596.cc:144
#define assert(EX)
Definition: assert.h:17
unsigned short qtype
Definition: rfc1035.h:50
#define RFC1035_TYPE_AAAA
Definition: rfc3596.h:48
unsigned short id
Definition: rfc1035.h:56
struct SquidConfig::@107 dns
char name[RFC1035_MAXHOSTNAMESZ]
Definition: rfc1035.h:49
ssize_t rfc3596BuildHostQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, int qtype)
Definition: rfc3596.cc:58
unsigned short qclass
Definition: rfc1035.h:51
unsigned int rd
Definition: rfc1035.h:61
int rfc1035QuestionPack(char *buf, const size_t sz, const char *name, const unsigned short type, const unsigned short _class)
Definition: rfc1035.cc:154
unsigned short arcount
Definition: rfc1035.h:67
ssize_t rfc3596BuildAAAAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition: rfc3596.cc:114
#define RFC1035_CLASS_IN
Definition: rfc1035.h:96
unsigned int qr
Definition: rfc1035.h:57
class SquidConfig Config
Definition: SquidConfig.cc:12
int unsigned int
Definition: stub_fd.cc:19
ssize_t packet_max
maximum size EDNS advertised for DNS replies.
Definition: SquidConfig.h:542

 

Introduction

Documentation

Support

Miscellaneous