]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Merge branch 'master' into features/rfc8914-ede
authorTom Carpay <tom@nlnetlabs.nl>
Mon, 15 Nov 2021 14:48:35 +0000 (14:48 +0000)
committerTom Carpay <tom@nlnetlabs.nl>
Mon, 15 Nov 2021 14:48:35 +0000 (14:48 +0000)
1  2 
daemon/worker.c
services/localzone.c
services/mesh.c
util/config_file.c
util/config_file.h
util/data/msgparse.c
util/data/msgparse.h
util/data/msgreply.c
util/data/msgreply.h

diff --cc daemon/worker.c
index bd7567b34fb6f0e36eacb6a0ba50108ac5dd0d98,5d2483cd2cd94060eab85a66c8c76049bf260174..5c05631ad03fd1f02d245887dceb81ff4bafcd1d
@@@ -485,8 -484,6 +484,8 @@@ answer_norec_from_cache(struct worker* 
                                msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
                                worker->env.now_tv))
                                        return 0;
-                       EDNS_OPT_APPEND_EDE(edns, worker->scratchpad,
-                               LDNS_EDE_DNSSEC_BOGUS, "");
++                      EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
++                              worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
                        error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                                &msg->qinfo, id, flags, edns);
                        if(worker->stats.extended) {
                        secure = 1;
                        break;
                case sec_status_indeterminate:
-                       EDNS_OPT_APPEND_EDE(edns, worker->scratchpad,
-                               LDNS_EDE_DNSSEC_INDETERMINATE, "");
++                      EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
++                              worker->scratchpad, LDNS_EDE_DNSSEC_INDETERMINATE, "");
++
                case sec_status_insecure:
                default:
                        /* not secure */
@@@ -663,8 -654,6 +659,8 @@@ answer_from_cache(struct worker* worker
                        LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
                        worker->env.now_tv))
                        goto bail_out;
-               EDNS_OPT_APPEND_EDE(edns, worker->scratchpad,
-                       LDNS_EDE_DNSSEC_BOGUS, "");
++              EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
++                      worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
                error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
                        qinfo, id, flags, edns);
                rrset_array_unlock_touch(worker->env.rrset_cache,
@@@ -1521,12 -1382,9 +1500,12 @@@ worker_handle_request(struct comm_point
         * ACLs allow the snooping. */
        if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
                acl != acl_allow_snoop ) {
-               EDNS_OPT_APPEND_EDE(&edns, worker->scratchpad,
-                       LDNS_EDE_NOT_AUTHORITATIVE, "");
 +              edns.opt_list = NULL;
++              EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
++                      worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
                error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
                        *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
 -                      sldns_buffer_read_u16_at(c->buffer, 2), NULL);
 +                      sldns_buffer_read_u16_at(c->buffer, 2), &edns);
                regional_free_all(worker->scratchpad);
                log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
                        &repinfo->addr, repinfo->addrlen);
@@@ -1603,16 -1460,6 +1582,16 @@@ lookup_cache
                                                < *worker->env.now)
                                                leeway = 0;
                                        lock_rw_unlock(&e->lock);
-                                       //      EDNS_OPT_APPEND_EDE(&edns, worker->scratchpad,
 +
 +                                      // // stale answer? 
 +                                      // if (worker->env.cfg->serve_expired &&
 +                                      //      *worker->env.now >= ((struct reply_info*)e->data)->ttl) {
 +                                      //      // EDE Error Code 3 - Stale Answer
