static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
	struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
	int rpz_passthru, struct comm_reply* rep, struct edns_option* edns_list)
{
	struct mesh_state* s = NULL;
	struct edns_option* opt = NULL;
#ifdef UNBOUND_DEBUG
	struct rbnode_type* n;
#endif
	if(!mesh_make_new_space(mesh, NULL)) {
		verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
		mesh->stats_dropped ++;
		return;
	}

	s = mesh_state_create(mesh->env, qinfo, NULL,
		qflags&(BIT_RD|BIT_CD), 0, 0);
	if(!s) {
		log_err("prefetch_subnet mesh_state_create: out of memory");
		return;
	}
	mesh_state_make_unique(s);

	opt = edns_opt_list_find(edns_list, mesh->env->cfg->client_subnet_opcode);
	if(opt) {
		/* Use the client's ECS data */
		if(!edns_opt_list_append(&s->s.edns_opts_front_in, opt->opt_code,
			opt->opt_len, opt->opt_data, s->s.region)) {
			log_err("prefetch_subnet edns_opt_list_append: out of memory");
			return;
		}
	} else {
		/* Fake the ECS data from the client's IP */
		struct ecs_data ecs;
		memset(&ecs, 0, sizeof(ecs));
		subnet_option_from_ss(&rep->addr, &ecs, mesh->env->cfg);
		if(ecs.subnet_validdata == 0) {
			log_err("prefetch_subnet subnet_option_from_ss: invalid data");
			return;
		}
		subnet_ecs_opt_list_append(&ecs, &s->s.edns_opts_front_in,
			&s->s, s->s.region);
		if(!s->s.edns_opts_front_in) {
			log_err("prefetch_subnet subnet_ecs_opt_list_append: out of memory");
			return;
		}
	}
#ifdef UNBOUND_DEBUG
	n =
#else
	(void)
#endif
	rbtree_insert(&mesh->all, &s->node);
	log_assert(n != NULL);
	/* set detached (it is now) */
	mesh->num_detached_states++;
	/* make it ignore the cache */
	sock_list_insert(&s->s.blacklist, NULL, 0, s->s.region);
	s->s.prefetch_leeway = leeway;

	if(s->list_select == mesh_no_list) {
		/* move to either the forever or the jostle_list */
		if(mesh->num_forever_states < mesh->max_forever_states) {
			mesh->num_forever_states ++;
			mesh_list_insert(s, &mesh->forever_first,
				&mesh->forever_last);
			s->list_select = mesh_forever_list;
		} else {
			mesh_list_insert(s, &mesh->jostle_first,
				&mesh->jostle_last);
			s->list_select = mesh_jostle_list;
		}
	}
	s->s.rpz_passthru = rpz_passthru;

	if(!run) {
#ifdef UNBOUND_DEBUG
		n =
#else
		(void)
#endif
		rbtree_insert(&mesh->run, &s->run_node);
		log_assert(n != NULL);
		return;
	}

	mesh_run(mesh, s, module_event_new, NULL);
}
static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
	struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
	int rpz_passthru, struct comm_reply* rep, struct edns_option* edns_list)
{
	struct mesh_state* s = NULL;
	struct edns_option* opt = NULL;
#ifdef UNBOUND_DEBUG
	struct rbnode_type* n;
#endif
	if(!mesh_make_new_space(mesh, NULL)) {
		verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
		mesh->stats_dropped ++;
		return;
	}

	s = mesh_state_create(mesh->env, qinfo, NULL,
		qflags&(BIT_RD|BIT_CD), 0, 0);
	if(!s) {
		log_err("prefetch_subnet mesh_state_create: out of memory");
		return;
	}
	mesh_state_make_unique(s);

	opt = edns_opt_list_find(edns_list, mesh->env->cfg->client_subnet_opcode);
	if(opt) {
		 
		if(!edns_opt_list_append(&s->s.edns_opts_front_in, opt->opt_code,
			opt->opt_len, opt->opt_data, s->s.region)) {
			log_err("prefetch_subnet edns_opt_list_append: out of memory");
			return;
		}
	} else {
		 
		struct ecs_data ecs;
		memset(&ecs, 0, sizeof(ecs));
		subnet_option_from_ss(&rep->addr, &ecs, mesh->env->cfg);
		if(ecs.subnet_validdata == 0) {
			log_err("prefetch_subnet subnet_option_from_ss: invalid data");
			return;
		}
		subnet_ecs_opt_list_append(&ecs, &s->s.edns_opts_front_in,
			&s->s, s->s.region);
		if(!s->s.edns_opts_front_in) {
			log_err("prefetch_subnet subnet_ecs_opt_list_append: out of memory");
			return;
		}
	}
#ifdef UNBOUND_DEBUG
	n =
#else
	(void)
#endif
	rbtree_insert(&mesh->all, &s->node);
	log_assert(n != NULL);
	 
	mesh->num_detached_states++;
	 
	sock_list_insert(&s->s.blacklist, NULL, 0, s->s.region);
	s->s.prefetch_leeway = leeway;

	if(s->list_select == mesh_no_list) {
		 
		if(mesh->num_forever_states < mesh->max_forever_states) {
			mesh->num_forever_states ++;
			mesh_list_insert(s, &mesh->forever_first,
				&mesh->forever_last);
			s->list_select = mesh_forever_list;
		} else {
			mesh_list_insert(s, &mesh->jostle_first,
				&mesh->jostle_last);
			s->list_select = mesh_jostle_list;
		}
	}
	s->s.rpz_passthru = rpz_passthru;

	if(!run) {
#ifdef UNBOUND_DEBUG
		n =
#else
		(void)
#endif
		rbtree_insert(&mesh->run, &s->run_node);
		log_assert(n != NULL);
		return;
	}

	mesh_run(mesh, s, module_event_new, NULL);
}