Пример #1
0
Файл: prop.c Проект: j0sh/thesis
static unsigned match_enrich(kd_tree *t, int *coeffs, int x, int y,
    int *prev)
{
    int k = t->k, *start = t->start;
    kd_node *n  = kdt_query(t, coeffs);

    // set results of query
    int64_t res = match_score(coeffs, n, k);
    int best[] = {INT_MAX, UNPACK_SCORE(res)};
    int pos[] = {INT_MAX, n->value[UNPACK_IDX(res)] - start};

    pos[0] = pos[1]; // hack for (x,y) == (0,0)

    // now check 2 best matches for the left
    if (x) {
        check_guide(t, coeffs, prev[-1], best, pos);
        check_guide(t, coeffs, prev[-2], best, pos);
    }

    // check 2 best matches for top
    if (y) {
        check_guide(t, coeffs, prev[0], best, pos);
        check_guide(t, coeffs, prev[1], best, pos);
    }

    // set prev to best matches
    prev[0] = pos[0];
    prev[1] = pos[1];
    return pos[1];
}
Пример #2
0
/*
 * Lists nat64lsn states.
 * Data layout (v0)(current):
 * Request: [ ipfw_obj_header ipfw_obj_data [ uint64_t ]]
 * Reply: [ ipfw_obj_header ipfw_obj_data [
 *		ipfw_nat64lsn_stg ipfw_nat64lsn_state x N] ]
 *
 * Returns 0 on success
 */
static int
nat64lsn_states(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
    struct sockopt_data *sd)
{
	ipfw_obj_header *oh;
	ipfw_obj_data *od;
	ipfw_nat64lsn_stg *stg;
	struct nat64lsn_cfg *cfg;
	struct nat64lsn_portgroup *pg, *pg_next;
	uint64_t next_idx;
	size_t sz;
	uint32_t addr, states;
	uint16_t port;
	uint8_t nat_proto;

	sz = sizeof(ipfw_obj_header) + sizeof(ipfw_obj_data) +
	    sizeof(uint64_t);
	/* Check minimum header size */
	if (sd->valsize < sz)
		return (EINVAL);

	oh = (ipfw_obj_header *)sd->kbuf;
	od = (ipfw_obj_data *)(oh + 1);
	if (od->head.type != IPFW_TLV_OBJDATA ||
	    od->head.length != sz - sizeof(ipfw_obj_header))
		return (EINVAL);

	next_idx = *(uint64_t *)(od + 1);
	/* Translate index to the request position to start from */
	UNPACK_IDX(next_idx, addr, nat_proto, port);
	if (nat_proto >= NAT_MAX_PROTO)
		return (EINVAL);
	if (nat_proto == 0 && addr != 0)
		return (EINVAL);

	IPFW_UH_RLOCK(ch);
	cfg = nat64lsn_find(CHAIN_TO_SRV(ch), oh->ntlv.name, oh->ntlv.set);
	if (cfg == NULL) {
		IPFW_UH_RUNLOCK(ch);
		return (ESRCH);
	}
	/* Fill in starting point */
	if (addr == 0) {
		addr = cfg->prefix4;
		nat_proto = 1;
		port = 0;
	}
	if (addr < cfg->prefix4 || addr > cfg->pmask4) {
		IPFW_UH_RUNLOCK(ch);
		DPRINTF(DP_GENERIC | DP_STATE, "XXX: %lu %u %u",
		    next_idx, addr, cfg->pmask4);
		return (EINVAL);
	}

	sz = sizeof(ipfw_obj_header) + sizeof(ipfw_obj_data) +
	    sizeof(ipfw_nat64lsn_stg);
	if (sd->valsize < sz)
		return (ENOMEM);
	oh = (ipfw_obj_header *)ipfw_get_sopt_space(sd, sz);
	od = (ipfw_obj_data *)(oh + 1);
	od->head.type = IPFW_TLV_OBJDATA;
	od->head.length = sz - sizeof(ipfw_obj_header);
	stg = (ipfw_nat64lsn_stg *)(od + 1);

	pg = get_first_pg(cfg, &addr, &nat_proto, &port);
	if (pg == NULL) {
		/* No states */
		stg->next_idx = 0xFF;
		stg->count = 0;
		IPFW_UH_RUNLOCK(ch);
		return (0);
	}
	states = 0;
	pg_next = NULL;
	while (pg != NULL) {
		pg_next = get_next_pg(cfg, &addr, &nat_proto, &port);
		if (pg_next == NULL)
			stg->next_idx = 0xFF;
		else
			stg->next_idx = PACK_IDX(addr, nat_proto, port);

		if (export_pg_states(cfg, pg, stg, sd) != 0) {
			IPFW_UH_RUNLOCK(ch);
			return (states == 0 ? ENOMEM: 0);
		}
		states += stg->count;
		od->head.length += stg->count * sizeof(ipfw_nat64lsn_state);
		sz += stg->count * sizeof(ipfw_nat64lsn_state);
		if (pg_next != NULL) {
			sz += sizeof(ipfw_nat64lsn_stg);
			if (sd->valsize < sz)
				break;
			stg = (ipfw_nat64lsn_stg *)ipfw_get_sopt_space(sd,
			    sizeof(ipfw_nat64lsn_stg));
		}
		pg = pg_next;
	}
	IPFW_UH_RUNLOCK(ch);
	return (0);
}