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:
Erik Ekman
2014-06-09 20:05:29 +02:00
parent 2466cd184a
commit 3ebcd29b13
9 changed files with 44 additions and 28 deletions

View File

@@ -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");

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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");

View File

@@ -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: