Commit Diff
Diff:
10133795a114a1387b2e7dbde3c41bc2581628c4
fe42904fa966a9150cc90f58b4fc294326a25230
Commit:
fe42904fa966a9150cc90f58b4fc294326a25230
Tree:
2b9efc5ab94a860f0f1411ebeaf169e2132a119b
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Sat Mar 27 15:40:09 2010 UTC
Message:
* TXT RR support tested on OpenBSD
blob - ec867624177b0a2dc910796e304c2c4c859f3d95
blob + da96b0b665f2d06fa37a6ecf0e1ef000ad878606
--- TODO
+++ TODO
@@ -5,13 +5,13 @@ Here are a few things left to do (until beta):
* A better configuration file and parser [sorta done]
* AAAA and A RR's when there is more than 1 need to be rotated every answer in
order to make use of load sharing. [done]
-* TXT RR support
+* TXT RR support [done]
* TCP support [done]
* NS delegation the right way [done]
Here are a few things nice to have but not necessarily needed:
-* split-horizon dns with IPv6
+* split-horizon dns with IPv6 [partially done]
* EDNS0 support
* AXFR
* recursing and caching support
blob - 37037f1a5dfa66f49180a6ff2eb05a90aea547bb
blob + 87b13b17feaf3cc13cf2aedb5d02f00b9b5fea8d
--- db.h
+++ db.h
@@ -71,6 +71,7 @@ struct domain {
#define DOMAIN_HAVE_MX 0x10
#define DOMAIN_HAVE_AAAA 0x20
#define DOMAIN_HAVE_NS 0x40
+#define DOMAIN_HAVE_TXT 0x80
struct soa soa; /* start of authority */
u_int32_t ttl; /* time to live */
in_addr_t a[10]; /* IP addresses */
@@ -91,6 +92,8 @@ struct domain {
u_int8_t cnamelen; /* len of CNAME */
char ptr[DNS_MAXNAME]; /* PTR RR */
u_int8_t ptrlen; /* len of PTR */
+ char txt[DNS_MAXNAME]; /* TXT string */
+ u_int8_t txtlen; /* len of TXT */
} __attribute__((packed));
struct sreply {
blob - e3274b37bf6f2afc87518d6469d2c2bbc350db04
blob + 620beefcbfe8e76f023a08e4c0129387ff1d00ae
--- example4.conf
+++ example4.conf
@@ -66,4 +66,6 @@ zone "centroid.eu" {
; balance these two
centroid.eu,balance,3600,62.75.160.180
centroid.eu,balance,3600,192.168.0.24
+ centroid.eu,txt,3600,1234
+ text.centroid.eu,txt,3600,,,,this is valid,,,too,,,
}
blob - c8ce2bf2fd2c401817bc227e9b2c381f13479173
blob + 378a149d8a6e06eb4fa80aeb01ae888756b130e0
--- main.c
+++ main.c
@@ -49,6 +49,7 @@ extern void reply_ptr(struct sreply *);
extern void reply_cname(struct sreply *);
extern void reply_mx(struct sreply *, DB *);
extern void reply_ns(struct sreply *, DB *);
+extern void reply_txt(struct sreply *);
extern u_int8_t find_region(struct sockaddr_storage *sst, int family);
extern void collects_init(void);
@@ -103,7 +104,7 @@ struct tcps {
} *tn1, *tn2, *tnp;
-static const char rcsid[] = "$Id: main.c,v 1.44 2010/03/27 10:25:18 pbug Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.45 2010/03/27 15:40:10 pbug Exp $";
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
@@ -1052,6 +1053,14 @@ lookup_zone(DB *db, struct question *question, struct
}
returnval = DNS_TYPE_NS;
break;
+ case DNS_TYPE_TXT:
+ if ((sd->flags & DOMAIN_HAVE_TXT) ==
+ DOMAIN_HAVE_TXT) {
+ returnval = DNS_TYPE_TXT;
+ break;
+ }
+ *lzerrno = ERR_NOERROR;
+ return -1;
default: /* RR's that we don't support, but have a zone for */
*lzerrno = ERR_NOERROR;
return -1;
@@ -1169,6 +1178,14 @@ lookup_zone(DB *db, struct question *question, struct
}
returnval = DNS_TYPE_CNAME;
break;
+ case DNS_TYPE_TXT:
+ if ((sd->flags & DOMAIN_HAVE_TXT) ==
+ DOMAIN_HAVE_TXT) {
+ returnval = DNS_TYPE_TXT;
+ break;
+ }
+ *lzerrno = ERR_NOERROR;
+ return -1;
default: /* RR's that we don't support, but have a zone for */
*lzerrno = ERR_NOERROR;
return -1;
@@ -1810,6 +1827,14 @@ tcpnxdomain:
}
break;
+ case DNS_TYPE_TXT:
+ if (type0 == DNS_TYPE_TXT) {
+ BUILD_REPLY(sreply, so, pbuf, len, question, from, \
+ fromlen, &sd0, NULL, tnp->region, istcp);
+ reply_txt(&sreply);
+ }
+ break;
+
default:
/*
@@ -2162,7 +2187,13 @@ udpnxdomain:
break; /* must break here */
}
break;
-
+ case DNS_TYPE_TXT:
+ if (type0 == DNS_TYPE_TXT) {
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion, istcp);
+ reply_txt(&sreply);
+ }
+ break;
default:
/*
blob - 90003d3a535eed13cbc00b9593b44efa8126f4f0
blob + ffdad9c085d44434dc1d4f14d455c2552f569895
--- parse.c
+++ parse.c
@@ -39,14 +39,15 @@ struct myrr_lookup {
u_int16_t type;
} mysrr_lookup[] = {
{ "a", DNS_TYPE_A } ,
- { "balance", DNS_TYPE_BALANCE },
{ "soa", DNS_TYPE_SOA },
{ "cname", DNS_TYPE_CNAME },
{ "ptr", DNS_TYPE_PTR },
{ "mx", DNS_TYPE_MX },
{ "aaaa", DNS_TYPE_AAAA },
{ "ns", DNS_TYPE_NS },
+ { "txt", DNS_TYPE_TXT },
{ "delegate", DNS_TYPE_DELEGATE },
+ { "balance", DNS_TYPE_BALANCE },
{ NULL, 0 },
};
@@ -73,7 +74,7 @@ struct cmd_lookup {
static u_int32_t config = 0;
-static const char rcsid[] = "$Id: parse.c,v 1.19 2010/03/27 10:25:20 pbug Exp $";
+static const char rcsid[] = "$Id: parse.c,v 1.20 2010/03/27 15:40:10 pbug Exp $";
/*
* PARSE_FILE - parse the configfile XXX rewrite me in yacc :(
@@ -834,6 +835,37 @@ parse_file(DB *db, char *file)
*p = save;
sdomain.flags |= DOMAIN_HAVE_CNAME;
+ break;
+ case DNS_TYPE_TXT:
+
+ p = endline;
+ save = *p;
+ *p = 0;
+
+ tokenlen = (p - starttoken);
+ if (tokenlen > 255) {
+ syslog(LOG_INFO, "TXT record too long, maximum length is 255 (per protocol), line %d\n", line);
+ fclose(f);
+ return (-1);
+ }
+
+ /*
+ * RFC 1035, page 13 says:
+ * <character-string> is a single
+ * length octet followed by that number of
+ * characters. <character-string> is treated
+ * as binary information, and can be up to
+ * 256 characters in length (including the
+ * length octet).
+ * let's remember to put that in reply_txt()
+ */
+
+ memcpy(&sdomain.txt, starttoken, tokenlen);
+ sdomain.txtlen = tokenlen;
+
+ *p = save;
+
+ sdomain.flags |= DOMAIN_HAVE_TXT;
break;
default:
blob - 11d5c9bab30105fe17b7b66e6b5f875084b368e5
blob + ea81b3ce5f9773f1f6aac61e4029afce5cc6aa16
--- reply.c
+++ reply.c
@@ -67,7 +67,7 @@ struct collects {
} *cn1, *cn2, *cnp;
-static const char rcsid[] = "$Id: reply.c,v 1.18 2010/03/19 17:21:01 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.19 2010/03/27 15:40:10 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -1231,6 +1231,111 @@ reply_soa(struct sreply *sreply)
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
+ if (istcp) {
+ char *tmpbuf;
+ u_int16_t *plen;
+
+ tmpbuf = malloc(outlen + 2);
+ if (tmpbuf == NULL) {
+ syslog(LOG_INFO, "malloc: %m");
+ }
+ plen = (u_int16_t *)tmpbuf;
+ *plen = htons(outlen);
+
+ memcpy(&tmpbuf[2], reply, outlen);
+
+ if (send(so, tmpbuf, outlen + 2, 0) < 0) {
+ syslog(LOG_INFO, "send: %m");
+ }
+ free(tmpbuf);
+ } else {
+ if (sendto(so, reply, outlen, 0, sa, salen) < 0) {
+ syslog(LOG_INFO, "sendto: %m");
+ }
+ }
+
+ return;
+}
+
+/*
+ * REPLY_TXT() - replies a DNS question (*q) on socket (so)
+ *
+ */
+
+
+void
+reply_txt(struct sreply *sreply)
+{
+ char reply[512];
+ struct dns_header *odh;
+ int outlen;
+ char *p;
+
+ struct answer {
+ char name[2];
+ u_int16_t type;
+ u_int16_t class;
+ u_int32_t ttl;
+ u_int16_t rdlength; /* 12 */
+ char rdata;
+ } __attribute__((packed));
+
+ struct answer *answer;
+
+ int so = sreply->so;
+ char *buf = sreply->buf;
+ int len = sreply->len;
+ struct question *q = sreply->q;
+ struct sockaddr *sa = sreply->sa;
+ int salen = sreply->salen;
+ struct domain *sd = sreply->sd1;
+ int istcp = sreply->istcp;
+
+ /* st */
+
+ odh = (struct dns_header *)&reply[0];
+ outlen = sizeof(struct dns_header);
+
+ if (len > sizeof(reply)) {
+ return;
+ }
+
+ /* copy question to reply */
+ memcpy(&reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
+ /* blank query */
+ memset((char *)&odh->query, 0, sizeof(u_int16_t));
+
+ outlen += (q->hdr->namelen + 4);
+
+ SET_DNS_REPLY(odh);
+ SET_DNS_AUTHORITATIVE(odh);
+
+ HTONS(odh->query);
+
+ odh->question = htons(1);
+ odh->answer = htons(1);
+ odh->nsrr = 0;
+ odh->additional = 0;
+
+ answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
+ q->hdr->namelen + 4);
+
+ answer->name[0] = 0xc0;
+ answer->name[1] = 0x0c;
+ answer->type = q->hdr->qtype;
+ answer->class = q->hdr->qclass;
+ answer->ttl = htonl(sd->ttl);
+
+ outlen += 12; /* up to rdata length */
+
+ p = (char *)&answer->rdata;
+
+ *p = sd->txtlen;
+ memcpy((p + 1), sd->txt, sd->txtlen);
+ outlen += (sd->txtlen + 1);
+
+ answer->rdlength = htons(sd->txtlen + 1);
+
if (istcp) {
char *tmpbuf;
u_int16_t *plen;
repomaster@centroid.eu