Commit Diff
Diff:
c51e1dad2f485970a517ea001821fc49d41796f8
1aaa191279eda8b8cd40cd020c96b55b0340de8c
Commit:
1aaa191279eda8b8cd40cd020c96b55b0340de8c
Tree:
b8f9a65fb08cd5e905538feaa6e4444cf79e457c
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Sat Jun 20 15:27:07 2015 UTC
Message:
* RRSIG is added to A and NS records now * code for above is in additional.c * take out find_rrsig_substruct() * allow a dnssec config option to turn on DNSSEC.. Prost!
blob - 943e790df557207b668d072f822b0881aa4d34dd
blob + ae79e8a134a95a6b470ef641204936afdbb82a1c
--- additional.c
+++ additional.c
@@ -34,12 +34,14 @@ int additional_aaaa(char *, int, struct domain *, char
int additional_mx(char *, int, struct domain *, char *, int, int, int *);
int additional_opt(struct question *, char *, int, int);
int additional_ptr(char *, int, struct domain *, char *, int, int, int *);
+int additional_rrsig(char *, int, int, struct domain *, char *, int, int);
extern int compress_label(u_char *, int, int);
extern void * find_substruct(struct domain *, u_int16_t);
+extern int dnssec;
-static const char rcsid[] = "$Id: additional.c,v 1.3 2015/06/17 06:45:09 pjp Exp $";
+static const char rcsid[] = "$Id: additional.c,v 1.4 2015/06/20 15:27:07 pjp Exp $";
/*
@@ -466,6 +468,7 @@ int
additional_opt(struct question *question, char *reply, int replylen, int offset)
{
struct dns_optrr *answer;
+ int rcode = 0;
if ((offset + sizeof(struct dns_optrr)) > replylen) {
goto out;
@@ -476,12 +479,100 @@ additional_opt(struct question *question, char *reply,
memset(answer->name, 0, sizeof(answer->name));
answer->type = htons(DNS_TYPE_OPT);
answer->class = htons(question->edns0len);
- answer->ttl = htonl(0);
+ if (dnssec && question->dnssecok)
+ rcode = DNSSEC_OK;
+ answer->ttl = htonl(rcode); /* EXTENDED RCODE */
+
answer->rdlen = htons(0);
offset += sizeof(struct dns_optrr);
+out:
+ return (offset);
+
+}
+
+/*
+ * ADDITIONAL_RRSIG - tag on an additional RRSIG to the answer
+ * type passed must be an INTERNAL_TYPE!
+ */
+
+int
+additional_rrsig(char *name, int namelen, int inttype, struct domain *sd, char *reply, int replylen, int offset)
+{
+ struct answer {
+ u_int16_t type;
+ u_int16_t class;
+ u_int32_t ttl;
+ u_int16_t rdlength; /* 12 */
+ u_int16_t type_covered;
+ u_int8_t algorithm;
+ u_int8_t labels;
+ u_int32_t original_ttl;
+ u_int32_t sig_expiration;
+ u_int32_t sig_inception;
+ u_int16_t keytag;
+ } __attribute__((packed));
+
+
+ struct answer *answer;
+ struct domain_rrsig *sdrr;
+ int tmplen, rroffset;
+
+ sdrr = (struct domain_rrsig *)find_substruct(sd, INTERNAL_TYPE_RRSIG);
+ if (sdrr == NULL)
+ goto out;
+
+ rroffset = offset;
+
+ if ((offset + namelen) > replylen)
+ goto out;
+
+ memcpy(&reply[offset], name, namelen);
+ offset += namelen;
+ tmplen = compress_label((u_char*)reply, offset, namelen);
+
+ if (tmplen != 0) {
+ offset = tmplen;
+ }
+
+ if ((offset + sizeof(struct answer)) > replylen) {
+ offset = rroffset;
+ goto out;
+ }
+
+
+ answer = (struct answer *)&reply[offset];
+ answer->type = htons(DNS_TYPE_RRSIG);
+ answer->class = htons(DNS_CLASS_IN);
+ answer->ttl = htonl(sd->ttl[inttype]);
+ answer->type_covered = htons(sdrr->rrsig[inttype].type_covered);
+ answer->algorithm = sdrr->rrsig[inttype].algorithm;
+ answer->labels = sdrr->rrsig[inttype].labels;
+ answer->original_ttl = htonl(sdrr->rrsig[inttype].original_ttl);
+ answer->sig_expiration = htonl(sdrr->rrsig[inttype].signature_expiration);
+ answer->sig_inception = htonl(sdrr->rrsig[inttype].signature_inception);
+ answer->keytag = htons(sdrr->rrsig[inttype].key_tag);
+
+ offset += sizeof(*answer);
+ rroffset = offset;
+
+ memcpy(&reply[offset], &sdrr->rrsig[inttype].signers_name, sdrr->rrsig[inttype].signame_len);
+
+ offset += sdrr->rrsig[inttype].signame_len;
+#if 0
+ tmplen = compress_label((u_char*)reply, offset, sdrr->rrsig[inttype].signame_len);
+
+ if (tmplen != 0) {
+ offset = tmplen;
+ }
+#endif
+
+ memcpy(&reply[offset], &sdrr->rrsig[inttype].signature, sdrr->rrsig[inttype].signature_len);
+ offset += sdrr->rrsig[inttype].signature_len;
+
+ answer->rdlength = htons((offset - rroffset) + 18);
out:
return (offset);
blob - 700e0be4a13a5abb20ab6003d9fe1ecdae25b08a
blob + 7f7e018250105097256199e812c49cecf3641af6
--- main.c
+++ main.c
@@ -80,6 +80,7 @@ char *dns_label(char *, int *);
int free_question(struct question *);
char *get_dns_type(int dnstype);
struct domain * get_soa(DB *, struct question *);
+int lookup_type(int);
struct domain * lookup_zone(DB *, struct question *, int *, int *, char *);
int get_record_size(DB *, char *, int);
void * find_substruct(struct domain *, u_int16_t);
@@ -174,7 +175,7 @@ static struct tcps {
} *tn1, *tnp, *tntmp;
-static const char rcsid[] = "$Id: main.c,v 1.7 2015/06/18 10:45:53 pjp Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.8 2015/06/20 15:27:07 pjp Exp $";
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
@@ -3766,4 +3767,31 @@ find_substruct(struct domain *ssd, u_int16_t type)
}
return NULL;
+}
+
+int
+lookup_type(int internal_type)
+{
+ int array[INTERNAL_TYPE_MAX];
+
+ array[INTERNAL_TYPE_A] = DNS_TYPE_A;
+ array[INTERNAL_TYPE_AAAA] = DNS_TYPE_AAAA;
+ array[INTERNAL_TYPE_CNAME] = DNS_TYPE_CNAME;
+ array[INTERNAL_TYPE_NS] = DNS_TYPE_NS;
+ array[INTERNAL_TYPE_DNSKEY] =DNS_TYPE_DNSKEY;
+ array[INTERNAL_TYPE_DS] = DNS_TYPE_DS;
+ array[INTERNAL_TYPE_MX] = DNS_TYPE_MX;
+ array[INTERNAL_TYPE_NAPTR] = DNS_TYPE_NAPTR;
+ array[INTERNAL_TYPE_NSEC] = DNS_TYPE_NSEC;
+ array[INTERNAL_TYPE_PTR] = DNS_TYPE_PTR;
+ array[INTERNAL_TYPE_SOA] = DNS_TYPE_SOA;
+ array[INTERNAL_TYPE_SPF] = DNS_TYPE_SPF;
+ array[INTERNAL_TYPE_SRV] = DNS_TYPE_SRV;
+ array[INTERNAL_TYPE_SSHFP] = DNS_TYPE_SSHFP;
+ array[INTERNAL_TYPE_TXT] = DNS_TYPE_TXT;
+
+ if (internal_type < 0 || internal_type > INTERNAL_TYPE_MAX)
+ return -1;
+
+ return(array[internal_type]);
}
blob - 26069f4e3e9da96046197ec3883dfbf8db51e6f4
blob + 27c3e20cd24ed75bdfa3b14254a6a188e72ad67a
--- parse.y
+++ parse.y
@@ -101,7 +101,7 @@ typedef struct {
#define YYSTYPE_IS_DECLARED 1
#endif
-static const char rcsid[] = "$Id: parse.y,v 1.11 2015/06/20 08:07:17 pjp Exp $";
+static const char rcsid[] = "$Id: parse.y,v 1.12 2015/06/20 15:27:07 pjp Exp $";
static int version = 0;
static int state = 0;
static uint8_t region = 0;
@@ -141,7 +141,6 @@ int findeol(void);
int get_ip(char *, int);
char *get_prefixlen(char *, char *, int);
int get_quotedstring(char *, int);
-void * find_rrsig_substruct(struct domain *, u_int16_t, u_int16_t);
int get_record(struct domain *, char *, int);
int get_string(char *, int);
int lgetc(int);
@@ -2185,7 +2184,7 @@ fill_rrsig(char *name, char *type, u_int32_t myttl, ch
break;
}
- ssd_rrsig = (struct domain_rrsig *) find_rrsig_substruct(ssd, DNS_TYPE_RRSIG, rr->type);
+ ssd_rrsig = (struct domain_rrsig *) find_substruct(ssd, INTERNAL_TYPE_RRSIG);
if (ssd_rrsig == NULL) {
rs += sizeof(struct domain_rrsig);
#ifdef __OpenBSD__
@@ -2203,8 +2202,11 @@ fill_rrsig(char *name, char *type, u_int32_t myttl, ch
ssd_rrsig->type = INTERNAL_TYPE_RRSIG;
}
+ printf("filling internal type %d\n", rr->internal_type);
+
ssd_rrsig->rrsig[rr->internal_type].type_covered = rr->type;
ssd_rrsig->rrsig[rr->internal_type].algorithm = algorithm;
+ ssd_rrsig->rrsig[rr->internal_type].labels = labels;
if (ssd->ttl[rr->internal_type] != original_ttl) {
return (-1);
@@ -3430,116 +3432,6 @@ fill_soa(char *name, char *type, int myttl, char *auth
return (0);
}
-
-
-/* find a rrsig substruct in struct domain */
-void *
-find_rrsig_substruct(struct domain *ssd, u_int16_t type, u_int16_t rrtype)
-{
- struct domain_generic *sdg = NULL;
- struct domain_rrsig *sdrr = NULL;
- void *ptr = NULL;
- void *vssd = (void *)ssd;
-
- switch (type) {
- case INTERNAL_TYPE_SOA:
- if (! (ssd->flags & DOMAIN_HAVE_SOA))
- return NULL;
- break;
- case INTERNAL_TYPE_A:
- if (! (ssd->flags & DOMAIN_HAVE_A))
- return NULL;
- break;
- case INTERNAL_TYPE_AAAA:
- if (! (ssd->flags & DOMAIN_HAVE_AAAA))
- return NULL;
- break;
- case INTERNAL_TYPE_MX:
- if (! (ssd->flags & DOMAIN_HAVE_MX))
- return NULL;
- break;
- case INTERNAL_TYPE_NS:
- if (! (ssd->flags & DOMAIN_HAVE_NS))
- return NULL;
- break;
- case INTERNAL_TYPE_CNAME:
- if (! (ssd->flags & DOMAIN_HAVE_CNAME))
- return NULL;
- break;
- case INTERNAL_TYPE_PTR:
- if (! (ssd->flags & DOMAIN_HAVE_PTR))
- return NULL;
- break;
- case INTERNAL_TYPE_TXT:
- if (! (ssd->flags & DOMAIN_HAVE_TXT))
- return NULL;
- break;
- case INTERNAL_TYPE_SPF:
- if (! (ssd->flags & DOMAIN_HAVE_SPF))
- return NULL;
- break;
- case INTERNAL_TYPE_SRV:
- if (! (ssd->flags & DOMAIN_HAVE_SRV))
- return NULL;
- break;
- case INTERNAL_TYPE_SSHFP:
- if (! (ssd->flags & DOMAIN_HAVE_SSHFP))
- return NULL;
- break;
- case INTERNAL_TYPE_NAPTR:
- if (! (ssd->flags & DOMAIN_HAVE_NAPTR))
- return NULL;
- break;
- case INTERNAL_TYPE_DNSKEY:
- if (! (ssd->flags & DOMAIN_HAVE_DNSKEY))
- return NULL;
- break;
- case INTERNAL_TYPE_DS:
- if (! (ssd->flags & DOMAIN_HAVE_DS))
- return NULL;
- break;
- case INTERNAL_TYPE_NSEC:
- if (! (ssd->flags & DOMAIN_HAVE_NSEC))
- return NULL;
- break;
- case INTERNAL_TYPE_RRSIG:
- if (! (ssd->flags & DOMAIN_HAVE_RRSIG))
- return NULL;
- break;
- default:
- return NULL;
- break;
- }
-
-#if 0
- for (sdg = (struct domain_generic *)(ssd + sizeof(struct domain)); \
- sdg <= (struct domain_generic *)(ssd + ssd->len); \
- sdg += sdg->len) {
- if (type == sdg->type) {
- sdrr = (struct domain_rrsig *)sdg;
- if (rrtype == sdrr->rrsig[type].type_covered) {
- ptr = (void *)sdg;
- return (ptr);
- }
- }
- }
-#endif
- for (ptr = (void *)(vssd + sizeof(struct domain)); \
- ptr <= (void *)(vssd + ssd->len); \
- ptr += sdg->len) {
- sdg = (struct domain_generic *)ptr;
- if (type == sdg->type) {
- sdrr = (struct domain_rrsig *)ptr;
- if (rrtype == sdrr->rrsig[type].type_covered) {
- return (ptr);
- }
- }
- }
-
-
- return NULL;
-}
-
int
get_record(struct domain *sdomain, char *converted_name, int converted_namelen)
blob - e056c476c9dd3fdd38d95c20d2277693048b9af9
blob + f9998371b7585e83202cb20cf8bb07c52aba2ede
--- reply.c
+++ reply.c
@@ -36,6 +36,7 @@ extern int additional_aaaa(char *, int, struct domai
extern int additional_mx(char *, int, struct domain *, char *, int, int, int *);
extern int additional_ptr(char *, int, struct domain *, char *, int, int, int *);
extern int additional_opt(struct question *, char *, int, int);
+extern int additional_rrsig(char *, int, int, struct domain *, char *, int, int);
extern struct question *build_fake_question(char *, int, u_int16_t);
extern int compress_label(u_char *, int, int);
extern void dolog(int, char *, ...);
@@ -87,10 +88,10 @@ struct collects {
SLIST_ENTRY(collects) collect_entry;
} *cn1, *cn2, *cnp;
-extern int debug, verbose;
+extern int debug, verbose, dnssec;
-static const char rcsid[] = "$Id: reply.c,v 1.6 2015/06/18 09:56:58 pjp Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.7 2015/06/20 15:27:07 pjp Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -105,7 +106,6 @@ reply_a(struct sreply *sreply, DB *db)
u_int16_t outlen;
int a_count;
int mod, pos;
- int ttlhack = 0;
struct answer {
char name[2];
@@ -127,7 +127,6 @@ reply_a(struct sreply *sreply, DB *db)
struct domain *sd = sreply->sd1;
struct domain_a *sda = NULL;
- u_int8_t region = sreply->region;
int istcp = sreply->istcp;
int replysize = 512;
int retlen = -1;
@@ -172,25 +171,12 @@ reply_a(struct sreply *sreply, DB *db)
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
q->hdr->namelen + 4);
- /* if we aren't a balance record our region code is 0xff so check */
- if (sda->region[sda->a_ptr] != 0xff) {
- ttlhack = 1;
- }
-
a_count = 0;
pos = sda->a_ptr;
mod = sda->a_count;
do {
/*
- * skip records that are not in the needed region
- */
- if (ttlhack && sda->region[pos % mod] != region) {
- pos++;
- continue;
- }
-
- /*
* answer->name is a pointer to the request (0xc00c)
*/
@@ -224,8 +210,10 @@ reply_a(struct sreply *sreply, DB *db)
answer = (struct answer *)&reply[outlen];
} while (a_count < RECORD_COUNT && --sda->a_count);
- if (ttlhack) {
- odh->answer = htons(a_count);
+ /* Add RRSIG */
+ if (dnssec && q->dnssecok) {
+ odh->answer = htons(a_count + 1);
+ outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sd, reply, replysize, outlen);
}
if (q->edns0len) {
@@ -690,6 +678,7 @@ reply_ns(struct sreply *sreply, DB *db)
int wildcard = sreply->wildcard;
int replysize = 512;
int retlen = -1;
+ struct domain *sdhave_a = NULL, *sdhave_aaaa = NULL;
if ((sdns = find_substruct(sd, INTERNAL_TYPE_NS)) == NULL)
return -1;
@@ -828,25 +817,56 @@ reply_ns(struct sreply *sreply, DB *db)
answer = (struct answer *)&reply[outlen];
} while (++ns_count < RECORD_COUNT && --sdns->ns_count);
+ /* add RRSIG */
+
+ if (dnssec && q->dnssecok) {
+ if (odh->answer)
+ odh->answer = htons(ns_count + 1);
+ else if (odh->nsrr)
+ odh->nsrr = htons(ns_count + 1);
+
+ outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_NS, sd, reply, replysize, outlen);
+ }
+
/* shuffle through our linked collect structure and add additional */
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
- int addcount;
- int tmplen;
+ int addcount = 0;
+ int tmplen = 0;
switch (cnp->type) {
case DNS_TYPE_A:
tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
+ if (addcount)
+ sdhave_a = cnp->sd;
+
additional += addcount;
break;
case DNS_TYPE_AAAA:
tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
+ if (addcount)
+ sdhave_aaaa = cnp->sd;
additional += addcount;
break;
}
if (tmplen > 0) {
outlen = tmplen;
+ }
+ }
+
+ /* Add RRSIG */
+
+ if (dnssec && q->dnssecok) {
+ if (sdhave_a) {
+ outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_A, sdhave_a, reply, replysize, outlen);
+ additional++;
+ }
+
+ if (sdhave_aaaa) {
+ outlen = additional_rrsig(q->hdr->name, q->hdr->namelen, INTERNAL_TYPE_AAAA, sdhave_aaaa, reply, replysize, outlen);
+ additional++;
+
}
}
repomaster@centroid.eu