]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
setup for appending subnet option in outbound replies and queries
authorYuri Schaeffer <yuri@nlnetlabs.nl>
Mon, 6 Aug 2012 15:37:51 +0000 (15:37 +0000)
committerYuri Schaeffer <yuri@nlnetlabs.nl>
Mon, 6 Aug 2012 15:37:51 +0000 (15:37 +0000)
git-svn-id: file:///svn/unbound/branches/edns-subnet@2742 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
services/localzone.c
services/mesh.c
services/outside_network.c
util/config_file.c
util/data/msgencode.c
util/data/msgparse.h
util/net_help.c
util/net_help.h

index 832278fc3d5923768584fefa7884695a4fc50328..6d6993afbf66af7b5545dedc8ff3cef8063aea41 100644 (file)
@@ -475,6 +475,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
                        edns->udp_size = EDNS_ADVERTISED_SIZE;
                        edns->ext_rcode = 0;
                        edns->bits &= EDNS_DO;
+                       edns->subnet_option_add = 0;
                        error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                                &msg->qinfo, id, flags, edns);
                        regional_free_all(worker->scratchpad);
@@ -503,6 +504,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
+       edns->subnet_option_add = 0;
        msg->rep->flags |= BIT_QR|BIT_RA;
        if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags, 
                repinfo->c->buffer, 0, 1, worker->scratchpad,
@@ -561,6 +563,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                edns->udp_size = EDNS_ADVERTISED_SIZE;
                edns->ext_rcode = 0;
                edns->bits &= EDNS_DO;
