Squid Web Cache master
Loading...
Searching...
No Matches
rfc3596.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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
57ssize_t
58rfc3596BuildHostQuery(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
99ssize_t
100rfc3596BuildAQuery(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
113ssize_t
114rfc3596BuildAAAAQuery(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
127ssize_t
128rfc3596BuildPTRQuery4(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
143ssize_t
144rfc3596BuildPTRQuery6(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
class SquidConfig Config
#define assert(EX)
Definition assert.h:17
ssize_t packet_max
maximum size EDNS advertised for DNS replies.
struct SquidConfig::@100 dns
int rfc1035QuestionPack(char *buf, const size_t sz, const char *name, const unsigned short type, const unsigned short _class)
Definition rfc1035.cc:154
int rfc1035HeaderPack(char *buf, size_t sz, rfc1035_message *hdr)
Definition rfc1035.cc:56
#define RFC1035_TYPE_PTR
Definition rfc1035.h:95
#define RFC1035_TYPE_A
Definition rfc1035.h:93
#define RFC1035_CLASS_IN
Definition rfc1035.h:96
#define RFC1035_MAXHOSTNAMESZ
Definition rfc1035.h:32
int rfc2671RROptPack(char *buf, size_t sz, ssize_t edns_sz)
Definition rfc2671.cc:14
ssize_t rfc3596BuildAAAAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition rfc3596.cc:114
ssize_t rfc3596BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition rfc3596.cc:100
ssize_t rfc3596BuildPTRQuery6(const struct in6_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition rfc3596.cc:144
ssize_t rfc3596BuildHostQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query *query, int qtype)
Definition rfc3596.cc:58
ssize_t rfc3596BuildPTRQuery4(const struct in_addr addr, char *buf, size_t sz, unsigned short qid, rfc1035_query *query)
Definition rfc3596.cc:128
#define RFC1035_TYPE_AAAA
Definition rfc3596.h:48
unsigned int rd
Definition rfc1035.h:61
unsigned short qdcount
Definition rfc1035.h:64
unsigned int opcode
Definition rfc1035.h:58
unsigned short id
Definition rfc1035.h:56
unsigned int qr
Definition rfc1035.h:57
unsigned short arcount
Definition rfc1035.h:67
unsigned short qclass
Definition rfc1035.h:51
char name[RFC1035_MAXHOSTNAMESZ]
Definition rfc1035.h:49
unsigned short qtype
Definition rfc1035.h:50
int unsigned int
Definition stub_fd.cc:19
char * xstrncpy(char *dst, const char *src, size_t n)
Definition xstring.cc:37