Esempio n. 1
0
PUBLIC struct content_entry *
process_incoming_content(struct ccnr_handle *h, struct fdholder *fdholder,
                         unsigned char *msg, size_t size)
{
    struct ccn_parsed_ContentObject obj = {0};
    int res;
    struct content_entry *content = NULL;
    ccnr_accession accession = CCNR_NULL_ACCESSION;
    
    content = calloc(1, sizeof(*content));
    if (content == NULL)
        goto Bail;    
    content->cob = ccn_charbuf_create();
    if (content->cob == NULL)
        goto Bail;    
    res = ccn_charbuf_append(content->cob, msg, size);
    if (res < 0) goto Bail;
    content->size = size;
    res = r_store_set_flatname(h, content, &obj);
    if (res < 0) goto Bail;
    ccnr_meter_bump(h, fdholder->meter[FM_DATI], 1);
    content->accession = CCNR_NULL_ACCESSION;
    r_store_enroll_content(h, content);
    if (CCNSHOULDLOG(h, LM_4, CCNL_FINE))
        ccnr_debug_content(h, __LINE__, "content_from", fdholder, content);
    res = r_store_content_btree_insert(h, content, &obj, &accession);
    if (res < 0) goto Bail;
    if (res == 0) {
        /* Content was there, with an accession */
        if (CCNSHOULDLOG(h, LM_4, CCNL_FINER))
            ccnr_debug_content(h, __LINE__, "content_duplicate",
                               fdholder, content);
        h->content_dups_recvd++;
        r_store_forget_content(h, &content);
        content = r_store_content_from_accession(h, accession);
        if (content == NULL)
            goto Bail;
    }
    r_store_set_content_timer(h, content, &obj);
    r_match_match_interests(h, content, &obj, NULL, fdholder);
    return(content);
Bail:
    r_store_forget_content(h, &content);
    return(content);
}
Esempio n. 2
0
enum ndn_upcall_res hash_store_handle_proto_sha256(struct hash_store* self, struct ndn_upcall_info* info) {
  int res;
  // extract hash
  const uint8_t* hash; size_t hashsz;
  res = ndn_name_comp_get(info->interest_ndnb, info->interest_comps, 1, &hash, &hashsz);
  if (res != 0 || hashsz != SEGMENT_HASHSZ) return NDN_UPCALL_RESULT_ERR;
  LOG("hash_store_handle_proto_sha256("); LOG_hash(hash, hashsz); LOG(") ");
  
  // find content
  ndnr_accession accession = hash_store_find(self, hash);
  if (accession == NDNR_NULL_ACCESSION) {
    LOG("MISS\n");
    return NDN_UPCALL_RESULT_OK;
  }
  struct content_entry* orig_content = r_store_content_from_accession(self->h, accession);
  if (orig_content == NULL) { LOG("LOST\n"); return NDN_UPCALL_RESULT_OK; }
  if (orig_content->cob == NULL && r_store_content_base(self->h, orig_content) == NULL) { LOG("LOST\n"); return NDN_UPCALL_RESULT_OK; }
  LOG("HIT %" PRIx64 ", ", (uint64_t)ndnr_accession_encode(self->h, accession));

  // extract payload
  struct ndn_parsed_ContentObject orig_pco = {0};
  res = ndn_parse_ContentObject(orig_content->cob->buf, orig_content->cob->length, &orig_pco, NULL);
  if (res != 0) { LOG("cannot parse\n"); return NDN_UPCALL_RESULT_OK; }
  const uint8_t* payload; size_t payloadsz;
  res = ndn_content_get_value(orig_content->cob->buf, orig_content->cob->length, &orig_pco, &payload, &payloadsz);
  if (res != 0) { LOG("cannot extract payload\n"); return NDN_UPCALL_RESULT_OK; }
  
  // verify hash
  if (!hash_store_verify_hash(self, payload, payloadsz, hash)) { LOG("hash mismatch\n"); return NDN_UPCALL_RESULT_OK; }
  
  // build reply
  struct ndn_charbuf* reply = ndn_charbuf_create();
  hash_store_build_reply(self, reply, hash, payload, payloadsz);
  
  // send reply TODO use queues
  res = ndn_put(info->h, reply->buf, reply->length);
  if (res != 0) { LOG("cannot send\n"); ndn_charbuf_destroy(&reply); return NDN_UPCALL_RESULT_OK; }
  ndn_charbuf_destroy(&reply);
  LOG("OK\n");
  return NDN_UPCALL_RESULT_INTEREST_CONSUMED;
}
Esempio n. 3
0
PUBLIC struct content_entry *
r_store_lookup(struct ccnr_handle *h,
               const unsigned char *msg,
               const struct ccn_parsed_interest *pi,
               struct ccn_indexbuf *comps)
{
    struct content_entry *content = NULL;
    struct ccn_btree_node *leaf = NULL;
    ccnr_cookie last_match = 0;
    ccnr_accession last_match_acc = CCNR_NULL_ACCESSION;
    struct ccn_charbuf *scratch = NULL;
    size_t size = pi->offset[CCN_PI_E];
    int ndx;
    int res;
    int try;
    
