Esempio n. 1
0
/*
 * This appends a tagged, valid, fully-saturated Bloom filter, useful for
 * excluding everything between two 'fenceposts' in an Exclude construct.
 */
static void
append_bf_all(struct ccn_charbuf *c)
{
    unsigned char bf_all[9] = { 3, 1, 'A', 0, 0, 0, 0, 0, 0xFF };
    const struct ccn_bloom_wire *b = ccn_bloom_validate_wire(bf_all, sizeof(bf_all));
    if (b == NULL) abort();
    ccnb_append_tagged_blob(c, CCN_DTAG_Bloom, bf_all, sizeof(bf_all));
}
Esempio n. 2
0
/*
 * This appends a tagged, valid, fully-saturated Bloom filter, useful for
 * excluding everything between two 'fenceposts' in an Exclude construct.
 */
static void
append_bf_all(struct ccn_charbuf *c)
{
    unsigned char bf_all[9] = { 3, 1, 'A', 0, 0, 0, 0, 0, 0xFF };
    const struct ccn_bloom_wire *b = ccn_bloom_validate_wire(bf_all, sizeof(bf_all));
    if (b == NULL) abort();
    ccn_charbuf_append_tt(c, CCN_DTAG_Bloom, CCN_DTAG);
    ccn_charbuf_append_tt(c, sizeof(bf_all), CCN_BLOB);
    ccn_charbuf_append(c, bf_all, sizeof(bf_all));
    ccn_charbuf_append_closer(c);
}
Esempio n. 3
0
/**
 * Test for a match between a ContentObject and an Interest
 *
 * @param content_object        ccnb-encoded ContentObject
 * @param content_object_size   its size in bytes
 * @param implicit_content_digest boolean indicating whether the
 *                              final name component is implicit (as in
 *                              the on-wire format) or explicit (as within
 *                              ccnd's content store).
 * @param pc                    Valid parse information may be provided to
 *                              speed things up. If NULL it will be
 *                              reconstructed internally.
 * @param interest_msg          ccnb-encoded Interest
 * @param interest_msg_size     its size in bytes
 * @param pi                    see _pc_
 *
 * @result 1 if the ccnb-encoded content_object matches the 
 *           ccnb-encoded interest_msg, otherwise 0.
 */
