Ejemplo n.º 1
0
Archivo: ndnpoke.c Proyecto: cawka/ndnx
enum ndn_upcall_res
incoming_interest(
    struct ndn_closure *selfp,
    enum ndn_upcall_kind kind,
    struct ndn_upcall_info *info)
{
    struct ndn_charbuf *cob = selfp->data;
    int res;
    
    switch (kind) {
        case NDN_UPCALL_FINAL:
            break;
        case NDN_UPCALL_INTEREST:
            if (ndn_content_matches_interest(cob->buf, cob->length,
                    1, NULL,
                    info->interest_ndnb, info->pi->offset[NDN_PI_E],
                    info->pi)) {
                res = ndn_put(info->h, cob->buf, cob->length);
                if (res >= 0) {
                    selfp->intdata = 1;
                    ndn_set_run_timeout(info->h, 0);
                    return(NDN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
            break;
        default:
            break;
    }
    return(NDN_UPCALL_RESULT_OK);
}
Ejemplo n.º 2
0
enum ndn_upcall_res
outgoing_content(struct ndn_closure *selfp,
                 enum ndn_upcall_kind kind,
                 struct ndn_upcall_info *info)
{
    struct mini_store *md;
    struct ndn_charbuf *cob = NULL;
    int i;
    int res = 0;
    int which;
    
    md = selfp->data;
    which = md->me.intdata;
    if (kind == NDN_UPCALL_FINAL) {
        fprintf(stderr, "NDN_UPCALL_FINAL for store %d\n", which);
        for (i = 0; i < MINI_STORE_LIMIT; i++)
            ndn_charbuf_destroy(&md->cob[i]);
        return(NDN_UPCALL_RESULT_OK);
    }
    printf("Store %d got interest matching %d components, kind = %d",
           which, info->matched_comps, kind);
    /* Look through our little pile of content and send one that matches */
    if (kind == NDN_UPCALL_INTEREST) {
        for (i = 0; i < MINI_STORE_LIMIT; i++) {
            cob = md->cob[i];
            if (cob != NULL && cob_matches(info, cob)) {
                res = ndn_put(info->h, cob->buf, cob->length);
                if (res == -1) {
                    fprintf(stderr, "... error sending data\n");
                    return(NDN_UPCALL_RESULT_ERR);
                }
                else {
                    printf("... sent my content:\n");
                    printraw(cob->buf, cob->length);
                    ndn_charbuf_destroy(&md->cob[i]);
                    return(NDN_UPCALL_RESULT_INTEREST_CONSUMED);
                }
            }
        }
        printf("... no match\n");
    }
    else
        printf("\n");
    return(NDN_UPCALL_RESULT_ERR);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
enum ndn_upcall_res
interest_handler(struct ndn_closure *selfp,
                 enum ndn_upcall_kind upcall_kind,
                 struct ndn_upcall_info *info)
{
    int i, c, mc, match, res;
    struct handlerstateitem item;
    struct handlerstate *state;
    size_t ndnb_size = 0;

    state = selfp->data;
    switch(upcall_kind) {
    case NDN_UPCALL_FINAL:
        fprintf(stderr, "Upcall final\n");
        return (0);

    case NDN_UPCALL_INTEREST_TIMED_OUT:
        fprintf(stderr, "refresh\n");
        return (NDN_UPCALL_RESULT_REEXPRESS);
        
    case NDN_UPCALL_CONTENT:
    case NDN_UPCALL_CONTENT_UNVERIFIED:
        ndnb_size = info->pco->offset[NDN_PCO_E];
        c = state->count;
        for (i = 0; i < c; i++) {
            if (info->content_comps->n == state->items[i].components->n) {
                mc = match_components((unsigned char *)info->content_ndnb, info->content_comps,
                                  state->items[i].contents, state->items[i].components);
                if (mc == (info->content_comps->n - 1)) {
                    fprintf(stderr, "Duplicate content\n");
                    return (0);
                }
            }
        }
        fprintf(stderr, "Storing content item %d ", c);
        state->items = realloc(state->items, (c + 1) * sizeof(*(state->items)));
        if (state->items == NULL) {
            perror("realloc failed");
            exit(1);
        }
        memset(&(state->items[c]), 0, sizeof(*(state->items)));
        state->items[c].components = ndn_indexbuf_create();
        /* XXX: probably should not have to do this re-parse of the content object */
        res = ndn_parse_ContentObject(info->content_ndnb, ndnb_size, &(state->items[c].x), state->items[c].components);
        if (res < 0) {
            fprintf(stderr, "- skipping: Not a ContentObject\n");
            ndn_indexbuf_destroy(&state->items[c].components);
            return (-1);
        }
        fprintf(stderr, "- ok\n");
        state->items[c].filename = "ephemeral";
        state->items[c].contents = malloc(ndnb_size);
        state->items[c].size = ndnb_size;
        memcpy(state->items[c].contents, info->content_ndnb, ndnb_size);
        state->count = c + 1;
        return (0);

    case NDN_UPCALL_CONTENT_BAD:
	fprintf(stderr, "Content signature verification failed! Discarding.\n");
	return (-1);

    case NDN_UPCALL_CONSUMED_INTEREST:
        fprintf(stderr, "Upcall consumed interest\n");
        return (-1); /* no data */

    case NDN_UPCALL_INTEREST:
        c = state->count;
        for (i = 0; i < c; i++) {
            match = ndn_content_matches_interest(state->items[i].contents,
                                                 state->items[i].size,
                                                 1,
                                                 NULL,
                                                 info->interest_ndnb,
                                                 info->pi->offset[NDN_PI_E],
                                                 info->pi);
            if (match) {
                ndn_put(info->h, state->items[i].contents, state->items[i].size);
                fprintf(stderr, "Sending %s\n", state->items[i].filename);
                if (i < c - 1) {
                    item = state->items[i];
                    memmove(&(state->items[i]), &(state->items[i+1]), sizeof(item) * ((c - 1) - i));
                    state->items[c - 1] = item;
                }
                return (1);
            }
        }
        return(0);
    case NDN_UPCALL_CONTENT_KEYMISSING:
    case NDN_UPCALL_CONTENT_RAW:
        /* should not happen */
        return (-1);
    }
    return (-1);
}
Ejemplo n.º 5
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ndn *ndn = NULL;
    struct ndn_charbuf *root = NULL;
    struct ndn_charbuf *name = NULL;
    struct ndn_charbuf *temp = NULL;
    struct ndn_charbuf *templ = NULL;
    struct ndn_signing_params sp = NDN_SIGNING_PARAMS_INIT;
    long expire = -1;
    long blocksize = 1024;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    struct mydata mydata = { 0 };
    struct ndn_closure in_content = {.p=&incoming_content, .data=&mydata};
    struct ndn_closure in_interest = {.p=&incoming_interest, .data=&mydata};
    while ((res = getopt(argc, argv, "hx:b:")) != -1) {
        switch (res) {
            case 'x':
                expire = atol(optarg);
                if (expire <= 0)
                    usage(progname);
                break;
            case 'b':
                blocksize = atol(optarg);
                break;
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc != 1)
        usage(progname);
    name = ndn_charbuf_create();
    res = ndn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad NDN URI: %s\n", progname, argv[0]);
        exit(1);
    }
    ndn = ndn_create();
    if (ndn_connect(ndn, NULL) == -1) {
        perror("Could not connect to ndnd");
        exit(1);
    }
    
    buf = calloc(1, blocksize);
    root = name;
    name = ndn_charbuf_create();
    temp = ndn_charbuf_create();
    templ = ndn_charbuf_create();

    /* Set up a handler for interests */
    ndn_charbuf_append(name, root->buf, root->length);
    ndn_set_interest_filter(ndn, name, &in_interest);
    
    /* Initiate check to see whether there is already something there. */
    ndn_charbuf_reset(temp);
    ndn_charbuf_putf(temp, "%d", 0);
    ndn_name_append(name, temp->buf, temp->length);
    ndn_charbuf_reset(templ);
    ndnb_element_begin(templ, NDN_DTAG_Interest);
    ndnb_element_begin(templ, NDN_DTAG_Name);
    ndnb_element_end(templ); /* </Name> */
    ndnb_tagged_putf(templ, NDN_DTAG_MaxSuffixComponents, "%d", 1);
    // XXX - use pubid
    ndnb_element_end(templ); /* </Interest> */
    res = ndn_express_interest(ndn, name, &in_content, templ);
    if (res < 0) abort();
    
    sp.freshness = expire;
    for (i = 0;; i++) {
        read_res = read_full(0, buf, blocksize);
        if (read_res < 0) {
            perror("read");
            read_res = 0;
            status = 1;
        }
        if (read_res < blocksize) {
            sp.sp_flags |= NDN_SP_FINAL_BLOCK;
        }
        ndn_charbuf_reset(name);
        ndn_charbuf_append(name, root->buf, root->length);
        ndn_charbuf_reset(temp);
        ndn_charbuf_putf(temp, "%d", i);
        ndn_name_append(name, temp->buf, temp->length);
        ndn_charbuf_reset(temp);
        ndn_charbuf_append(temp, buf, read_res);
        ndn_charbuf_reset(temp);
        res = ndn_sign_content(ndn, temp, name, &sp, buf, read_res);
        if (res != 0) {
            fprintf(stderr, "Failed to sign ContentObject (res == %d)\n", res);
            exit(1);
        }
        /* Put the keylocator in the first block only. */
        sp.sp_flags |= NDN_SP_OMIT_KEY_LOCATOR;
        if (i == 0) {
            /* Finish check for old content */
            if (mydata.content_received == 0)
                ndn_run(ndn, 100);
            if (mydata.content_received > 0) {
                fprintf(stderr, "%s: name is in use: %s\n", progname, argv[0]);
                exit(1);
            }
            mydata.outstanding++; /* the first one is free... */
        }
        res = ndn_put(ndn, temp->buf, temp->length);
        if (res < 0) {
            fprintf(stderr, "ndn_put failed (res == %d)\n", res);
            exit(1);
        }
        if (read_res < blocksize)
            break;
        if (mydata.outstanding > 0)
            mydata.outstanding--;
        else
            res = 10;
        res = ndn_run(ndn, res * 100);
        if (res < 0) {
            status = 1;
            break;
        }
    }
    
    free(buf);
    buf = NULL;
    ndn_charbuf_destroy(&root);
    ndn_charbuf_destroy(&name);
    ndn_charbuf_destroy(&temp);
    ndn_destroy(&ndn);
    exit(status);
}
Ejemplo n.º 6
0
Archivo: ndnpoke.c Proyecto: cawka/ndnx
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ndn *ndn = NULL;
    struct ndn_charbuf *name = NULL;
    struct ndn_charbuf *pname = NULL;
    struct ndn_charbuf *temp = NULL;
    struct ndn_charbuf *extopt = NULL;
    long expire = -1;
    int versioned = 0;
    size_t blocksize = 8*1024;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    enum ndn_content_type content_type = NDN_CONTENT_DATA;
    struct ndn_closure in_interest = {.p=&incoming_interest};
    const char *postver = NULL;
    const char *key_uri = NULL;
    int force = 0;
    int verbose = 0;
    int timeout = -1;
    int setfinal = 0;
    int prefixcomps = -1;
    int fd;
    struct ndn_signing_params sp = NDN_SIGNING_PARAMS_INIT;
    
    while ((res = getopt(argc, argv, "e:fhk:lvV:p:t:w:x:")) != -1) {
        switch (res) {
            case 'e':
                if (extopt == NULL)
                    extopt = ndn_charbuf_create();
                fd = open(optarg, O_RDONLY);
                if (fd < 0) {
                    perror(optarg);
                    exit(1);
                }
                for (;;) {
                    read_res = read(fd, ndn_charbuf_reserve(extopt, 64), 64);
                    if (read_res <= 0)
                        break;
                    extopt->length += read_res;
                }
                if (read_res < 0)
                    perror(optarg);
                close(fd);
                break;
            case 'f':
                force = 1;
                break;
            case 'l':
                setfinal = 1; // set FinalBlockID to last comp of name
                break;
            case 'k':
                key_uri = optarg;
                break;
            case 'p':
                prefixcomps = atoi(optarg);
                if (prefixcomps < 0)
                    usage(progname);
                break;
            case 'x':
                expire = atol(optarg);
                if (expire <= 0)
                    usage(progname);
                break;
            case 'v':
                verbose = 1;
                break;
            case 'V':
                versioned = 1;
                postver = optarg;
                if (0 == memcmp(postver, "%00", 3))
                    setfinal = 1;
                break;
            case 'w':
                timeout = atol(optarg);
                if (timeout <= 0)
                    usage(progname);
                timeout *= 1000;
                break;
            case 't':
                if (0 == strcasecmp(optarg, "DATA")) {
                    content_type = NDN_CONTENT_DATA;
                    break;
                }
                if (0 == strcasecmp(optarg, "ENCR")) {
                    content_type = NDN_CONTENT_ENCR;
                    break;
                }
                if (0 == strcasecmp(optarg, "GONE")) {
                    content_type = NDN_CONTENT_GONE;
                    break;
                }
                if (0 == strcasecmp(optarg, "KEY")) {
                    content_type = NDN_CONTENT_KEY;
                    break;
                }
                if (0 == strcasecmp(optarg, "LINK")) {
                    content_type = NDN_CONTENT_LINK;
                    break;
                }
                if (0 == strcasecmp(optarg, "NACK")) {
                    content_type = NDN_CONTENT_NACK;
                    break;
                }
                content_type = atoi(optarg);
                if (content_type > 0 && content_type <= 0xffffff)
                    break;
                fprintf(stderr, "Unknown content type %s\n", optarg);
                /* FALLTHRU */
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argv[0] == NULL)
        usage(progname);
    name = ndn_charbuf_create();
    res = ndn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ndn URI: %s\n", progname, argv[0]);
        exit(1);
    }
    if (argv[1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", progname);
    
    /* Preserve the original prefix, in case we add versioning,
     * but trim it down if requested for the interest filter registration
     */
    pname = ndn_charbuf_create();
    ndn_charbuf_append(pname, name->buf, name->length);
    if (prefixcomps >= 0) {
        res = ndn_name_chop(pname, NULL, prefixcomps);
        if (res < 0) {
            fprintf(stderr, "%s: unable to trim name to %d component%s.\n",
                    progname, prefixcomps, prefixcomps == 1 ? "" : "s");
            exit(1);
        }
    }
    /* Connect to ndnd */
    ndn = ndn_create();
    if (ndn_connect(ndn, NULL) == -1) {
        perror("Could not connect to ndnd");
        exit(1);
    }

    /* Read the actual user data from standard input */
    buf = calloc(1, blocksize);
    read_res = read_full(0, buf, blocksize);
    if (read_res < 0) {
        perror("read");
        read_res = 0;
        status = 1;
    }
        
    /* Tack on the version component if requested */
    if (versioned) {
        res = ndn_create_version(ndn, name, NDN_V_REPLACE | NDN_V_NOW | NDN_V_HIGH, 0, 0);
        if (res < 0) {
            fprintf(stderr, "%s: ndn_create_version() failed\n", progname);
            exit(1);
        }
        if (postver != NULL) {
            res = ndn_name_from_uri(name, postver);
            if (res < 0) {
                fprintf(stderr, "-V %s: invalid name suffix\n", postver);
                exit(0);
            }
        }
    }
    temp = ndn_charbuf_create();
    
    /* Ask for a FinalBlockID if appropriate. */
    if (setfinal)
        sp.sp_flags |= NDN_SP_FINAL_BLOCK;
    
    if (res < 0) {
        fprintf(stderr, "Failed to create signed_info (res == %d)\n", res);
        exit(1);
    }
    
    /* Set content type */
    sp.type = content_type;
    
    /* Set freshness */
    if (expire >= 0) {
        if (sp.template_ndnb == NULL) {
            sp.template_ndnb = ndn_charbuf_create();
            ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_SignedInfo, NDN_DTAG);
        }
        else if (sp.template_ndnb->length > 0) {
            sp.template_ndnb->length--;
        }
        ndnb_tagged_putf(sp.template_ndnb, NDN_DTAG_FreshnessSeconds, "%ld", expire);
        sp.sp_flags |= NDN_SP_TEMPL_FRESHNESS;
        ndn_charbuf_append_closer(sp.template_ndnb);
    }
    
    /* Set key locator, if supplied */
    if (key_uri != NULL) {
        struct ndn_charbuf *c = ndn_charbuf_create();
        res = ndn_name_from_uri(c, key_uri);
        if (res < 0) {
            fprintf(stderr, "%s is not a valid ndnx URI\n", key_uri);
            exit(1);
        }
        if (sp.template_ndnb == NULL) {
            sp.template_ndnb = ndn_charbuf_create();
            ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_SignedInfo, NDN_DTAG);
        }
        else if (sp.template_ndnb->length > 0) {
            sp.template_ndnb->length--;
        }
        ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_KeyLocator, NDN_DTAG);
        ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_KeyName, NDN_DTAG);
        ndn_charbuf_append(sp.template_ndnb, c->buf, c->length);
        ndn_charbuf_append_closer(sp.template_ndnb);
        ndn_charbuf_append_closer(sp.template_ndnb);
        sp.sp_flags |= NDN_SP_TEMPL_KEY_LOCATOR;
        ndn_charbuf_append_closer(sp.template_ndnb);
        ndn_charbuf_destroy(&c);
    }