++                                      //      EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out, worker->scratchpad,
 +                                      // LDNS_EDE_STALE_ANSWER, "");
 +                                      // }
 +
 +                                      // add EDNS struct?
                                        reply_and_prefetch(worker, lookup_qinfo,
                                                sldns_buffer_read_u16_at(c->buffer, 2),
                                                repinfo, leeway,
index c6ed979fb08d7cc6174c16208e37bc074810e52d,a69aef8fd2d0f0a1f2682ec8d34d4213c2276671..d74191f9a96a9fdfc376d57ad913a4678e25505d
@@@ -1281,48 -1286,6 +1286,48 @@@ local_encode(struct query_info* qinfo, 
        return 1;
  }
  
-               edns_opt_append_ede(edns, temp, ede_code, ede_txt);
 +/** encode answer consisting of 1 rrset (with EDE code) */
 +static int
 +local_encode_ede(struct query_info* qinfo, struct module_env* env,
 +      struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
 +      struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
 +      int rcode, sldns_ede_code ede_code, const char* ede_txt)
 +{
 +      struct reply_info rep;
 +      uint16_t udpsize;
 +      /* make answer with time=0 for fixed TTL values */
 +      memset(&rep, 0, sizeof(rep));
 +      rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
 +      rep.qdcount = 1;
 +      if(ansec)
 +              rep.an_numrrsets = 1;
 +      else    rep.ns_numrrsets = 1;
 +      rep.rrset_count = 1;
 +      rep.rrsets = &rrset;
 +      udpsize = edns->udp_size;
 +      edns->edns_version = EDNS_ADVERTISED_VERSION;
 +      edns->udp_size = EDNS_ADVERTISED_SIZE;
 +      edns->ext_rcode = 0;
 +      edns->bits &= EDNS_DO;
 +      if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
 +              repinfo, temp, env->now_tv)) {
 +              error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
 +                      *(uint16_t*)sldns_buffer_begin(buf),
 +                      sldns_buffer_read_u16_at(buf, 2), edns);
 +      } else {
++              edns_opt_list_append_ede(&edns->opt_list_out, temp, ede_code, ede_txt);
 +
 +              if(!reply_info_answer_encode(qinfo, &rep,
 +                      *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
 +                      buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
 +                      error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
 +                              *(uint16_t*)sldns_buffer_begin(buf),
 +                              sldns_buffer_read_u16_at(buf, 2), edns);
 +              }
 +      }
 +      return 1;
 +}
 +
  /** encode local error answer */
  static void
  local_error_encode(struct query_info* qinfo, struct module_env* env,
  
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
                rcode, edns, repinfo, temp, env->now_tv))
-               edns->opt_list = NULL;
+               edns->opt_list_inplace_cb_out = NULL;
 +      if(ede_code >= 0 && env->cfg->local_data_do_ede)
-               edns_opt_append_ede(edns, temp, ede_code, ede_txt);
++              edns_opt_list_append_ede(&edns->opt_list_out, temp, ede_code, ede_txt);
        error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
                sldns_buffer_read_u16_at(buf, 2), edns);
  }
@@@ -1651,13 -1618,15 +1667,15 @@@ local_zones_zone_answer(struct local_zo
                 */
                int rcode = (ld || lz_type == local_zone_redirect ||
                        lz_type == local_zone_inform_redirect ||
-                       lz_type == local_zone_always_nodata)?
+                       lz_type == local_zone_always_nodata ||
+                       lz_type == local_zone_truncate)?
                        LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
-               if(z->soa && z->soa_negative)
+               rcode = (lz_type == local_zone_truncate ? (rcode|BIT_TC) : rcode);
+               if(z != NULL && z->soa && z->soa_negative)
                        return local_encode(qinfo, env, edns, repinfo, buf, temp,
                                z->soa_negative, 0, rcode);
 -              local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
 -                      (rcode|BIT_AA));
 +              local_error_encode(qinfo, env, edns, repinfo, buf, temp,
 +                      rcode, (rcode|BIT_AA), LDNS_EDE_BLOCKED, "");
                return 1;
        } else if(lz_type == local_zone_typetransparent
                || lz_type == local_zone_always_transparent) {
         * does not, then we should make this noerror/nodata */
        if(ld && ld->rrsets) {
                int rcode = LDNS_RCODE_NOERROR;
-               if(z->soa && z->soa_negative)
+               if(z != NULL && z->soa && z->soa_negative)
                        return local_encode(qinfo, env, edns, repinfo, buf, temp,
                                z->soa_negative, 0, rcode);
 +              /* NODATA: No EDE needed */
                local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
 -                      (rcode|BIT_AA));
 +                      (rcode|BIT_AA), -1, NULL);
                return 1;
        }
  
