Add support for using an unspecified RR type
Add PRIVATE query type with id 65399 (private use range). According to RFC3597 the reply data in a query with unspecified RR type must be handled as unstructured binary data, which means it can contain raw packet data just like the NULL type. Since the reply format is optimal it is ordered just after NULL in the priority order.
This commit is contained in:
parent
2466cd184a
commit
3ebcd29b13
|
@ -24,6 +24,8 @@ master:
|
|||
Barak A. Pearlmutter.
|
||||
- Testcase compilation fixes for OS X and FreeBSD
|
||||
- Do not let sockets be inherited by sub-processes, fixes #99.
|
||||
- Add unspecified RR type (called PRIVATE; id 65399, in private use
|
||||
range). For servers with RFC3597 support. Fixes #97.
|
||||
|
||||
2010-02-06: 0.6.0-rc1 "Hotspotify"
|
||||
- Fixed tunnel not working on Windows.
|
||||
|
|
21
README
21
README
|
@ -177,8 +177,9 @@ packet, and one query can be max 256 chars. Each domain name part can be max
|
|||
63 chars. So your domain name and subdomain should be as short as possible to
|
||||
allow maximum upstream throughput.
|
||||
|
||||
Several DNS request types are supported, with the NULL type expected to provide
|
||||
the largest downstream bandwidth. Other available types are TXT, SRV, MX,
|
||||
Several DNS request types are supported, with the NULL and PRIVATE types
|
||||
expected to provide the largest downstream bandwidth. The PRIVATE type uses
|
||||
value 65399 in the private-use range. Other available types are TXT, SRV, MX,
|
||||
CNAME and A (returning CNAME), in decreasing bandwidth order. Normally the
|
||||
"best" request type is autodetected and used. However, DNS relays may impose
|
||||
limits on for example NULL and TXT, making SRV or MX actually the best choice.
|
||||
|
@ -190,14 +191,14 @@ Note that SRV, MX and A (returning CNAME) queries may/will cause additional
|
|||
lookups by "smart" caching nameservers to get an actual IP address, which may
|
||||
either slow down or fail completely.
|
||||
|
||||
DNS responses for non-NULL queries can be encoded with the same set of codecs
|
||||
as upstream data. This is normally also autodetected, but no fully exhaustive
|
||||
tests are done, so some problems may not be noticed when selecting more
|
||||
advanced codecs. In that case, you'll see failures/corruption in the fragment
|
||||
size autoprobe. In particular, several DNS relays have been found that change
|
||||
replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when that
|
||||
hostname exceeds ca. 180 characters. In these and similar cases, use the -O
|
||||
option to try other downstream codecs; Base32 should always work.
|
||||
DNS responses for non-NULL/PRIVATE queries can be encoded with the same set of
|
||||
codecs as upstream data. This is normally also autodetected, but no fully
|
||||
exhaustive tests are done, so some problems may not be noticed when selecting
|
||||
more advanced codecs. In that case, you'll see failures/corruption in the
|
||||
fragment size autoprobe. In particular, several DNS relays have been found that
|
||||
change replies returning hostnames (SRV, MX, CNAME, A) to lowercase only when
|
||||
that hostname exceeds ca. 180 characters. In these and similar cases, use the
|
||||
-O option to try other downstream codecs; Base32 should always work.
|
||||
|
||||
Normal operation now is for the server to _not_ answer a DNS request until
|
||||
the next DNS request has come in, a.k.a. being "lazy". This way, the server
|
||||
|
|
|
@ -122,7 +122,8 @@ Server sends:
|
|||
s or S: Downstream encoding Base64, for TXT/CNAME/A/MX
|
||||
u or U: Downstream encoding Base64u, for TXT/CNAME/A/MX
|
||||
v or V: Downstream encoding Base128, for TXT/CNAME/A/MX
|
||||
r or R: Downstream encoding Raw, for TXT/NULL (default for NULL)
|
||||
r or R: Downstream encoding Raw, for PRIVATE/TXT/NULL (default for
|
||||
PRIVATE and NULL)
|
||||
If codec unsupported for request type, server will use Base32; note
|
||||
that server will answer any mix of request types that a client sends.
|
||||
Server may disregard this option; client must always use the downstream
|
||||
|
@ -188,8 +189,8 @@ encoded with the chosen upstream codec.
|
|||
Downstream data starts with 2 byte header. Then payload data, which may be
|
||||
compressed.
|
||||
|
||||
In NULL responses, downstream data is always raw. In all other response types,
|
||||
downstream data is encoded (see Options above).
|
||||
In NULL and PRIVATE responses, downstream data is always raw. In all other
|
||||
response types, downstream data is encoded (see Options above).
|
||||
Encoding type is indicated by 1 prefix char:
|
||||
TXT:
|
||||
End result is always DNS-chopped (series of len-prefixed strings
|
||||
|
|
|
@ -169,6 +169,7 @@ more bandwidth.
|
|||
In that case, use this option to override the autodetection.
|
||||
In (expected) decreasing bandwidth order, the supported DNS request types are:
|
||||
.IR NULL ,
|
||||
.IR PRIVATE ,
|
||||
.IR TXT ,
|
||||
.IR SRV ,
|
||||
.IR MX ,
|
||||
|
@ -183,7 +184,10 @@ and
|
|||
.I A
|
||||
may/will cause additional lookups by "smart" caching
|
||||
nameservers to get an actual IP address, which may either slow down or fail
|
||||
completely.
|
||||
completely. The
|
||||
.IR PRIVATE
|
||||
type uses value 65399 (in the 'private use' range) and requires servers
|
||||
implementing RFC 3597.
|
||||
.TP
|
||||
.B -O downenc
|
||||
Force downstream encoding type for all query type responses except NULL.
|
||||
|
|
23
src/client.c
23
src/client.c
|
@ -172,6 +172,8 @@ client_set_qtype(char *qtype)
|
|||
{
|
||||
if (!strcasecmp(qtype, "NULL"))
|
||||
do_qtype = T_NULL;
|
||||
else if (!strcasecmp(qtype, "PRIVATE"))
|
||||
do_qtype = T_PRIVATE;
|
||||
else if (!strcasecmp(qtype, "CNAME"))
|
||||
do_qtype = T_CNAME;
|
||||
else if (!strcasecmp(qtype, "A"))
|
||||
|
@ -191,6 +193,7 @@ client_get_qtype()
|
|||
char *c = "UNDEFINED";
|
||||
|
||||
if (do_qtype == T_NULL) c = "NULL";
|
||||
else if (do_qtype == T_PRIVATE) c = "PRIVATE";
|
||||
else if (do_qtype == T_CNAME) c = "CNAME";
|
||||
else if (do_qtype == T_A) c = "A";
|
||||
else if (do_qtype == T_MX) c = "MX";
|
||||
|
@ -1786,7 +1789,7 @@ handshake_downenc_autodetect(int dns_fd)
|
|||
int base64uok = 0;
|
||||
int base128ok = 0;
|
||||
|
||||
if (do_qtype == T_NULL) {
|
||||
if (do_qtype == T_NULL || do_qtype == T_PRIVATE) {
|
||||
/* no other choice than raw */
|
||||
fprintf(stderr, "No alternative downstream codec available, using default (Raw)\n");
|
||||
return ' ';
|
||||
|
@ -1840,13 +1843,14 @@ handshake_qtypetest(int dns_fd, int timeout)
|
|||
int trycodec;
|
||||
int k;
|
||||
|
||||
if (do_qtype == T_NULL)
|
||||
if (do_qtype == T_NULL || do_qtype == T_PRIVATE)
|
||||
trycodec = 'R';
|
||||
else
|
||||
trycodec = 'T';
|
||||
|
||||
/* We could use 'Z' bouncing here, but 'Y' also tests that 0-255
|
||||
byte values can be returned, which is needed for NULL to work. */
|
||||
byte values can be returned, which is needed for NULL/PRIVATE
|
||||
to work. */
|
||||
|
||||
send_downenctest(dns_fd, trycodec, 1, NULL, 0);
|
||||
|
||||
|
@ -1871,11 +1875,12 @@ handshake_qtype_numcvt(int num)
|
|||
{
|
||||
switch (num) {
|
||||
case 0: return T_NULL;
|
||||
case 1: return T_TXT;
|
||||
case 2: return T_SRV;
|
||||
case 3: return T_MX;
|
||||
case 4: return T_CNAME;
|
||||
case 5: return T_A;
|
||||
case 1: return T_PRIVATE;
|
||||
case 2: return T_TXT;
|
||||
case 3: return T_SRV;
|
||||
case 4: return T_MX;
|
||||
case 5: return T_CNAME;
|
||||
case 6: return T_A;
|
||||
}
|
||||
return T_UNSET;
|
||||
}
|
||||
|
@ -2317,7 +2322,7 @@ handshake_autoprobe_fragsize(int dns_fd)
|
|||
fprintf(stderr, "Note: this probably won't work well.\n");
|
||||
fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
|
||||
} else if (max_fragsize < 202 &&
|
||||
(do_qtype == T_NULL || do_qtype == T_TXT ||
|
||||
(do_qtype == T_NULL || do_qtype == T_PRIVATE || do_qtype == T_TXT ||
|
||||
do_qtype == T_SRV || do_qtype == T_MX)) {
|
||||
fprintf(stderr, "Note: this isn't very much.\n");
|
||||
fprintf(stderr, "Try setting -M to 200 or lower, or try other DNS types (-T option).\n");
|
||||
|
|
|
@ -75,8 +75,10 @@ extern const unsigned char raw_header[RAW_HDR_LEN];
|
|||
# define DONT_FRAG_VALUE 1
|
||||
#endif
|
||||
|
||||
#define T_PRIVATE 65399
|
||||
/* Undefined RR type; "private use" range, see http://www.bind9.net/dns-parameters */
|
||||
#define T_UNSET 65432
|
||||
/* Unused RR type; "private use" range, see http://www.bind9.net/dns-parameters */
|
||||
/* Unused RR type, never actually sent */
|
||||
|
||||
struct packet
|
||||
{
|
||||
|
|
|
@ -467,7 +467,7 @@ dns_decode(char *buf, size_t buflen, struct query *q, qr_t qr, char *packet, siz
|
|||
}
|
||||
|
||||
/* Here type is still the question type */
|
||||
if (type == T_NULL) {
|
||||
if (type == T_NULL || type == T_PRIVATE) {
|
||||
/* Assume that first answer is what we wanted */
|
||||
readname(packet, packetlen, &data, name, sizeof(name));
|
||||
CHECKLEN(10);
|
||||
|
|
|
@ -83,7 +83,7 @@ help() {
|
|||
"[-P password] [-m maxfragsize] [-M maxlen] [-T type] [-O enc] [-L 0|1] [-I sec] "
|
||||
"[-z context] [-F pidfile] [nameserver] topdomain\n", __progname);
|
||||
fprintf(stderr, "Options to try if connection doesn't work:\n");
|
||||
fprintf(stderr, " -T force dns type: NULL, TXT, SRV, MX, CNAME, A (default: autodetect)\n");
|
||||
fprintf(stderr, " -T force dns type: NULL, PRIVATE, TXT, SRV, MX, CNAME, A (default: autodetect)\n");
|
||||
fprintf(stderr, " -O force downstream encoding for -T other than NULL: Base32, Base64, Base64u,\n");
|
||||
fprintf(stderr, " Base128, or (only for TXT:) Raw (default: autodetect)\n");
|
||||
fprintf(stderr, " -I max interval between requests (default 4 sec) to prevent DNS timeouts\n");
|
||||
|
|
|
@ -1662,6 +1662,7 @@ tunnel_dns(int tun_fd, int dns_fd, int bind_fd)
|
|||
|
||||
switch (q.type) {
|
||||
case T_NULL:
|
||||
case T_PRIVATE:
|
||||
case T_CNAME:
|
||||
case T_A:
|
||||
case T_MX:
|
||||
|
|
Loading…
Reference in New Issue