    if (extopt != NULL && extopt->length > 0) {
        if (sp.template_ndnb == NULL) {
            sp.template_ndnb = ndn_charbuf_create();
            ndn_charbuf_append_tt(sp.template_ndnb, NDN_DTAG_SignedInfo, NDN_DTAG);
        }
        else if (sp.template_ndnb->length > 0) {
            sp.template_ndnb->length--;
        }
        ndnb_append_tagged_blob(sp.template_ndnb, NDN_DTAG_ExtOpt,
                                extopt->buf, extopt->length);
        sp.sp_flags |= NDN_SP_TEMPL_EXT_OPT;
        ndn_charbuf_append_closer(sp.template_ndnb);
    }
    
    /* Create the signed content object, ready to go */
    temp->length = 0;
    res = ndn_sign_content(ndn, temp, name, &sp, buf, read_res);
    if (res != 0) {
        fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res);
        exit(1);
    }
    if (read_res == blocksize) {
        read_res = read_full(0, buf, 1);
        if (read_res == 1) {
            fprintf(stderr, "%s: warning - truncated data\n", argv[0]);
            status = 1;
        }
    }
    free(buf);
    buf = NULL;
    if (force) {
        /* At user request, send without waiting to see an interest */
        res = ndn_put(ndn, temp->buf, temp->length);
        if (res < 0) {
            fprintf(stderr, "ndn_put failed (res == %d)\n", res);
            exit(1);
        }
    }
    else {
        in_interest.data = temp;
        /* Set up a handler for interests */
        res = ndn_set_interest_filter(ndn, pname, &in_interest);
        if (res < 0) {
            fprintf(stderr, "Failed to register interest (res == %d)\n", res);
            exit(1);
        }
        res = ndn_run(ndn, timeout);
        if (in_interest.intdata == 0) {
            if (verbose)
                fprintf(stderr, "Nobody's interested\n");
            exit(1);
        }
    }
    
    if (verbose) {
        struct ndn_charbuf *uri = ndn_charbuf_create();
        uri->length = 0;
        ndn_uri_append(uri, name->buf, name->length, 1);
        printf("wrote %s\n", ndn_charbuf_as_string(uri));
        ndn_charbuf_destroy(&uri);
    }
    ndn_destroy(&ndn);
    ndn_charbuf_destroy(&name);
    ndn_charbuf_destroy(&pname);
    ndn_charbuf_destroy(&temp);
    ndn_charbuf_destroy(&sp.template_ndnb);
    ndn_charbuf_destroy(&extopt);
    exit(status);
}