int
ccn_content_matches_interest(const unsigned char *content_object,
                             size_t content_object_size,
                             int implicit_content_digest,
                             struct ccn_parsed_ContentObject *pc,
                             const unsigned char *interest_msg,
                             size_t interest_msg_size,
                             const struct ccn_parsed_interest *pi)
{
    struct ccn_parsed_ContentObject pc_store;
    struct ccn_parsed_interest pi_store;
    int res;
    int ncomps;
    int prefixstart;
    int prefixbytes;
    int namecompstart;
    int namecompbytes;
    int checkdigest = 0;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    const unsigned char *nextcomp;
    size_t nextcomp_size = 0;
    const unsigned char *comp;
    size_t comp_size = 0;
    const unsigned char *bloom;
    size_t bloom_size = 0;
    unsigned char match_any[2] = "-";
    if (pc == NULL) {
        res = ccn_parse_ContentObject(content_object, content_object_size,
                                      &pc_store, NULL);
        if (res < 0) return(0);
        pc = &pc_store;
    }
    if (pi == NULL) {
        res = ccn_parse_interest(interest_msg, interest_msg_size,
                                 &pi_store, NULL);
        if (res < 0) return(0);
        pi = &pi_store;
    }
    if (!ccn_pubid_matches(content_object, pc, interest_msg, pi))
        return(0);
    ncomps = pc->name_ncomps + (implicit_content_digest ? 1 : 0);
    if (ncomps < pi->prefix_comps + pi->min_suffix_comps)
        return(0);
    if (ncomps > pi->prefix_comps + pi->max_suffix_comps)
        return(0);
    prefixstart = pi->offset[CCN_PI_B_Component0];
    prefixbytes = pi->offset[CCN_PI_E_LastPrefixComponent] - prefixstart;
    namecompstart = pc->offset[CCN_PCO_B_Component0];
    namecompbytes = pc->offset[CCN_PCO_E_ComponentLast] - namecompstart;
    if (prefixbytes > namecompbytes) {
        /*
         * The only way for this to be a match is if the implicit
         * content digest name component comes into play.
         */
        if (implicit_content_digest &&
            pi->offset[CCN_PI_B_LastPrefixComponent] - prefixstart == namecompbytes &&
            (pi->offset[CCN_PI_E_LastPrefixComponent] -
             pi->offset[CCN_PI_B_LastPrefixComponent]) == 1 + 2 + 32 + 1) {
            prefixbytes = namecompbytes;
            checkdigest = 1;
        }
        else
            return(0);
    }
    if (0 != memcmp(interest_msg + prefixstart,
                    content_object + namecompstart,
                    prefixbytes))
        return(0);
    if (checkdigest) {
        /*
         * The Exclude by next component is not relevant in this case,
         * since there is no next component present.
         */
        ccn_digest_ContentObject(content_object, pc);
        d = ccn_buf_decoder_start(&decoder,
                        interest_msg + pi->offset[CCN_PI_B_LastPrefixComponent],
                        (pi->offset[CCN_PI_E_LastPrefixComponent] -
                         pi->offset[CCN_PI_B_LastPrefixComponent]));
        comp_size = 0;
        if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
                ccn_buf_advance(d);
                ccn_buf_match_blob(d, &comp, &comp_size);
            }
        if (comp_size != pc->digest_bytes) abort();
        if (0 != memcmp(comp, pc->digest, comp_size))
            return(0);
    }
    else if (pi->offset[CCN_PI_E_Exclude] > pi->offset[CCN_PI_B_Exclude]) {
        if (prefixbytes < namecompbytes) {
            /* pick out the next component in the content object name */
            d = ccn_buf_decoder_start(&decoder,
                                      content_object +
                                        (namecompstart + prefixbytes),
                                      pc->offset[CCN_PCO_E_ComponentLast] -
                                        (namecompstart + prefixbytes));
            if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
                ccn_buf_advance(d);
                ccn_buf_match_blob(d, &nextcomp, &nextcomp_size);
            }
            else
                return(0);
        }
        else if (!implicit_content_digest)
            goto exclude_checked;
        else if (prefixbytes == namecompbytes) {
            /* use the digest name as the next component */
            ccn_digest_ContentObject(content_object, pc);
            nextcomp_size = pc->digest_bytes;
            nextcomp = pc->digest;
        }
        else abort(); /* bug - should have returned already */
        d = ccn_buf_decoder_start(&decoder,
                                  interest_msg + pi->offset[CCN_PI_B_Exclude],
                                  pi->offset[CCN_PI_E_Exclude] -
                                  pi->offset[CCN_PI_B_Exclude]);
        if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude))
            abort();
        ccn_buf_advance(d);
        bloom = NULL;
        bloom_size = 0;
        if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                bloom = match_any;
                ccn_buf_check_close(d);
        }
        else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_buf_check_close(d);
        }
        while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
            ccn_buf_advance(d);
            comp_size = 0;
            if (ccn_buf_match_blob(d, &comp, &comp_size))
                ccn_buf_advance(d);
            ccn_buf_check_close(d);
            if (comp_size > nextcomp_size)
                break;
            if (comp_size == nextcomp_size) {
                res = memcmp(comp, nextcomp, comp_size);
                if (res == 0)
                    return(0); /* One of the explicit excludes */
                if (res > 0)
                    break;
            }
            bloom = NULL;
            bloom_size = 0;
            if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                bloom = match_any;
                ccn_buf_check_close(d);
            }
            else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_buf_check_close(d);
            }
        }
        /*
         * Now we have isolated the applicable filter (Any or Bloom or none).
         */
        if (bloom == match_any)
            return(0);
        else if (bloom_size != 0) {
            const struct ccn_bloom_wire *f = ccn_bloom_validate_wire(bloom, bloom_size);
            /* If not a valid filter, treat like a false positive */
            if (f == NULL)
                return(0);
            if (ccn_bloom_match_wire(f, nextcomp, nextcomp_size))
                return(0);
        }
    exclude_checked: {}
    }
    /*
     * At this point the prefix matches and exclude-by-next-component is done.
     */
    // test any other qualifiers here
    return(1);
}