+               edns->subnet_option_add = 0;
                error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                        qinfo, id, flags, edns);
                rrset_array_unlock_touch(worker->env.rrset_cache, 
@@ -592,6 +595,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
+       edns->subnet_option_add = 0;
        if(!reply_info_answer_encode(qinfo, rep, id, flags, 
                repinfo->c->buffer, timenow, 1, worker->scratchpad,
                udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
@@ -665,6 +669,7 @@ chaos_replystr(ldns_buffer* pkt, const char* str, struct edns_data* edns)
        edns->edns_version = EDNS_ADVERTISED_VERSION;
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->bits &= EDNS_DO;
+       edns->subnet_option_add = 0;
        attach_edns_record(pkt, edns);
 }
 
@@ -816,6 +821,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
                edns.edns_version = EDNS_ADVERTISED_VERSION;
                edns.udp_size = EDNS_ADVERTISED_SIZE;
                edns.bits &= EDNS_DO;
+               edns.subnet_option_add = 0;
                verbose(VERB_ALGO, "query with bad edns version.");
                log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
                error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
index 98d69433e3083b1ed8eb1cf0200be679d03632a4..6a166e257e19763ee2e800e1fc185975aca2599e 100644 (file)
@@ -1010,6 +1010,7 @@ local_encode(struct query_info* qinfo, struct edns_data* edns,
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
+       edns->subnet_option_add = 0;
        if(!reply_info_answer_encode(qinfo, &rep, 
                *(uint16_t*)ldns_buffer_begin(buf),
                ldns_buffer_read_u16_at(buf, 2),
index f6fd288adf828ccec793215062c645a5240d7627..6d16412abb520ed0a430b7f78e1731d05836133e 100644 (file)
@@ -783,6 +783,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
                r->edns.udp_size = EDNS_ADVERTISED_SIZE;
                r->edns.ext_rcode = 0;
                r->edns.bits &= EDNS_DO;
+               r->edns.subnet_option_add = 0;
                if(!reply_info_answer_encode(&m->s.qinfo, rep, r->qid, 
                        r->qflags, r->buf, 0, 1, 
                        m->s.env->scratch, udp_size, &r->edns, 
@@ -854,6 +855,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                r->edns.udp_size = EDNS_ADVERTISED_SIZE;
                r->edns.ext_rcode = 0;
                r->edns.bits &= EDNS_DO;
+               r->edns.subnet_option_add = 0;
                m->s.qinfo.qname = r->qname;
                if(!reply_info_answer_encode(&m->s.qinfo, rep, r->qid, 
                        r->qflags, r->query_reply.c->buffer, 0, 1, 
index 24d65db399322cd066a3f6b73bb21564bbb19b03..3ee3e47a34f49d81084dc24a215925b8bbd4fa92 100644 (file)
@@ -1323,6 +1323,7 @@ serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns)
                edns.edns_present = 1;
                edns.ext_rcode = 0;
                edns.edns_version = EDNS_ADVERTISED_VERSION;
+               edns.subnet_option_add = 0;
                if(sq->status == serviced_query_UDP_EDNS_FRAG) {
                        if(addr_is_ip6(&sq->addr, sq->addrlen)) {
                                if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE)
index 6ab0c4a2c65469021ce6510a0ef352010ffae424..1e05a9ae7420bdf420d7bcab374a60fa95614398 100644 (file)
@@ -1091,6 +1091,7 @@ config_apply(struct config_file* config)
        MAX_TTL = (uint32_t)config->max_ttl;
        MIN_TTL = (uint32_t)config->min_ttl;
        EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
+       EDNS_SUBNET_OPC = (uint16_t)config->client_subnet_opc;
        MINIMAL_RESPONSES = config->minimal_responses;
        RRSET_ROUNDROBIN = config->rrset_roundrobin;
        log_set_time_asc(config->log_time_ascii);
index 157796deb95b1160d087f6e4d094654a63f5484d..c7cd60a96648850dabffd75c8c6933f4bc74c500 100644 (file)
@@ -728,7 +728,8 @@ calc_edns_field_size(struct edns_data* edns)
 void
 attach_edns_record(ldns_buffer* pkt, struct edns_data* edns)
 {
-       size_t len;
+       size_t len, sn_octs, sn_octs_remainder;
+       int i;
        if(!edns || !edns->edns_present)
                return;
        /* inc additional count */
@@ -744,7 +745,29 @@ attach_edns_record(ldns_buffer* pkt, struct edns_data* edns)
        ldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */
        ldns_buffer_write_u8(pkt, edns->edns_version);
        ldns_buffer_write_u16(pkt, edns->bits);
-       ldns_buffer_write_u16(pkt, 0); /* rdatalen */
+       /* YBS: do vandergaast hier! */
+       if(edns->subnet_option_add) {
+               assert(edns.addr_fam == 0x01 || edns.addr_fam == 0x02);
+               assert(edns.addr_fam != 0x01 || edns->subnet_source_mask <=  32);
+               assert(edns.addr_fam != 0x02 || edns->subnet_source_mask <= 128); //ipv6 addr fam?
+
+               sn_octs = edns->subnet_source_mask / 8;
+               sn_octs_remainder = !!(edns->subnet_source_mask % 8);
+               
+               ldns_buffer_write_u16(pkt, sn_octs + sn_octs_remainder + 4 + 4); /* rdatalen */
+               ldns_buffer_write_u16(pkt, EDNS_SUBNET_OPC); /* opc */
+               ldns_buffer_write_u16(pkt, sn_octs + sn_octs_remainder + 4); /* datalen */
+               ldns_buffer_write_u16(pkt, edns->subnet_addr_fam); /* addr fam */
+               ldns_buffer_write_u8(pkt,  edns->subnet_source_mask); /* source mask */
+               ldns_buffer_write_u8(pkt,  edns->subnet_scope_mask); /* scope mask */
+
+               for(i = 0; i<sn_octs; i++)
+                       ldns_buffer_write_u8(pkt, edns->subnet_addr[i]);
+               if(sn_octs_remainder)
+                               ldns_buffer_write_u8(pkt, edns->subnet_addr[sn_octs] & 
+                                               ~(1<<(8-(edns->subnet_source_mask % 8))-1));
+       } else ldns_buffer_write_u16(pkt, 0); /* rdatalen */
+       /* //YBS: do vandergaast hier! */
        ldns_buffer_flip(pkt);
 }
 
index 830d68e16cd677fed94f4adfecab73f3c9a99ae4..85c51289af25bf49f2eb6ac30a025b62e89dc493 100644 (file)
@@ -211,6 +211,13 @@ struct edns_data {
        uint16_t bits;
        /** UDP reassembly size. */
        uint16_t udp_size;
+       // YBS add vandergaast here
+       int             subnet_option_add;
+       uint16_t        subnet_addr_fam;
+       uint8_t         subnet_source_mask;
+       uint8_t         subnet_scope_mask;
+       uint8_t         subnet_addr[16];
+       // YBS add vandergaast here
 };
 
 /**
index 6be5fcc3132ad7f27b2b6639fa808b616258d654..2a8713c3d2363857aaf092ff37568a331780a313 100644 (file)
@@ -52,6 +52,8 @@
 #define MAX_ADDR_STRLEN 128 /* characters */
 /** default value for EDNS ADVERTISED size */
 uint16_t EDNS_ADVERTISED_SIZE = 4096;
+/** YBS: opcode for edns subnet option, is TBD. */
+uint16_t EDNS_SUBNET_OPC = 0x50fa;
 
 /** minimal responses when positive answer: default is no */
 int MINIMAL_RESPONSES = 0;
index e0c0ebea17572e081ec17c4fe3ee05e782250b1e..f8a3da9987e1f7e05539b9abb568e6c93e34e7cb 100644 (file)
@@ -81,6 +81,8 @@ struct regional;
 #define EDNS_ADVERTISED_VERSION         0
 /** Advertised size of EDNS capabilities */
 extern uint16_t EDNS_ADVERTISED_SIZE;
+/** YBS: opcode for edns subnet option, is TBD. */
+extern uint16_t EDNS_SUBNET_OPC;
 /** bits for EDNS bitfield */
 #define EDNS_DO 0x8000 /* Dnssec Ok */
 /** byte size of ip4 address */