]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
more straightforward way of managing edns communication
authorYuri Schaeffer <yuri@nlnetlabs.nl>
Thu, 21 Mar 2013 15:10:53 +0000 (15:10 +0000)
committerYuri Schaeffer <yuri@nlnetlabs.nl>
Thu, 21 Mar 2013 15:10:53 +0000 (15:10 +0000)
git-svn-id: file:///svn/unbound/branches/edns-subnet@2867 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
edns-subnet/subnetmod.c
iterator/iterator.c
libunbound/libworker.c
services/mesh.c
validator/validator.c

index d3860ffce17b71cb3c04c5db80a53f257efc25c5..22819e598c0da8e2ddf78aa525f9f58a194d6fdb 100644 (file)
@@ -1282,7 +1282,7 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
                addrlen, zone, zonelen, worker_handle_service_reply, e,
                worker->back->udp_buff
 #ifdef CLIENT_SUBNET
-               , &q->edns_out
+               , &q->edns_server_out
 #endif
                );
        if(!e->qsent) {
index d1101c173d909c6b08a7bb4f0491c54e6ad817ce..91bf9593e1b76617807aac6c22bde687e95527b5 100644 (file)
@@ -73,30 +73,28 @@ void cp_edns_bad_response(struct edns_data* target, struct edns_data* source)
 
 enum module_ext_state eval_response(struct module_qstate* qstate)
 {
-       if (!qstate->edns_out.subnet_sent) {
-               if (qstate->edns_in.subnet_validdata)
+       if (!qstate->edns_server_out.subnet_sent) {
+               if (qstate->edns_server_in.subnet_validdata)
                        verbose(VERB_QUERY, "subnet: received spurious data");
-               if (qstate->edns_out.subnet_downstream) {
+               if (qstate->edns_client_in.subnet_downstream) {
                        /* Copy question back to client */
-                       qstate->edns_to_client = &qstate->edns_in;
-                       cp_edns_bad_response(qstate->edns_to_client, 
-                                                               qstate->edns_from_client);
+                       cp_edns_bad_response(&qstate->edns_client_out, 
+                                                               &qstate->edns_client_in);
                }
                return module_finished;
        }
        
        /* subnet sent but nothing came back */
-       if (!qstate->edns_in.subnet_validdata) {
+       if (!qstate->edns_server_in.subnet_validdata) {
                /** The authority indicated no support for vandergaast. As a
                 * consequence the answer ended up in the regular cache. It
                 * is still usefull to put it in the vandergaast cache for 
                 * when a client explicitly asks for subnet specific answer. */
                verbose(VERB_QUERY, "subnet: Authority indicates no support");
                // TODO PUT IT IN OUR SPECIAL CACHE
-               if (qstate->edns_out.subnet_downstream) {
-                       qstate->edns_to_client = &qstate->edns_in;
-                       cp_edns_bad_response(qstate->edns_to_client, 
-                                                               qstate->edns_from_client);
+               if (qstate->edns_client_in.subnet_downstream) {
+                       cp_edns_bad_response(&qstate->edns_client_out, 
+                                                               &qstate->edns_client_in);
                }
                return module_finished;
        }
@@ -106,29 +104,31 @@ enum module_ext_state eval_response(struct module_qstate* qstate)
        
        /* can we accept response? */
        size_t sn_octs, remainder;
-       sn_octs = qstate->edns_out.subnet_source_mask / 8;
+       sn_octs = qstate->edns_server_out.subnet_source_mask / 8;
        assert(sn_octs <= INET6_SIZE); /* Enforced by msgparse */
-       remainder = 8 - (size_t)(qstate->edns_out.subnet_source_mask % 8);
-       if(qstate->edns_out.subnet_addr_fam != qstate->edns_in.subnet_addr_fam ||
-               qstate->edns_out.subnet_source_mask != qstate->edns_in.subnet_source_mask ||
-               memcmp(qstate->edns_out.subnet_addr, qstate->edns_in.subnet_addr, sn_octs) != 0 ||
-               (qstate->edns_out.subnet_addr[sn_octs]^qstate->edns_in.subnet_addr[sn_octs])>>remainder) {
+       remainder = 8 - (size_t)(qstate->edns_server_out.subnet_source_mask % 8);
+       if(qstate->edns_server_out.subnet_addr_fam != qstate->edns_server_in.subnet_addr_fam ||
+               qstate->edns_server_out.subnet_source_mask != qstate->edns_server_in.subnet_source_mask ||
+               memcmp(qstate->edns_server_out.subnet_addr, qstate->edns_server_in.subnet_addr, sn_octs) != 0 ||
+               //YBS should this just be equal?
+               (qstate->edns_server_out.subnet_addr[sn_octs]^qstate->edns_server_in.subnet_addr[sn_octs])>>remainder) {
                /* we can not, restart query without option */
                verbose(VERB_QUERY, "subnet: forged data");
-               qstate->edns_out.subnet_validdata = 0;
-               qstate->edns_out.subnet_sent = 0;
+               qstate->edns_server_out.subnet_validdata = 0;
+               qstate->edns_server_out.subnet_sent = 0;
                return module_wait_module;
        }
        
        /* TODO PUT IT IN OUR SPECIAL CACHE */
        
-       if (qstate->edns_out.subnet_downstream) {
+       if (qstate->edns_client_in.subnet_downstream) {
                /* Client wants to see the answer, echo option back
                 * and adjust the scope. */
-               qstate->edns_to_client = qstate->edns_from_client;
+               memcpy(&qstate->edns_client_out, &qstate->edns_client_in, 
+                       sizeof(qstate->edns_client_in));
                verbose(VERB_QUERY, "subnet: attach");
-               qstate->edns_to_client->subnet_scope_mask = 
-                       qstate->edns_in.subnet_scope_mask;
+               qstate->edns_client_out.subnet_scope_mask = 
+                       qstate->edns_server_in.subnet_scope_mask;
        }
        verbose(VERB_QUERY, "subnet: done");
        return module_finished;
@@ -141,7 +141,6 @@ void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
        void* cachehit;
        int max_mask;
 #endif
-       struct edns_data* edns_from_client;
        struct subnet_env* sne = (struct subnet_env*)qstate->env->modinfo[id];
        struct subnet_qstate* snq = (struct subnet_qstate*)qstate->minfo[id];
        
@@ -151,20 +150,18 @@ void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
        log_query_info(VERB_QUERY, "subnet operate: query", &qstate->qinfo);
 
        if(event == module_event_new) {
-               edns_from_client = qstate->edns_from_client;
-               
-               if(!edns_from_client || !edns_from_client->subnet_validdata) {
+               if(!qstate->edns_client_in.subnet_validdata) {
                        /* No clients are interested in result or we could not
                         * parse it, we don't do client subnet */
-                       qstate->edns_out.subnet_validdata = 0;
+                       qstate->edns_server_out.subnet_validdata = 0;
                        verbose(VERB_ALGO, "subnet: pass to next module");
                        qstate->ext_state[id] = module_wait_module;
                        return;
                }
                /* copy information from client request to upstream query */
-               memcpy(&qstate->edns_out, edns_from_client, sizeof(struct edns_data));
-               qstate->edns_out.subnet_scope_mask = 0;
-               qstate->edns_out.subnet_sent = 0;
+               memcpy(&qstate->edns_server_out, &qstate->edns_client_in, sizeof(struct edns_data));
+               qstate->edns_server_out.subnet_scope_mask = 0;
+               qstate->edns_server_out.subnet_sent = 0;
 #if 0
                while(1) {
                        /* cache returns valid answer with largest mask. */
@@ -223,7 +220,6 @@ void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
        /* Query handed back by next module, we have a 'final' answer */
        if(event == module_event_moddone) {
                verbose(VERB_QUERY, "subnet: done");
-               qstate->edns_to_client = NULL;
                qstate->ext_state[id] = eval_response(qstate);
                return;
        }
index 8885832a6f7a73d2b04dcd085edd800b744230e8..f0f9ef427fa5f743ead3d9bb463d02709618e17c 100644 (file)
@@ -1934,8 +1934,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                }
 #ifdef CLIENT_SUBNET
                /* Do not cache, we asked for and got subnet option */
-               if(!qstate->edns_in.subnet_validdata || 
-                       !qstate->edns_out.subnet_sent) {
+               if(!qstate->edns_server_in.subnet_validdata || 
+                       !qstate->edns_server_out.subnet_sent) {
 #endif
                iter_dns_store(qstate->env, &iq->response->qinfo,
                        iq->response->rep, 0, qstate->prefetch_leeway,
@@ -2740,7 +2740,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
        }
        memset(prs, 0, sizeof(*prs));
 #ifdef CLIENT_SUBNET
-       memset(&qstate->edns_in, 0, sizeof(qstate->edns_in));
+       memset(&qstate->edns_server_in, 0, sizeof(qstate->edns_server_in));
 #else
        memset(&edns, 0, sizeof(edns));
 #endif
@@ -2751,7 +2751,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
                goto handle_it;
        }
 #ifdef CLIENT_SUBNET
-       if(parse_extract_edns(prs, &qstate->edns_in) != LDNS_RCODE_NOERROR)
+       if(parse_extract_edns(prs, &qstate->edns_server_in) != LDNS_RCODE_NOERROR)
 #else
        /* edns is not examined, but removed from message to help cache */
        if(parse_extract_edns(prs, &edns) != LDNS_RCODE_NOERROR)
index 2bad0ba6056c144e34dcf089043c552dba4615ca..d6c28b4240058de4f5aaeb8d2f039f31208f1d05 100644 (file)
@@ -752,7 +752,7 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
                addrlen, zone, zonelen, libworker_handle_service_reply, e,
                w->back->udp_buff
 #ifdef CLIENT_SUBNET
-               , &q->edns_out
+               , &q->edns_server_out
 #endif
                );
 
index 43474101f11103c40458e3fcfdc18e9e70ee62de..bcb3d447dcd3fd29025b215ab3022f5381ccf694 100644 (file)
@@ -128,31 +128,21 @@ timeval_smaller(const struct timeval* x, const struct timeval* y)
 /** Returns a==b: 0, a<b: positive, a>b: negative */
 int subnet_compare(struct edns_data *a, struct edns_data *b)
 {
-       if (!a) {
-               if (b) return 1;
-               return 0;
-       } else {
-               if (!b) return -1;
-               /* crude way:
-                * return  memcmp(b, a, sizeof(struct edns_data)); */
-               
-               if ( a->edns_present && !b->edns_present) return -1;
-               if (!a->edns_present && !b->edns_present) return  0;
-               if (!a->edns_present &&  b->edns_present) return  1;
+       if ( a->edns_present && !b->edns_present) return -1;
+       if (!a->edns_present && !b->edns_present) return  0;
+       if (!a->edns_present &&  b->edns_present) return  1;
 
-               if ( a->subnet_validdata && !b->subnet_validdata) return -1;
-               if (!a->subnet_validdata && !b->subnet_validdata) return  0;
-               if (!a->subnet_validdata &&  b->subnet_validdata) return  1;
-               
-               if (a->subnet_addr_fam != b->subnet_addr_fam) {
-                       return b->subnet_addr_fam - a->subnet_addr_fam;
-               }
-               if (a->subnet_source_mask != b->subnet_source_mask) {
-                       return b->subnet_source_mask - a->subnet_source_mask;
-               }
-               return memcmp(b->subnet_addr, a->subnet_addr, INET6_SIZE);
-               
+       if ( a->subnet_validdata && !b->subnet_validdata) return -1;
+       if (!a->subnet_validdata && !b->subnet_validdata) return  0;
+       if (!a->subnet_validdata &&  b->subnet_validdata) return  1;
+       
+       if (a->subnet_addr_fam != b->subnet_addr_fam) {
+               return b->subnet_addr_fam - a->subnet_addr_fam;
        }
+       if (a->subnet_source_mask != b->subnet_source_mask) {
+               return b->subnet_source_mask - a->subnet_source_mask;
+       }
+       return memcmp(b->subnet_addr, a->subnet_addr, INET6_SIZE);
 }
 #endif
 
@@ -183,7 +173,7 @@ mesh_state_compare(const void* ap, const void* bp)
                return 1;
 
 #ifdef CLIENT_SUBNET
-       r = subnet_compare(a->s.edns_from_client, b->s.edns_from_client);
+       r = subnet_compare(&a->s.edns_client_in, &b->s.edns_client_in);
        if (r != 0) return r;
 #endif
        return query_info_compare(&a->s.qinfo, &b->s.qinfo);
@@ -425,7 +415,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
                }
 #endif /* INET6 */
        }
-       s->s.edns_from_client = edns;
+       memcpy(&s->s.edns_client_in, edns, sizeof(struct edns_data));
 #endif /* CLIENT_SUBNET */
        /* update statistics */
        if(was_detached) {
@@ -624,10 +614,6 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
        mstate->s.env = env;
        mstate->s.mesh_info = mstate;
        mstate->s.prefetch_leeway = 0;
-#ifdef CLIENT_SUBNET
-       mstate->s.edns_from_client = NULL;
-       mstate->s.edns_to_client = NULL;
-#endif
        /* init modules */
        for(i=0; i<env->mesh->mods.num; i++) {
                mstate->s.minfo[i] = NULL;
@@ -964,12 +950,12 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                r->edns.ext_rcode = 0;
                r->edns.bits &= EDNS_DO;
 #ifdef CLIENT_SUBNET
-               if(m->s.edns_to_client && m->s.edns_to_client->subnet_validdata) {
+               if(m->s.edns_client_out.subnet_validdata) {
                        r->edns.subnet_validdata = 1;
-                       r->edns.subnet_addr_fam    = m->s.edns_to_client->subnet_addr_fam;
-                       r->edns.subnet_source_mask = m->s.edns_to_client->subnet_source_mask;
-                       r->edns.subnet_scope_mask  = m->s.edns_to_client->subnet_scope_mask;
-                       memcpy(r->edns.subnet_addr, m->s.edns_to_client->subnet_addr, INET6_SIZE);
+                       r->edns.subnet_addr_fam    = m->s.edns_client_out.subnet_addr_fam;
+                       r->edns.subnet_source_mask = m->s.edns_client_out.subnet_source_mask;
+                       r->edns.subnet_scope_mask  = m->s.edns_client_out.subnet_scope_mask;
+                       memcpy(r->edns.subnet_addr, m->s.edns_client_out.subnet_addr, INET6_SIZE);
                } else r->edns.subnet_validdata = 0;
 #endif
                m->s.qinfo.qname = r->qname;
@@ -1047,7 +1033,8 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
        key.s.qinfo = *qinfo;
        key.s.query_flags = qflags;
 #ifdef CLIENT_SUBNET
-       key.s.edns_from_client = NULL; /* is used in subnet cmp function */
+       key.s.edns_client_in.edns_present = 0;
+       key.s.edns_client_in.subnet_validdata = 0;
 #endif
 
        result = (struct mesh_state*)rbtree_search(&mesh->all, &key);
index 139511c5d437968bcf4ed4c78745d246116a57ea..c90e57ebcc9b1d5d3936660e61526b6fcfec1015 100644 (file)
@@ -1985,8 +1985,8 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
 
 #ifdef CLIENT_SUBNET
        /* Do not cache, we asked for and got subnet option */
-       if(!qstate->edns_in.subnet_validdata || 
-               !qstate->edns_out.subnet_sent) {
+       if(!qstate->edns_server_in.subnet_validdata || 
+               !qstate->edns_server_out.subnet_sent) {
 #endif
        /* store results in cache */
        if(qstate->query_flags&BIT_RD) {