}
}
+/** check if the lookup target name equals the found answer name. */
+static int
+xfer_target_equals_answer_name(struct auth_master* lookup_target,
+ struct ub_packed_rrset_key* answer, struct query_info* rq,
+ struct reply_info* rep)
+{
+ uint8_t qname[LDNS_MAX_DOMAINLEN+1];
+ size_t qname_len;
+ if(!lookup_target) return 0;
+ if(!answer) return 0;
+ qname_len = sizeof(qname);
+ if(sldns_str2wire_dname_buf(lookup_target->host, qname, &qname_len)
+ != 0) {
+ verbose(VERB_ALGO, "xfer_target_equals_answer_name: could not parse auth host name");
+ return 0;
+ }
+ if(query_dname_compare(answer->rk.dname, qname) == 0)
+ return 1;
+ /* It could be a CNAME. */
+ if(reply_find_rrset_section_an(rep, qname, qname_len,
+ LDNS_RR_TYPE_CNAME, rq->qclass))
+ return 1;
+ return 0;
+}
+
/** callback for task_transfer lookup of host name, of A or AAAA */
void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
- enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
- int ATTR_UNUSED(was_ratelimited))
+ enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
{
struct auth_xfer* xfr = (struct auth_xfer*)arg;
struct module_env* env;
{
struct rrset_ref ref;
uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
+ uint8_t* new_dname;
+ size_t new_dname_len;
+
+ /* See if the RRSIG signer name allows this wildcard,
+ * the new rrset should fall within the zone of the RRSIG signer(s). */
+ if(!dname_subdomain_rrsig_signers(ce, rrset)) {
+ verbose(VERB_ALGO, "wildcard canonical parent outside signer authority");
+ return;
+ }
+
rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
if(!rrset) {
log_err("malloc failure in rrset_cache_update_wildcard");
while(open) {
nopen = open->next;
mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp,
-- NULL);
++ NULL, NULL);
free(open);
open = nopen;
}
if(!node)
return;
stream = (struct doq_stream*)node;
- args->conn->doq_socket->cp, stream);
+ if(stream->mesh_state) {
+ mesh_state_remove_reply(stream->mesh, stream->mesh_state,
++ args->conn->doq_socket->cp, NULL, stream);
+ stream->mesh_state = NULL;
+ }
if(stream->in)
doq_table_quic_size_subtract(table, stream->inlen);
if(stream->out)
lock_rw_unlock(&conn->table->conid_lock);
/* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
* because the ngtcp2 conn is deleted. */
- SSL_set_app_data(conn->ssl, NULL);
+ if(conn->ssl)
+ SSL_set_app_data(conn->ssl, NULL);
if(conn->stream_tree.count != 0) {
- traverse_postorder(&conn->stream_tree, stream_tree_del, table);
+ struct doq_stream_tree_del_args args;
+ memset(&args, 0, sizeof(args));
+ args.table = table;
+ args.conn = conn;
+ traverse_postorder(&conn->stream_tree, stream_tree_del, &args);
}
free(conn->key.dcid);
SSL_free(conn->ssl);
if(stream->is_closed)
return 1;
stream->is_closed = 1;
- conn->doq_socket->cp, stream);
+ if(stream->mesh_state) {
+ mesh_state_remove_reply(stream->mesh, stream->mesh_state,
++ conn->doq_socket->cp, NULL, stream);
+ stream->mesh_state = NULL;
+ }
doq_stream_off_write_list(conn, stream);
if(send_shutdown) {
verbose(VERB_ALGO, "doq: shutdown stream_id %d with app_error_code %d",
goto servfail_mem;
}
}
+ added_tcp = 1;
if(rep->c->use_h2) {
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
+ } else if(rep->c->type == comm_doq && rep->doq_stream) {
+ doq_stream_add_meshstate(rep->doq_stream, mesh, s);
}
/* add serve expired timer if required and not already there */
if(timeout && !mesh_serve_expired_init(s, timeout)) {
qinfo, qid, qflags, edns);
if(rep->c->use_h2)
http2_stream_remove_mesh_state(rep->c->h2_stream);
+ else if(rep->c->type == comm_doq && rep->doq_stream)
+ doq_stream_remove_mesh_state(rep->doq_stream);
comm_point_send_reply(rep);
+ if(added_reply_without_accounting) {
+ mesh_remove_reply_without_accounting(s, repadded);
+ if(added_tcp && rep->c->tcp_req_info)
+ tcp_req_info_remove_mesh_state(rep->c->tcp_req_info, s);
+ }
if(added)
mesh_state_delete(&s->s);
return;
}
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
- struct comm_point* cp, struct http2_stream* h2_stream)
- struct comm_point* cp, struct doq_stream* doq_stream)
++ struct comm_point* cp, struct http2_stream* h2_stream,
++ struct doq_stream* doq_stream)
{
struct mesh_reply* n, *prev = NULL;
n = m->reply_list;
if(!n) return; /* nothing to remove, also no accounting needed */
while(n) {
if(n->query_reply.c == cp
- && (!h2_stream || n->h2_stream == h2_stream)) {
- && (!doq_stream || n->query_reply.doq_stream == doq_stream)) {
++ && (!h2_stream || n->h2_stream == h2_stream)
++ && (!doq_stream || n->query_reply.doq_stream == doq_stre
++am)) {
/* unlink it */
if(prev) prev->next = n->next;
else m->reply_list = n->next;
* @param mesh: to update the counters.
* @param m: the mesh state.
* @param cp: the comm_point to remove from the list.
+ * @param h2_stream: if not NULL, it specifies the h2_stream to match
+ * for the delete.
+ * @param doq_stream: if not NULL, it specifies the doq_stream to match
+ * for the delete.
*/
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
- struct comm_point* cp, struct http2_stream* h2_stream);
- struct comm_point* cp, struct doq_stream* doq_stream);
++ struct comm_point* cp, struct http2_stream* h2_stream,
++ struct doq_stream* doq_stream);
/** Callback for when the serve expired client timer has run out. Tries to
* find an expired answer in the cache and reply that to the client.
* @param qflags: flags from client query.
* @param cb: callback function.
* @param cb_arg: callback user arg.
+ * @param unique_info: if not NULL, used to find a unique state for removal.
*/
void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
- uint16_t qflags, mesh_cb_func_type cb, void* cb_arg);
+ uint16_t qflags, mesh_cb_func_type cb, void* cb_arg, void* unique_info);
+ /** Copy the client info to the query region. */
+ struct respip_client_info* mesh_copy_client_info(struct regional* region,
+ struct respip_client_info* cinfo);
+
#endif /* SERVICES_MESH_H */
!netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT,
&pif->addr, &pif->addrlen, &pif->pfxlen))
return 0;
+#ifdef INT_MAX
+ if(numfd > (size_t)INT_MAX) {
+ log_err("num_ports exceeds INT_MAX");
+ return 0;
+ }
++#endif
+ #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
+ pif->shpif = shared_ports_find_if(shp, &pif->addr, pif->addrlen,
+ pif->pfxlen);
+ #else
+ (void)shp;
#endif
pif->maxout = (int)numfd;
pif->inuse = 0;
{
if(h2_stream->mesh_state) {
mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state,
- h2_session->c, h2_stream);
- h2_session->c, NULL);
++ h2_session->c, h2_stream, NULL);
h2_stream->mesh_state = NULL;
}
http2_req_stream_clear(h2_stream);
size_t len)
{
uint8_t* datstart = sldns_buffer_current(buf)-len+2;
+ uint8_t* datend = sldns_buffer_current(buf);
+ size_t firstlen;
switch(ntohs(rrset->rk.type)) {
case LDNS_RR_TYPE_NXT:
case LDNS_RR_TYPE_NS:
case LDNS_RR_TYPE_RP:
case LDNS_RR_TYPE_SOA:
/* two names after another */
- query_dname_tolower(datstart);
+ canon_dname_tolower(datstart, datend);
- canon_dname_tolower(datstart +
- dname_valid(datstart, len-2), datend);
+ firstlen = dname_valid(datstart, len-2);
+ if(firstlen && firstlen < len-2)
- query_dname_tolower(datstart + firstlen);
++ canon_dname_tolower(datstart + firstlen, datend);
return;
case LDNS_RR_TYPE_RT:
case LDNS_RR_TYPE_AFSDB:
if(len < 2+2+1)
return;
datstart += 2;
- query_dname_tolower(datstart);
+ canon_dname_tolower(datstart, datend);
- canon_dname_tolower(datstart +
- dname_valid(datstart, len-2-2), datend);
+ firstlen = dname_valid(datstart, len-2-2);
+ if(firstlen && firstlen < len-2-2)
- query_dname_tolower(datstart + firstlen);
++ canon_dname_tolower(datstart + firstlen, datend);
return;
case LDNS_RR_TYPE_NAPTR:
if(len < 2+4)