diff --cc services/mesh.c
index 4f1cb83d97b1a9f21b2c40393a792527c7741cb0,d2a1c68567436c07eb3a7211cbbaf0e6b0f589f1..fae8bee787b79e269802bb46e944f508530a78f9
@@@ -1269,24 -1288,8 +1288,24 @@@ mesh_send_reply(struct mesh_state* m, i
                } else { 
                        if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
                                &r->edns, &r->query_reply, m->s.region, &r->start_time))
-                                       r->edns.opt_list = NULL;
+                                       r->edns.opt_list_inplace_cb_out = NULL;
                }
-                       edns_opt_append_ede(&r->edns, m->s.region,
 +              /* Send along EDE BOGUS EDNS0 option when answer is bogus */
 +              if(rcode == LDNS_RCODE_SERVFAIL &&
 +                      m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
 +                      m->s.env->cfg->ignore_cd) && rep &&
 +                      (rep->security <= sec_status_bogus ||
 +                      rep->security == sec_status_secure_sentinel_fail)) {
 +
 +                      char *reason = m->s.env->cfg->val_log_level >= 2
 +                                   ? errinf_to_str_bogus(&m->s) : NULL;
 +                      sldns_ede_code reason_bogus = rep->reason_bogus != LDNS_EDE_DNSSEC_BOGUS
 +                                                  ? rep->reason_bogus : errinf_to_reason_bogus(&m->s);
 +
++                      edns_opt_list_append_ede(&r->edns.opt_list_out, m->s.region,
 +                                      reason_bogus, reason);
 +                      free(reason);
 +              }
                error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
                        r->qflags, &r->edns);
                m->reply_list = NULL;
                {
                        if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
                        rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
-                               r->edns.opt_list = NULL;
+                               r->edns.opt_list_inplace_cb_out = NULL;
 +                      // @TODO EDE?
                        error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
                                &m->s.qinfo, r->qid, r->qflags, &r->edns);
                }