    content = r_store_find_first_match_candidate(h, msg, pi);
    if (content != NULL && CCNSHOULDLOG(h, LM_8, CCNL_FINER))
        ccnr_debug_content(h, __LINE__, "first_candidate", NULL,
                           content);
    if (content != NULL &&
        !r_store_content_matches_interest_prefix(h, content, msg, size)) {
            if (CCNSHOULDLOG(h, LM_8, CCNL_FINER))
                ccnr_debug_ccnb(h, __LINE__, "prefix_mismatch", NULL,
                                msg, size);
            content = NULL;
        }
    scratch = ccn_charbuf_create();
    for (try = 0; content != NULL; try++) {
        res = ccn_btree_lookup(h->btree,
                               content->flatname->buf,
                               content->flatname->length,
                               &leaf);
        if (CCN_BT_SRCH_FOUND(res) == 0) {
            ccnr_debug_content(h, __LINE__, "impossible", NULL, content);
            content = NULL;
            break;
        }
        ndx = CCN_BT_SRCH_INDEX(res);
        res = ccn_btree_match_interest(leaf, ndx, msg, pi, scratch);
        if (res == -1) {
            ccnr_debug_ccnb(h, __LINE__, "match_error", NULL, msg, size);
            content = NULL;
            break;
        }
        if (res == 1) {
            if ((pi->orderpref & 1) == 0) // XXX - should be symbolic
                break;
            last_match = content->cookie;
            last_match_acc = content->accession;
            content = r_store_next_child_at_level(h, content, comps->n - 1);
        }
        else
            content = r_store_content_next(h, content);
        if (content != NULL &&
            !r_store_content_matches_interest_prefix(h, content, msg, size))
                content = NULL;
    }
    if (last_match != 0) {
        content = r_store_content_from_cookie(h, last_match);
        if (content == NULL)
            content = r_store_content_from_accession(h, last_match_acc);
    }
    ccn_charbuf_destroy(&scratch);
    return(content);
}

/**
 * Find the first content handle that matches the prefix given by the namish,
 * which may be a Name, Interest, ContentObject, ...
 *
 * Does not check the other parts of namish, in particular, does not generate
 * the digest component of a ContentObject.
 */
PUBLIC struct content_entry *
r_store_lookup_ccnb(struct ccnr_handle *h,
                    const unsigned char *namish, size_t size)
{
    struct content_entry *content = NULL;
    struct ccn_charbuf *flatname = NULL;
    int res;
    
    flatname = ccn_charbuf_create();
    if (flatname == NULL)
        goto Bail;
    res = ccn_flatname_from_ccnb(flatname, namish, size);
    if (res < 0)
        goto Bail;
    content = r_store_look(h, flatname->buf, flatname->length);
    if (content != NULL) {
        res = ccn_flatname_charbuf_compare(flatname, content->flatname);
        if (res == 0 || res == -9999) {
            /* prefix matches */
        }
        else
            content = NULL;
    }
Bail:
    ccn_charbuf_destroy(&flatname);
    return(content);
}

/**
 * Mark content as stale
 */
PUBLIC void
r_store_mark_stale(struct ccnr_handle *h, struct content_entry *content)
{
    ccnr_cookie cookie = content->cookie;
    if ((content->flags & CCN_CONTENT_ENTRY_STALE) != 0)
        return;
    if (CCNSHOULDLOG(h, LM_4, CCNL_FINE))
            ccnr_debug_content(h, __LINE__, "stale", NULL, content);
    content->flags |= CCN_CONTENT_ENTRY_STALE;
    h->n_stale++;
    if (cookie < h->min_stale)
        h->min_stale = cookie;
    if (cookie > h->max_stale)
        h->max_stale = cookie;
}

/**
 * Scheduled event that makes content stale when its FreshnessSeconds
 * has expired.
 */
static int
expire_content(struct ccn_schedule *sched,
               void *clienth,
               struct ccn_scheduled_event *ev,
               int flags)
{
    struct ccnr_handle *h = clienth;
    ccnr_cookie cookie = ev->evint;
    struct content_entry *content = NULL;
    if ((flags & CCN_SCHEDULE_CANCEL) != 0)
        return(0);
    content = r_store_content_from_cookie(h, cookie);
    if (content != NULL)
        r_store_mark_stale(h, content);
    return(0);
}

/**
 * Schedules content expiration based on its FreshnessSeconds.
 *
 */
PUBLIC void
r_store_set_content_timer(struct ccnr_handle *h, struct content_entry *content,
                  struct ccn_parsed_ContentObject *pco)
{
    int seconds = 0;
    int microseconds = 0;
    size_t start = pco->offset[CCN_PCO_B_FreshnessSeconds];
    size_t stop  = pco->offset[CCN_PCO_E_FreshnessSeconds];
    const unsigned char *content_msg = NULL;
    if (start == stop)
        return;
    content_msg = r_store_content_base(h, content);
    seconds = ccn_fetch_tagged_nonNegativeInteger(
                CCN_DTAG_FreshnessSeconds,
                content_msg,
                start, stop);
    if (seconds <= 0)
        return;
    if (seconds > ((1U<<31) / 1000000)) {
        ccnr_debug_content(h, __LINE__, "FreshnessSeconds_too_large", NULL,
                           content);
        return;
    }
    microseconds = seconds * 1000000;
    ccn_schedule_event(h->sched, microseconds,
                       &expire_content, NULL, content->cookie);
}