Simple merge
Simple merge
Simple merge
index 981f53d4631d7f4ee79dead0a93155302cee997f,4c0559a739a4e755c756e5d83f8c13c0074a603d..860e8ff0561b45dd0b0852ec832682f65447a2ce
@@@ -281,17 -290,9 +290,17 @@@ int parse_packet(struct sldns_buffer* p
   * @return: 0 on success. or an RCODE on an error.
   *    RCODE formerr if OPT in wrong section, and so on.
   */
- int parse_extract_edns(struct msg_parse* msg, struct edns_data* edns,
-       struct regional* region);
+ int parse_extract_edns_from_response_msg(struct msg_parse* msg,
+       struct edns_data* edns, struct regional* region);
  
 +/** 
 + * Skip RRs from packet 
 + * @param pkt:the packet. position at start must be right after the query
 + *    section. At end, right after EDNS data or no movement if failed.
 + * @param num: Limit of the number of records we want to parse.
 + * @return: 0 on success, 1 on failure*/
 +int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
 +
  /**
   * If EDNS data follows a query section, extract it and initialize edns struct.
   * @param pkt: the packet. position at start must be right after the query
index 0947a495cae74f382baf286c7900667f9067b5a2,ec46e47247800e3b5e3cdf028f5e191f5202781c..69427d455cf23b7866cb450dbf141127e2ab3d3b
@@@ -960,63 -989,6 +990,35 @@@ parse_reply_in_temp_region(sldns_buffer
        return rep;
  }
  
- int edns_opt_append(struct edns_data* edns, struct regional* region,
-       uint16_t code, size_t len, uint8_t* data)
- {
-       struct edns_option** prevp;
-       struct edns_option* opt;
-       /* allocate new element */
-       opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
-       if(!opt)
-               return 0;
-       opt->next = NULL;
-       opt->opt_code = code;
-       opt->opt_len = len;
-       opt->opt_data = NULL;
-       if(len > 0) {
-               opt->opt_data = regional_alloc_init(region, data, len);
-               if(!opt->opt_data)
-                       return 0;
-       }
-       
-       /* append at end of list */
-       prevp = &edns->opt_list;
-       while(*prevp != NULL)
-               prevp = &((*prevp)->next);
-       *prevp = opt;
-       return 1;
- }
- int edns_opt_append_ede(struct edns_data* edns, struct regional* region,
++int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
 +      sldns_ede_code code, const char *txt)
 +{
 +      struct edns_option** prevp;
 +      struct edns_option* opt;
 +      size_t txt_len = txt ? strlen(txt) : 0;
 +
 +      /* allocate new element */
 +      opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
 +      if(!opt)
 +              return 0;
 +      opt->next = NULL;
 +      opt->opt_code = LDNS_EDNS_EDE;
 +      opt->opt_len = txt_len + sizeof(uint16_t);
 +      opt->opt_data = regional_alloc(region, txt_len + sizeof(uint16_t));
 +      if(!opt->opt_data)
 +              return 0;
 +      sldns_write_uint16(opt->opt_data, (uint16_t)code);
 +      if (txt_len)
 +              memmove(opt->opt_data + 2, txt, txt_len);
 +
 +      /* append at end of list */
-       prevp = &edns->opt_list;
++      prevp = list;
 +      while(*prevp != NULL)
 +              prevp = &((*prevp)->next);
 +      *prevp = opt;
 +      return 1;
 +}
 +
  int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
        uint8_t* data, struct regional* region)
  {
index 1fbcbac45e040b6f6c65839f29afb4cb3abaf345,81c763fc7c3a247f04a5519594581e09ec175c4f..88e37f5b38122e69336682f82a8a1452e4837a10
@@@ -516,52 -524,12 +530,41 @@@ void log_query_info(enum verbosity_valu
   * @param code: the edns option's code.
   * @param len: the edns option's length.
   * @param data: the edns option's data.
+  * @param region: region to allocate the new edns option.
   * @return false on failure.
   */
- int edns_opt_append(struct edns_data* edns, struct regional* region,
-       uint16_t code, size_t len, uint8_t* data);
+ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
+       uint8_t* data, struct regional* region);
  
-  * @param EDNS: the edns data structure to append the edns option to.
 +/**
 + * Append edns EDE option to edns options list
- #define EDNS_OPT_APPEND_EDE(EDNS, REGION, CODE, TXT)                  \
++ * @param LIST: the edns option list to append the edns option to.
 + * @param REGION: region to allocate the new edns option.
 + * @param CODE: the EDE code.
 + * @param TXT: Additional text for the option
 + */
-               edns_opt_append((EDNS), (REGION), LDNS_EDNS_EDE,        \
++#define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT)                     \
 +      do {                                                            \
 +              struct {                                                \
 +                      uint16_t code;                                  \
 +                      char text[sizeof(TXT) - 1];                     \
 +              } ede = { htons(CODE), TXT };                           \
-  * @param edns: the edns data structure to append the edns option to.
++              edns_opt_list_append((LIST), (REGION), LDNS_EDNS_EDE,   \
 +                      sizeof(uint16_t) + sizeof(TXT) - 1,             \
 +                      (void *)&ede);                                  \
 +      } while(0)
 +
 +/**
 + * Append edns EDE option to edns options list
- int edns_opt_append_ede(struct edns_data* edns, struct regional* region,
++ * @param list: the edns option list to append the edns option to.
 + * @param region: region to allocate the new edns option.
 + * @param code: the EDE code.
 + * @param txt: Additional text for the option
 + * @return false on failure.
 + */
- /**
-  * Append edns option to edns option list
-  * @param list: the edns option list to append the edns option to.
-  * @param code: the edns option's code.
-  * @param len: the edns option's length.
-  * @param data: the edns option's data.
-  * @param region: region to allocate the new edns option.
-  * @return false on failure.
-  */
- int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
-       uint8_t* data, struct regional* region);
++int edns_opt_append_ede(struct edns_option* list, struct regional* region,
 +      sldns_ede_code code, const char *txt);
 +
  /**
   * Remove any option found on the edns option list that matches the code.
   * @param list: the list of edns options.