Esempio n. 1
0
bool CcnH_regPrefix(CcnPrefixOp operation, struct ccn* ccnh, CCNDID ccndid, int faceid, struct ccn_charbuf* prefix) {
	struct ccn_forwarding_entry* fe = CcnH_buildForwardingEntry(operation, ccndid, faceid, prefix);
	struct ccn_charbuf* reqname = CcnH_signForwardingEntry(ccnh, ccndid, fe);
	int res = ccn_get(ccnh, reqname, CcnH_localScopeTempl(), 5000, NULL, NULL, NULL, 0);
	ccn_charbuf_destroy(&reqname);
	free(fe);
	return res == 0;
}
Esempio n. 2
0
/**
 *
 * Create new face by sending out a request Interest
 * The actual new face instance is returned
 * 
 */
static 
struct ccn_face_instance *create_face(struct ccn *h, struct ccn_charbuf *local_scope_template,
        struct ccn_charbuf *no_name, struct ccn_face_instance *face_instance)
{
	struct ccn_charbuf *newface = NULL;
	struct ccn_charbuf *signed_info = NULL;
	struct ccn_charbuf *temp = NULL;
	struct ccn_charbuf *name = NULL;
	struct ccn_charbuf *resultbuf = NULL;
	struct ccn_parsed_ContentObject pcobuf = {0};
	struct ccn_face_instance *new_face_instance = NULL;
	const unsigned char *ptr = NULL;
	size_t length = 0;
	int res = 0;

	/* Encode the given face instance */
	newface = ccn_charbuf_create();
	ccnb_append_face_instance(newface, face_instance);

	temp = ccn_charbuf_create();
	res = ccn_sign_content(h, temp, no_name, NULL, newface->buf, newface->length);
	resultbuf = ccn_charbuf_create();

	/* Construct the Interest name that will create the face */
	name = ccn_charbuf_create();
	ccn_name_init(name);
	ccn_name_append_str(name, "ccnx");
	ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size);
	ccn_name_append_str(name, face_instance->action);
	ccn_name_append(name, temp->buf, temp->length);

	/* send Interest to retrieve Data that contains the newly created face */
	res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
	ON_ERROR_CLEANUP(res);

	/* decode Data to get the actual face instance */
	res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
	ON_ERROR_CLEANUP(res);

	new_face_instance = ccn_face_instance_parse(ptr, length);

	ccn_charbuf_destroy(&newface);
	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&temp);
	ccn_charbuf_destroy(&resultbuf);
	ccn_charbuf_destroy(&name);

	return new_face_instance;

	cleanup:
		ccn_charbuf_destroy(&newface);
		ccn_charbuf_destroy(&signed_info);
		ccn_charbuf_destroy(&temp);
		ccn_charbuf_destroy(&resultbuf);
		ccn_charbuf_destroy(&name);

	return NULL;
}
Esempio n. 3
0
/**
 * Request the current segment number from the ccnx data producer
 *
 * This is a request for meta data for the media stream the user has named with their URI.
 * We assume that they want to join the media broadcast from what is currently being published
 * and \em not want to start from the beginning...although there is good reason for that too.
 *
 * Getting this data is done by expressing interests in the meta data. The producer of the
 * media stream will catch this through one of its ccnx filters and produce this meta data
 * back through the network to us.
 *
 * \param h		ccnx context handle
 * \param name	the content name for which we desire the meta data
 * \param timeout	how long to wait around
 * \return the segment number to ask for first, 0 on timeout
 */
static uintmax_t *
get_segment (struct ccn *h, struct ccn_charbuf *name, int timeout)
{
  struct ccn_charbuf *hn;
  uintmax_t *result = NULL;
  int res = 0;

  GST_INFO ("get_segment step 1");
  hn = ccn_charbuf_create ();
  // ccn_name_append_components(hn, name->buf, 0, name->length );
  ccn_charbuf_append_charbuf (hn, name);
  ccn_name_from_uri (hn, "_meta_/.segment");
  // ccn_name_append_str(hn, "_meta_");
  // ccn_name_append_str(hn, ".segment");
  GST_INFO ("get_segment step 2");
  // res = ccn_resolve_version(h, hn, CCN_V_HIGHEST, timeout);
  GST_INFO ("get_segment step 3, res: %d", res);
  if (res == 0) {
    struct ccn_charbuf *ho = ccn_charbuf_create ();
    struct ccn_parsed_ContentObject pcobuf = { 0 };
    const unsigned char *hc;
    size_t hcs;

    // hDump(DUMP_ADDR(hn->buf), DUMP_SIZE(hn->length));
    GST_INFO ("get_segment step 10");
    res = ccn_get (h, hn, NULL, timeout, ho, &pcobuf, NULL, 0);
    GST_INFO ("get_segment step 11, res: %d", res);
    if (res >= 0) {
      hc = ho->buf;
      hcs = ho->length;
      // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs));
      ccn_content_get_value (hc, hcs, &pcobuf, &hc, &hcs);
      // hDump( DUMP_ADDR(hc), DUMP_SIZE(hcs));
      result = calloc (1, sizeof (uintmax_t));
      memcpy (result, hc, sizeof (uintmax_t));
    }
    ccn_charbuf_destroy (&ho);
  }
  GST_INFO ("get_segment step 9");
  ccn_charbuf_destroy (&hn);
  return (result);
}
Esempio n. 4
0
void CcnCC_fetchCcndid(CcnCC self) {
	int res;
	struct ccn_charbuf* name = ccn_charbuf_create();
	struct ccn_charbuf* resultbuf = ccn_charbuf_create();
	struct ccn_parsed_ContentObject pcobuf = {0};
	const uint8_t* ccndid_result;
	static size_t ccndid_result_size;
	ccn_name_from_uri(name, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY");
	res = ccn_get(self->ccnh, name, CcnH_localScopeTempl(), 4500, resultbuf, &pcobuf, NULL, 0);
	if (res >= 0) {
		res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, resultbuf->buf, pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest], pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest], &ccndid_result, &ccndid_result_size);
	}
	if (res >= 0 && ccndid_result_size == CCNDID_length) {
		memcpy((void*)self->ccndid, ccndid_result, CCNDID_length);
	} else {
		self->error = true;
	}
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&resultbuf);
}
Esempio n. 5
0
/**
 * Read a slice (from a repository) given the name.
 * @param h is the ccn_handle on which to read.
 * @param name is the charbuf containing the name of the sync slice to be read.
 * @param slice is a pointer to a ccns_slice object which will be filled in
 *  on successful return.
 * @returns 0 on success, -1 otherwise.
 */
int
ccns_read_slice(struct ccn *h, struct ccn_charbuf *name,
                struct ccns_slice *slice) {
    struct ccn_parsed_ContentObject pco_space = { 0 };
    struct ccn_parsed_ContentObject *pco = &pco_space;
    struct ccn_charbuf *nc = ccn_charbuf_create_n(name->length);
    struct ccn_charbuf *cob = ccn_charbuf_create();
    const unsigned char *content;
    size_t content_length;
    int res = -1;

    if (nc == NULL || cob == NULL)
        goto Cleanup;

    ccn_charbuf_append_charbuf(nc, name);
    res = ccn_resolve_version(h, nc,  CCN_V_HIGHEST, 100); // XXX: timeout
    if (res < 0)
        goto Cleanup;
    if (res == 0) {
        // TODO: check if the last component is a segment number, chop it off, try again.
    }
    res = ccn_get(h, nc, NULL, 100, cob, pco, NULL, 0);
    if (res < 0)
        goto Cleanup;
    if (pco->type != CCN_CONTENT_DATA) {
        res = -1;
        goto Cleanup;
    }
    res = ccn_content_get_value(cob->buf, cob->length, pco,
                                &content, &content_length);
    if (res < 0)
        goto Cleanup;
    res = slice_parse(slice, content, content_length);

Cleanup:
    ccn_charbuf_destroy(&nc);
    ccn_charbuf_destroy(&cob);
    return (res);
}
Esempio n. 6
0
/**
 *
 * Get ccnd id
 *
 */
static int 
get_ccndid(struct ccn *h, struct ccn_charbuf *local_scope_template,
        unsigned char *ccndid)
{
	struct ccn_charbuf *name = NULL;
	struct ccn_charbuf *resultbuf = NULL;
	struct ccn_parsed_ContentObject pcobuf = {0};
	char ccndid_uri[] = "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
	const unsigned char *ccndid_result;
	static size_t ccndid_result_size;
	int res;

	name = ccn_charbuf_create();
	resultbuf = ccn_charbuf_create();

	res = ccn_name_from_uri(name, ccndid_uri);
	ON_ERROR_EXIT(res, "Unable to parse service locator URI for ccnd key\n");

	/* get Data */
	res = ccn_get(h, name, local_scope_template, 4500, resultbuf, &pcobuf, NULL, 0);
	ON_ERROR_EXIT(res, "Unable to get key from ccnd\n");

	/* extract from Data */
	res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
            resultbuf->buf,
            pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
            pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
            &ccndid_result, &ccndid_result_size);
	ON_ERROR_EXIT(res, "Unable to parse ccnd response for ccnd id\n");

	memcpy((void *)ccndid, ccndid_result, ccndid_result_size);

	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&resultbuf);

	return (ccndid_result_size);
}
Esempio n. 7
0
static int
write_slice(struct ccn *h,
            struct ccns_slice *slice,
            struct ccn_charbuf *name) {
    struct ccn_charbuf *content = NULL;
    unsigned char *cbuf = NULL;
    size_t clength = 0;
    struct ccn_charbuf *sw = NULL;
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *cob = NULL;
    struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
    struct ccn_closure *wc = NULL;
    int res;

    sw = ccn_charbuf_create_n(32 + name->length);
    if (sw == NULL) {
        res = -1;
        goto Cleanup;
    }
    ccn_charbuf_append_charbuf(sw, name);
    ccn_name_chop(sw, NULL, -1); // remove segment number
    ccn_name_from_uri(sw, "%C1.R.sw");
    ccn_name_append_nonce(sw);

    // create and sign the content object
    cob = ccn_charbuf_create();
    if (cob == NULL) {
        res = -1;
        goto Cleanup;
    }
    if (slice != NULL) {
        content = ccn_charbuf_create();
        if (content == NULL) {
            res = -1;
            goto Cleanup;
        }
        res = append_slice(content, slice);
        if (res < 0)
            goto Cleanup;
        cbuf = content->buf;
        clength = content->length;
    } else {
        sparm.type = CCN_CONTENT_GONE;
    }

    sparm.sp_flags = CCN_SP_FINAL_BLOCK;
    res = ccn_sign_content(h, cob, name, &sparm, cbuf, clength);
    if (res < 0)
        goto Cleanup;
    // establish handler for interest in the slice content object
    wc = calloc(1, sizeof(*wc));
    if (wc == NULL) {
        res = -1;
        goto Cleanup;
    }
    wc->p = &write_interest_handler;
    wc->data = cob;
    res = ccn_set_interest_filter(h, name, wc);
    if (res < 0)
        goto Cleanup;
    templ = make_scope1_template();
    if (templ == NULL) {
        res = -1;
        goto Cleanup;
    }
    res = ccn_get(h, sw, templ, 1000, NULL, NULL, NULL, 0);
    if (res < 0)
        goto Cleanup;
    ccn_run(h, 1000); // give the repository a chance to fetch the data
    if (wc->intdata != 1) {
        res = -1;
        goto Cleanup;
    }
    res = 0;
Cleanup:
    ccn_set_interest_filter(h, name, NULL);
    if (wc != NULL)
        free(wc);
    ccn_charbuf_destroy(&cob);
    ccn_charbuf_destroy(&content);
    ccn_charbuf_destroy(&sw);
    ccn_charbuf_destroy(&templ);
    return (res);
}
Esempio n. 8
0
// creates a full structure without action, if proto == "face" only the
// faceid (from cmd_host parameter) and lifetime will be filled in.
struct ccn_face_instance *
parse_ccn_face_instance(struct ccndc_data *self,
                        const char *cmd_proto,
                        const char *cmd_host,     const char *cmd_port,
                        const char *cmd_mcastttl, const char *cmd_mcastif,
                        int freshness)
{
    struct ccn_face_instance *entry;
    struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG)};
    struct addrinfo mcasthints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG | AI_NUMERICHOST)};
    struct addrinfo *raddrinfo = NULL;
    struct addrinfo *mcastifaddrinfo = NULL;
    char rhostnamebuf [NI_MAXHOST];
    char rhostportbuf [NI_MAXSERV];
    int off_address = -1, off_port = -1, off_source_address = -1;
    int res;
    int socktype;
    
    entry = calloc(1, sizeof(*entry));
    if (entry == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    // allocate storage for Face data
    entry->store = ccn_charbuf_create();
    if (entry->store == NULL) {
        ccndc_warn(__LINE__, "Fatal error: memory allocation failed");
        goto ExitOnError;
    }
    // copy static info
    entry->ccnd_id = (const unsigned char *)self->ccnd_id;
    entry->ccnd_id_size = self->ccnd_id_size;
    
    if (cmd_proto == NULL) {
        ccndc_warn(__LINE__, "command error, missing address type\n");
        goto ExitOnError;
    }
    if (strcasecmp(cmd_proto, "udp") == 0) {
        entry->descr.ipproto = IPPROTO_UDP;
        socktype = SOCK_DGRAM;
    } else if (strcasecmp(cmd_proto, "tcp") == 0) {
        entry->descr.ipproto = IPPROTO_TCP;
        socktype = SOCK_STREAM;
    } else if (strcasecmp(cmd_proto, "face") == 0) {
        errno = 0;
        unsigned long faceid = strtoul(cmd_host, (char **)NULL, 10);
        if (errno == ERANGE || errno == EINVAL || faceid > UINT_MAX || faceid == 0) {
            ccndc_warn(__LINE__, "command error, face number invalid or out of range '%s'\n", cmd_host);
            goto ExitOnError;
        }
        entry->faceid = (unsigned) faceid;
        entry->lifetime = freshness;
        return (entry);
    } else {
        ccndc_warn(__LINE__, "command error, unrecognized address type '%s'\n", cmd_proto);
        goto ExitOnError;
    }
    
    if (cmd_host == NULL) {
        ccndc_warn(__LINE__, "command error, missing hostname\n");
        goto ExitOnError;
    }
    
    if (cmd_port == NULL || cmd_port[0] == 0)
        cmd_port = CCN_DEFAULT_UNICAST_PORT;
    
    hints.ai_socktype = socktype;
    res = getaddrinfo(cmd_host, cmd_port, &hints, &raddrinfo);
    if (res != 0 || raddrinfo == NULL) {
        ccndc_warn(__LINE__, "command error, getaddrinfo for host [%s] port [%s]: %s\n", cmd_host, cmd_port, gai_strerror(res));
        goto ExitOnError;
    }
    res = getnameinfo(raddrinfo->ai_addr, raddrinfo->ai_addrlen,
                      rhostnamebuf, sizeof(rhostnamebuf),
                      rhostportbuf, sizeof(rhostportbuf),
                      NI_NUMERICHOST | NI_NUMERICSERV);
    freeaddrinfo(raddrinfo);
    if (res != 0) {
        ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res));
        goto ExitOnError;
    }
    
    off_address = entry->store->length;
    res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1);
    if (res != 0) {
        ccndc_warn(__LINE__, "Cannot append to charbuf");
        goto ExitOnError;
    }
    
    off_port = entry->store->length;
    res = ccn_charbuf_append(entry->store, rhostportbuf, strlen(rhostportbuf)+1);
    if (res != 0) {
        ccndc_warn(__LINE__, "Cannot append to charbuf");
        goto ExitOnError;
    }
    
    entry->descr.mcast_ttl = -1;
    if (cmd_mcastttl != NULL) {
        char *endptr;
        entry->descr.mcast_ttl = strtol(cmd_mcastttl, &endptr, 10); 
        if ((endptr != &cmd_mcastttl[strlen(cmd_mcastttl)]) ||
            entry->descr.mcast_ttl < 0 || entry->descr.mcast_ttl > 255) {
            ccndc_warn(__LINE__, "command error, invalid multicast ttl: %s\n", cmd_mcastttl);
            goto ExitOnError;
        }
    }
    
    if (cmd_mcastif != NULL) {
        res = getaddrinfo(cmd_mcastif, NULL, &mcasthints, &mcastifaddrinfo);
        if (res != 0) {
            ccndc_warn(__LINE__, "command error, incorrect multicat interface [%s]: "
                       "mcastifaddr getaddrinfo: %s\n", cmd_mcastif, gai_strerror(res));
            goto ExitOnError;
        }
        
        res = getnameinfo(mcastifaddrinfo->ai_addr, mcastifaddrinfo->ai_addrlen,
                          rhostnamebuf, sizeof(rhostnamebuf),
                          NULL, 0,
                          NI_NUMERICHOST | NI_NUMERICSERV);
        freeaddrinfo(mcastifaddrinfo);
        if (res != 0) {
            ccndc_warn(__LINE__, "command error, getnameinfo: %s\n", gai_strerror(res));
            goto ExitOnError;
        }
        
        off_source_address = entry->store->length;
        res = ccn_charbuf_append(entry->store, rhostnamebuf, strlen(rhostnamebuf)+1);
        if (res != 0) {
            ccndc_warn(__LINE__, "Cannot append to charbuf");
            goto ExitOnError;
        }
    }
    
    entry->descr.address = (const char *)(entry->store->buf + off_address);
    entry->descr.port = (const char *)(entry->store->buf + off_port);
    if (off_source_address >= 0) {
        entry->descr.source_address = (const char *)(entry->store->buf + off_source_address);
    }
    
    entry->lifetime = freshness;
    
    return entry;
    
ExitOnError:
    ccn_face_instance_destroy(&entry);
    return (NULL);
}

struct ccn_face_instance *
parse_ccn_face_instance_from_face(struct ccndc_data *self,
                                  const char *cmd_faceid)
{
    struct ccn_face_instance *entry = calloc(1, sizeof(*entry));
    
    // allocate storage for Face data
    entry->store = ccn_charbuf_create();
    
    // copy static info
    entry->ccnd_id = (const unsigned char *)self->ccnd_id;
    entry->ccnd_id_size = self->ccnd_id_size;
    
    /* destroy a face - the URI field will hold the face number */
    if (cmd_faceid == NULL) {
        ccndc_warn(__LINE__, "command error, missing face number for destroyface\n");
        goto ExitOnError;
    }
    
    char *endptr;
    int facenumber = strtol(cmd_faceid, &endptr, 10);
    if ((endptr != &cmd_faceid[strlen(cmd_faceid)]) ||
        facenumber < 0) {
        ccndc_warn(__LINE__, "command error invalid face number for destroyface: %d\n", facenumber);
        goto ExitOnError;
    }
    
    entry->faceid = facenumber;
    
    return entry;
    
ExitOnError:
    ccn_face_instance_destroy(&entry);
    return (NULL);
}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// "private section
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

int
ccndc_get_ccnd_id(struct ccndc_data *self)
{
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    char ccndid_uri[] = "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
    const unsigned char *ccndid_result;
    int res = 0;
    
    name = ccn_charbuf_create();
    if (name == NULL) {
        ccndc_warn(__LINE__, "Unable to allocate storage for service locator name charbuf\n");
        return -1;
    }
    
    resultbuf = ccn_charbuf_create();
    if (resultbuf == NULL) {
        ccndc_warn(__LINE__, "Unable to allocate storage for result charbuf");
        res = -1;
        goto Cleanup;
    }
    
    res = ccn_name_from_uri(name, ccndid_uri);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to parse service locator URI for ccnd key");
        goto Cleanup;
    }
    
    res = ccn_get(self->ccn_handle,
                  name,
                  self->local_scope_template,
                  4500, resultbuf, &pcobuf, NULL, 0);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to get key from ccnd");
        goto Cleanup;
    }
    
    res = ccn_ref_tagged_BLOB (CCN_DTAG_PublisherPublicKeyDigest,
                               resultbuf->buf,
                               pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
                               pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
                               &ccndid_result, &self->ccnd_id_size);
    if (res < 0) {
        ccndc_warn(__LINE__, "Unable to parse ccnd response for ccnd id");
        goto Cleanup;
    }
    
    if (self->ccnd_id_size > sizeof (self->ccnd_id))
    {
        ccndc_warn(__LINE__, "Incorrect size for ccnd id in response");
        goto Cleanup;
    }
    
    memcpy(self->ccnd_id, ccndid_result, self->ccnd_id_size);
    
Cleanup:
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&resultbuf);
    return (res);
}


struct ccn_face_instance *
ccndc_do_face_action(struct ccndc_data *self,
                     const char *action,
                     struct ccn_face_instance *face_instance)
{
    struct ccn_charbuf *newface = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    struct ccn_face_instance *new_face_instance = NULL;
    const unsigned char *ptr = NULL;
    size_t length = 0;
    int res = 0;
    
    face_instance->action = action;
    
    /* Encode the given face instance */
    newface = ccn_charbuf_create();
    ON_NULL_CLEANUP(newface);
    ON_ERROR_CLEANUP(ccnb_append_face_instance(newface, face_instance));
    
    temp = ccn_charbuf_create();
    ON_NULL_CLEANUP(temp);
    res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, newface->buf, newface->length);
    ON_ERROR_CLEANUP(res);
    resultbuf = ccn_charbuf_create();
    ON_NULL_CLEANUP(resultbuf);
    
    /* Construct the Interest name that will create the face */
    name = ccn_charbuf_create();
    ON_NULL_CLEANUP(name);
    ON_ERROR_CLEANUP(ccn_name_init(name));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx"));
    ON_ERROR_CLEANUP(ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, face_instance->action));
    ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length));
    
    res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
    ON_ERROR_CLEANUP(res);
    
    ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length));
    new_face_instance = ccn_face_instance_parse(ptr, length);
    ON_NULL_CLEANUP(new_face_instance);
    ccn_charbuf_destroy(&newface);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    return (new_face_instance);
    
Cleanup:
    ccn_charbuf_destroy(&newface);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_face_instance_destroy(&new_face_instance);
    return (NULL);
}

int
ccndc_do_prefix_action(struct ccndc_data *self,
                       const char *action,
                       struct ccn_forwarding_entry *forwarding_entry)
{
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_charbuf *signed_info = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *prefixreg = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    struct ccn_forwarding_entry *new_forwarding_entry = NULL;
    
    const unsigned char *ptr = NULL;
    size_t length = 0;
    int res;
    
    forwarding_entry->action = action;
    
    prefixreg = ccn_charbuf_create();
    ON_NULL_CLEANUP(prefixreg);
    ON_ERROR_CLEANUP(ccnb_append_forwarding_entry(prefixreg, forwarding_entry));
    temp = ccn_charbuf_create();
    ON_NULL_CLEANUP(temp);
    res = ccn_sign_content(self->ccn_handle, temp, self->no_name, NULL, prefixreg->buf, prefixreg->length);
    ON_ERROR_CLEANUP(res);    
    resultbuf = ccn_charbuf_create();
    ON_NULL_CLEANUP(resultbuf);
    name = ccn_charbuf_create();
    ON_ERROR_CLEANUP(ccn_name_init(name));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, "ccnx"));
    ON_ERROR_CLEANUP(ccn_name_append(name, forwarding_entry->ccnd_id, forwarding_entry->ccnd_id_size));
    ON_ERROR_CLEANUP(ccn_name_append_str(name, forwarding_entry->action));
    ON_ERROR_CLEANUP(ccn_name_append(name, temp->buf, temp->length));
    res = ccn_get(self->ccn_handle, name, self->local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
    ON_ERROR_CLEANUP(res);
    ON_ERROR_CLEANUP(ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length));
    new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length);
    ON_NULL_CLEANUP(new_forwarding_entry);
    
    res = new_forwarding_entry->faceid;
    
    ccn_forwarding_entry_destroy(&new_forwarding_entry);
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&prefixreg);
    
    return (res);
    
    /* This is where ON_ERROR_CLEANUP sends us in case of an error
     * and we must free any storage we allocated before returning.
     */
Cleanup:
    ccn_charbuf_destroy(&signed_info);
    ccn_charbuf_destroy(&temp);
    ccn_charbuf_destroy(&resultbuf);
    ccn_charbuf_destroy(&name);
    ccn_charbuf_destroy(&prefixreg);
    
    return (-1);
}
Esempio n. 9
0
/**
 * 
 * Bind a prefix to a face
 *
 */
static int 
register_unregister_prefix(struct ccn *h, struct ccn_charbuf *local_scope_template,
        struct ccn_charbuf *no_name, struct ccn_charbuf *name_prefix,
        struct ccn_face_instance *face_instance, int operation)
{
	struct ccn_charbuf *temp = NULL;
	struct ccn_charbuf *resultbuf = NULL;
	struct ccn_charbuf *signed_info = NULL;
	struct ccn_charbuf *name = NULL;
	struct ccn_charbuf *prefixreg = NULL;
	struct ccn_parsed_ContentObject pcobuf = {0};
	struct ccn_forwarding_entry forwarding_entry_storage = {0};
	struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage;
	struct ccn_forwarding_entry *new_forwarding_entry;
	const unsigned char *ptr = NULL;
	size_t length = 0;
	int res;

	/* Register or unregister the prefix */
	forwarding_entry->action = (operation == OP_REG) ? "prefixreg" : "unreg";
	forwarding_entry->name_prefix = name_prefix;
	forwarding_entry->ccnd_id = face_instance->ccnd_id;
	forwarding_entry->ccnd_id_size = face_instance->ccnd_id_size;
	forwarding_entry->faceid = face_instance->faceid;
	forwarding_entry->flags = -1;
	forwarding_entry->lifetime = 2100;

	prefixreg = ccn_charbuf_create();
	ccnb_append_forwarding_entry(prefixreg, forwarding_entry);
	temp = ccn_charbuf_create();
	res = ccn_sign_content(h, temp, no_name, NULL, prefixreg->buf, prefixreg->length);
	resultbuf = ccn_charbuf_create();

	/* construct Interest containing prefixreg request */
	name = ccn_charbuf_create();
	ccn_name_init(name);
	ccn_name_append_str(name, "ccnx");
	ccn_name_append(name, face_instance->ccnd_id, face_instance->ccnd_id_size);
	ccn_name_append_str(name, (operation == OP_REG) ? "prefixreg" : "unreg");
	ccn_name_append(name, temp->buf, temp->length);

	/* send Interest, get Data */
	res = ccn_get(h, name, local_scope_template, 1000, resultbuf, &pcobuf, NULL, 0);
	ON_ERROR_CLEANUP(res);

	res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
	ON_ERROR_CLEANUP(res);
    
	/* extract new forwarding entry from Data */
	new_forwarding_entry = ccn_forwarding_entry_parse(ptr, length);
	ON_NULL_CLEANUP(new_forwarding_entry);

	res = new_forwarding_entry->faceid;

	ccn_forwarding_entry_destroy(&new_forwarding_entry);
	ccn_charbuf_destroy(&signed_info);
	ccn_charbuf_destroy(&temp);
	ccn_charbuf_destroy(&resultbuf);
	ccn_charbuf_destroy(&name);
	ccn_charbuf_destroy(&prefixreg);

	return res;

	cleanup:
		ccn_forwarding_entry_destroy(&new_forwarding_entry);
		ccn_charbuf_destroy(&signed_info);
		ccn_charbuf_destroy(&temp);
		ccn_charbuf_destroy(&resultbuf);
		ccn_charbuf_destroy(&name);
		ccn_charbuf_destroy(&prefixreg);

	return -1;
}
Esempio n. 10
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_seqwriter *w = NULL;
    int blocksize = 1024;
    int torepo = 0;
    int scope = 1;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    size_t blockread;
    unsigned char *buf = NULL;
    struct ccn_charbuf *templ;

    while ((res = getopt(argc, argv, "hrb:s:")) != -1) {
        switch (res) {
        case 'b':
            blocksize = atoi(optarg);
            if (blocksize <= 0 || blocksize > 4096)
                usage(progname);
            break;
        case 'r':
            torepo = 1;
            break;
        case 's':
            scope = atoi(optarg);
            if (scope < 1 || scope > 3)
                usage(progname);
            break;
        default:
        case 'h':
            usage(progname);
            break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc != 1)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad CCN URI: %s\n", progname, argv[0]);
        exit(1);
    }
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }

    buf = calloc(1, blocksize);

    w = ccn_seqw_create(ccn, name);
    if (w == NULL) {
        fprintf(stderr, "ccn_seqw_create failed\n");
        exit(1);
    }
    ccn_seqw_set_block_limits(w, blocksize, blocksize);
    if (torepo) {
        struct ccn_charbuf *name_v = ccn_charbuf_create();
        ccn_seqw_get_name(w, name_v);
        ccn_name_from_uri(name_v, "%C1.R.sw");
        ccn_name_append_nonce(name_v);
        templ = make_template(scope);
        res = ccn_get(ccn, name_v, templ, 60000, NULL, NULL, NULL, 0);
        ccn_charbuf_destroy(&templ);
        ccn_charbuf_destroy(&name_v);
        if (res < 0) {
            fprintf(stderr, "No response from repository\n");
            exit(1);
        }
    }
    blockread = 0;
    for (i = 0;; i++) {
        while (blockread < blocksize) {
            ccn_run(ccn, 1);
            read_res = read(0, buf + blockread, blocksize - blockread);
            if (read_res == 0)
                goto cleanup;
            if (read_res < 0) {
                perror("read");
                status = 1;
                goto cleanup;
            }
            blockread += read_res;
        }
        res = ccn_seqw_write(w, buf, blockread);
        while (res == -1) {
            ccn_run(ccn, 100);
            res = ccn_seqw_write(w, buf, blockread);
        }
        if (res != blockread)
            abort(); /* hmm, ccn_seqw_write did a short write or something */
        blockread = 0;
    }

cleanup:
    // flush out any remaining data and close
    if (blockread > 0) {
        res = ccn_seqw_write(w, buf, blockread);
        while (res == -1) {
            ccn_run(ccn, 100);
            res = ccn_seqw_write(w, buf, blockread);
        }
    }
    ccn_seqw_close(w);
    ccn_run(ccn, 1);
    free(buf);
    buf = NULL;
    ccn_charbuf_destroy(&name);
    ccn_destroy(&ccn);
    exit(status);
}
Esempio n. 11
0
int main (int argc, char **argv) {

    int res;
    //check if user supplied uri to trace
    if(argv[1] == NULL) {
        printf("Usage: trace URI\n");
        exit(1);
    }

    //get the length of user provided URI
    int argv_length = strlen(argv[1]);

    //check first six chars for ccnx:/, if present, skip them
    int skip = 0;
    res = strncmp("ccnx:/", argv[1], 6);
    if(res == 0) {
        skip = 5;
    }

    //if URI does not begins with /, exit
    if (argv[1][skip] != '/') {
        printf("URI must begin with /\n");
        exit(1);
    }

    //check if uri ends with slash, append if missing
    char *slash = "";
    if (argv[1][argv_length-1] != '/') {
        slash = "/";
    }



    //allocate memory for trace URI = /trace/user_input/random_number
    char *URI = (char *) malloc(sizeof(char)* argv_length+1); //find size of rand
    if(URI == NULL) {
        fprintf(stderr, "Can not allocate memory for URI\n");
        exit(1);
    }

    //put together the trace URI, add a random number to end of URI
    srand ((unsigned int)time (NULL)*getpid());
    sprintf(URI, "%s%s", argv[1]+skip, slash);

    //allocate memory for interest
    struct ccn_charbuf *ccnb = ccn_charbuf_create();
    if(ccnb == NULL) {
        fprintf(stderr, "Can not allocate memory for interest\n");
        exit(1);
    }

    //adding name to interest
    res = ccn_name_from_uri(ccnb, URI);
    if(res == -1) {
        fprintf(stderr, "Failed to assign name to interest");
        exit(1);
    }

    //create the ccn handle
    struct ccn *ccn = ccn_create();
    if(ccn == NULL) {
        fprintf(stderr, "Can not create ccn handle\n");
        exit(1);
    }

    //connect to ccnd
    res = ccn_connect(ccn, NULL);
    if (res == -1) {
        fprintf(stderr, "Could not connect to ccnd... exiting\n");
        exit(1);
    }

#ifdef DEBUG
    printf("Connected to CCND, return code: %d\n", res);
#endif

    //allocate buffer for response
    struct ccn_charbuf *resultbuf = ccn_charbuf_create();
    if(resultbuf == NULL) {
        fprintf(stderr, "Can not allocate memory for URI\n");
        exit(1);
    }

    //setting the parameters for ccn_get
    struct ccn_parsed_ContentObject pcobuf = { 0 };
    int timeout_ms = 6000;

    //express interest
    //res = ccn_get(ccn, ccnb, NULL, timeout_ms, resultbuf, &pcobuf, NULL, 0);

    //if cached answer is not allowed, set the template
    //make sure AnswerOriginKind is 0x0
    if(!ALLOW_CACHE) {
        struct ccn_charbuf *templ = ccn_charbuf_create();
        ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
        ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
        ccn_charbuf_append_closer(templ); /* </Name> */
        ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
        ccnb_append_number(templ,0x0);
        ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */
        ccn_charbuf_append_closer(templ);
        //send out the interest
        res = ccn_get(ccn, ccnb, templ, timeout_ms, resultbuf, &pcobuf, NULL, 0);
    } 
    
    //cached answer is allowed, don't set template
    else {
        res = ccn_get(ccn, ccnb, NULL, timeout_ms, resultbuf, &pcobuf, NULL, 0);
    }

    if (res == -1) {
        fprintf(stderr, "Did not receive answer for trace to %s\n", argv[1]);
#ifdef DEBUG
        fprintf(stderr, "Did not receive answer for trace to URI: %s\n", URI);
#endif
        exit(1);
    }

    //extract data from the response
    const unsigned char *ptr;
    size_t length;
    ptr = resultbuf->buf;
    length = resultbuf->length;
    ccn_content_get_value(ptr, length, &pcobuf, &ptr, &length);

    //check if received some data
    if(length == 0) {
        fprintf(stderr, "Received empty answer for trace to %s\n", argv[1]);
#ifdef DEBUG
        fprintf(stderr, "Received empty answer for trace to URI: %s\n", URI);
#endif
        exit(1);
    }

    //print the data
    printf("Reply: %s\n",  ptr);
    printf("Length of data: %Zu\n", length);
    exit(0);
}
Esempio n. 12
0
int
main(int argc, char **argv)
{
    struct ccn *h = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_charbuf *null_name = NULL;
    struct ccn_charbuf *name_prefix = NULL;
    struct ccn_charbuf *newface = NULL;
    struct ccn_charbuf *prefixreg = NULL;
    struct ccn_charbuf *resultbuf = NULL;
    struct ccn_charbuf *temp = NULL;
    struct ccn_charbuf *templ = NULL;
    const unsigned char *ptr = NULL;
    size_t length = 0;
    const char *arg = NULL;
    const char *progname = NULL;
    struct ccn_parsed_ContentObject pcobuf = {0};
    struct ccn_face_instance face_instance_storage = {0};
    struct ccn_face_instance *face_instance = &face_instance_storage;
    struct ccn_forwarding_entry forwarding_entry_storage = {0};
    struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage;
    struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
    struct ccn_charbuf *keylocator_templ = NULL;
    struct ccn_keystore *keystore = NULL;
    long expire = -1;
    int ipproto;
    unsigned char ccndid_storage[32] = {0};
    const unsigned char *ccndid = NULL;
    size_t ccndid_size = 0;
    int res;
    int opt;

    progname = argv[0];
    while ((opt = getopt(argc, argv, "h")) != -1) {
        switch (opt) {
        case 'h':
        default:
            usage(progname);
        }
    }

    /* Sanity check the URI and argument count */
    arg = argv[optind];
    if (arg == NULL)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, arg);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccn URI: %s\n", progname, arg);
        exit(1);
    }
    if (argc - optind < 3 || argc - optind > 4)
        usage(progname);

    h = ccn_create();
    res = ccn_connect(h, NULL);
    if (res < 0) {
        ccn_perror(h, "ccn_connect");
        exit(1);
    }

    newface = ccn_charbuf_create();
    temp = ccn_charbuf_create();
    templ = ccn_charbuf_create();
    keylocator_templ = ccn_charbuf_create();

    resultbuf = ccn_charbuf_create();
    name_prefix = ccn_charbuf_create();
    null_name = ccn_charbuf_create();
    CHKRES(ccn_name_init(null_name));

    keystore = ccn_keystore_create();

    /* We need to figure out our local ccnd's CCIDID */
    /* Set up our Interest template to indicate scope 1 */
    ccn_charbuf_reset(templ);
    ccnb_element_begin(templ, CCN_DTAG_Interest);
    ccnb_element_begin(templ, CCN_DTAG_Name);
    ccnb_element_end(templ);	/* </Name> */
    ccnb_tagged_putf(templ, CCN_DTAG_Scope, "1");
    ccnb_element_end(templ);	/* </Interest> */

    ccn_charbuf_reset(name);
    CHKRES(res = ccn_name_from_uri(name, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY"));
    CHKRES(res = ccn_get(h, name, templ, 200, resultbuf, &pcobuf, NULL, 0));
    res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
                              resultbuf->buf,
                              pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
                              pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
                              &ccndid, &ccndid_size);
    CHKRES(res);
    if (ccndid_size > sizeof(ccndid_storage))
        CHKRES(-1);
    memcpy(ccndid_storage, ccndid, ccndid_size);
    ccndid = ccndid_storage;

    face_instance->action = "newface";
    face_instance->ccnd_id = ccndid;
    face_instance->ccnd_id_size = ccndid_size;
    if (strcmp(argv[optind + 1], "tcp") == 0)
        ipproto = 6;
    else if (strcmp(argv[optind + 1], "udp") == 0)
        ipproto = 17;
    else
        ipproto = atoi(argv[optind + 1]);
    face_instance->descr.ipproto = ipproto; // XXX - 6 = tcp or 17 = udp
    face_instance->descr.address = argv[optind + 2];
    face_instance->descr.port = argv[optind + 3];
    if (face_instance->descr.port == NULL)
        face_instance->descr.port = CCN_DEFAULT_UNICAST_PORT;
    face_instance->descr.mcast_ttl = -1;
    face_instance->lifetime = (~0U) >> 1;

    CHKRES(res = ccnb_append_face_instance(newface, face_instance));
    temp->length = 0;
    CHKRES(ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME")));
    res = ccn_keystore_init(keystore,
                            ccn_charbuf_as_string(temp),
                            "Th1s1sn0t8g00dp8ssw0rd.");
    CHKRES(res);

    ccnb_element_begin(keylocator_templ, CCN_DTAG_SignedInfo);
    ccnb_element_begin(keylocator_templ, CCN_DTAG_KeyLocator);
    ccnb_element_begin(keylocator_templ, CCN_DTAG_Key);
    CHKRES(ccn_append_pubkey_blob(keylocator_templ, ccn_keystore_public_key(keystore)));
    ccnb_element_end(keylocator_templ);	/* </Key> */
    ccnb_element_end(keylocator_templ);	/* </KeyLocator> */
    ccnb_element_end(keylocator_templ);    /* </SignedInfo> */
    sp.template_ccnb = keylocator_templ;
    sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
    sp.freshness = expire;
    ccn_charbuf_reset(temp);
    res = ccn_sign_content(h, temp, null_name, &sp,
                           newface->buf, newface->length);
    CHKRES(res);

    /* Create the new face */
    CHKRES(ccn_name_init(name));
    CHKRES(ccn_name_append_str(name, "ccnx"));
    CHKRES(ccn_name_append(name, ccndid, ccndid_size));
    CHKRES(ccn_name_append(name, "newface", 7));
    CHKRES(ccn_name_append(name, temp->buf, temp->length));
    res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0);
    if (res < 0) {
        fprintf(stderr, "no response from face creation request\n");
        exit(1);
    }
    ptr = resultbuf->buf;
    length = resultbuf->length;
    res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
    CHKRES(res);
    face_instance = ccn_face_instance_parse(ptr, length);
    if (face_instance == NULL)
        CHKRES(res = -1);
    CHKRES(face_instance->faceid);

    /* Finally, register the prefix */
    ccn_charbuf_reset(name_prefix);
    CHKRES(ccn_name_from_uri(name_prefix, arg));
    forwarding_entry->action = "prefixreg";
    forwarding_entry->name_prefix = name_prefix;
    forwarding_entry->ccnd_id = ccndid;
    forwarding_entry->ccnd_id_size = ccndid_size;
    forwarding_entry->faceid = face_instance->faceid;
    forwarding_entry->flags = -1; /* let ccnd decide */
    forwarding_entry->lifetime = (~0U) >> 1;
    prefixreg = ccn_charbuf_create();
    CHKRES(res = ccnb_append_forwarding_entry(prefixreg, forwarding_entry));
    ccn_charbuf_reset(temp);
    res = ccn_sign_content(h, temp, null_name, &sp,
                           prefixreg->buf, prefixreg->length);
    CHKRES(res);
    CHKRES(ccn_name_init(name));
    CHKRES(ccn_name_append_str(name, "ccnx"));
    CHKRES(ccn_name_append(name, ccndid, ccndid_size));
    CHKRES(ccn_name_append_str(name, "prefixreg"));
    CHKRES(ccn_name_append(name, temp->buf, temp->length));
    res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0);
    if (res < 0) {
        fprintf(stderr, "no response from prefix registration request\n");
        exit(1);
    }
    fprintf(stderr, "Prefix %s will be forwarded to face %d\n", arg, face_instance->faceid);

    /* We're about to exit, so don't bother to free everything. */
    ccn_destroy(&h);
    exit(res < 0);
}
Esempio n. 13
0
/**
 * Resolve the version, based on existing ccn content.
 * @param h is the the ccn handle; it may be NULL, but it is preferable to
 *        use the handle that the client probably already has.
 * @param name is a ccnb-encoded Name prefix. It gets extended in-place with
 *        one additional Component such that it names highest extant
 *        version that can be found, subject to the supplied timeout.
 * @param versioning_flags presently must be CCN_V_HIGH or CCN_V_HIGHEST,
 *        possibly combined with CCN_V_NESTOK.  If CCN_V_NESTOK is not present
 *        and the ending component appears to be a version, the routine
 *        returns 0 immediately, on the assumption that an explicit
 *        version has already been provided.
 * @param timeout_ms is a time value in milliseconds. This is applied per
 *        fetch attempt, so the total time may be longer by a factor that
 *        depends on the number of (ccn) hops to the source(s).
 * @returns -1 for error, 0 if name could not be extended, 1 if was.
 */
int
ccn_resolve_version(struct ccn *h, struct ccn_charbuf *name,
                    int versioning_flags, int timeout_ms)
{
    int res;
    int myres = -1;
    struct ccn_parsed_ContentObject pco_space = { 0 };
    struct ccn_charbuf *templ = NULL;
    struct ccn_charbuf *prefix = ccn_charbuf_create();
    struct ccn_charbuf *cobj = ccn_charbuf_create();
    struct ccn_parsed_ContentObject *pco = &pco_space;
    struct ccn_indexbuf *ndx = ccn_indexbuf_create();
    const unsigned char *vers = NULL;
    size_t vers_size = 0;
    int n;
    struct ccn_indexbuf *nix = ccn_indexbuf_create();
    unsigned char lowtime[7] = {CCN_MARKER_VERSION, 0, FF, FF, FF, FF, FF};
    
    if ((versioning_flags & ~CCN_V_NESTOK & ~CCN_V_EST) != CCN_V_HIGH) {
        ccn_seterror(h, EINVAL);
        ccn_perror(h, "ccn_resolve_version is only implemented for versioning_flags = CCN_V_HIGH(EST)");
        goto Finish;
    }
    n = ccn_name_split(name, nix);
    if (n < 0)
        goto Finish;
    if ((versioning_flags & CCN_V_NESTOK) == 0) {
        res = ccn_name_comp_get(name->buf, nix, n - 1, &vers, &vers_size);
        if (res >= 0 && vers_size == 7 && vers[0] == CCN_MARKER_VERSION) {
            myres = 0;
            goto Finish;
        }    
    }
    templ = resolve_templ(templ, lowtime, sizeof(lowtime));
    ccn_charbuf_append(prefix, name->buf, name->length); /* our copy */
    cobj->length = 0;
    res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx, 0);
    while (cobj->length != 0) {
        if (pco->type == CCN_CONTENT_NACK) // XXX - also check for number of components
            break;
        res = ccn_name_comp_get(cobj->buf, ndx, n, &vers, &vers_size);
        if (res < 0)
            break;
        if (vers_size == 7 && vers[0] == CCN_MARKER_VERSION) {
            /* Looks like we have versions. */
            name->length = 0;
            ccn_charbuf_append(name, prefix->buf, prefix->length);
            ccn_name_append(name, vers, vers_size);
            myres = 0;
            if ((versioning_flags & CCN_V_EST) == 0)
                break;
            templ = resolve_templ(templ, vers, vers_size);
            if (templ == NULL) break;
            cobj->length = 0;
            res = ccn_get(h, prefix, templ, timeout_ms, cobj, pco, ndx,
                          CCN_GET_NOKEYWAIT);
        }
        else break;
    }
Finish:
    ccn_charbuf_destroy(&prefix);
    ccn_charbuf_destroy(&cobj);
    ccn_indexbuf_destroy(&ndx);
    ccn_indexbuf_destroy(&nix);
    ccn_charbuf_destroy(&templ);
    return(myres);
}
Esempio n. 14
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_seqwriter *w = NULL;
    int blocksize = CCN_MAX_CONTENT_PAYLOAD / 2;
    int freshness = -1;
    int torepo = 0;
    int scope = 1;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    size_t blockread;
    unsigned char *buf = NULL;
    struct ccn_charbuf *templ;
    char *symmetric_suffix = NULL;
    const char *password = NULL;
    char *dir = NULL;
    
    while ((res = getopt(argc, argv, "hrb:s:x:d:p:o:")) != -1) {
        switch (res) {
            case 'b':
                blocksize = atoi(optarg);
                if (blocksize <= 0 || blocksize > CCN_MAX_CONTENT_PAYLOAD)
                    usage(progname);
                break;
            case 'r':
                torepo = 1;
                break;
            case 's':
                scope = atoi(optarg);
                if (scope < 1 || scope > 3)
                    usage(progname);
                break;
            case 'x':
                freshness = atoi(optarg);
                if (freshness < 0)
                    usage(progname);
                break;
            case 'd':
                symmetric_suffix = optarg;
                break;
            case 'p':
                password = optarg;
                break;
            case 'o':
                dir = optarg;
                break;
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argc != 1)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad CCN URI: %s\n", progname, argv[0]);
        exit(1);
    }
    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    buf = calloc(1, blocksize);
    
    w = ccn_seqw_create(ccn, name);
    if (w == NULL) {
        fprintf(stderr, "ccn_seqw_create failed\n");
        exit(1);
    }

    if (symmetric_suffix != NULL) {
        struct ccn_charbuf *key_digest = ccn_charbuf_create();

        if (ccn_get_key_digest_from_suffix(ccn, dir, symmetric_suffix, password, key_digest)) {
            perror("Can't access keystore");
            exit(1);
        }
        ccn_seqw_set_key_digest(w, key_digest->buf, key_digest->length);
        ccn_charbuf_destroy(&key_digest);
    }
    
    ccn_seqw_set_block_limits(w, blocksize, blocksize);
    if (freshness > -1)
        ccn_seqw_set_freshness(w, freshness);
    if (torepo) {
        struct ccn_charbuf *name_v = ccn_charbuf_create();
        ccn_seqw_get_name(w, name_v);
        ccn_name_from_uri(name_v, "%C1.R.sw");
        ccn_name_append_nonce(name_v);
        templ = make_template(scope);
        res = ccn_get(ccn, name_v, templ, 60000, NULL, NULL, NULL, 0);
        ccn_charbuf_destroy(&templ);
        ccn_charbuf_destroy(&name_v);
        if (res < 0) {
            fprintf(stderr, "No response from repository\n");
            exit(1);
        }
    }
    blockread = 0;
    for (i = 0;; i++) {
        while (blockread < blocksize) {
            if (ccn_run(ccn, 1) < 0) {
                fprintf(stderr, "Lost connection to ccnd: %s\n",
                        strerror(ccn_geterror(ccn)));
                exit(1);
            }
            read_res = read(0, buf + blockread, blocksize - blockread);
            if (read_res == 0)
                goto cleanup;
            if (read_res < 0) {
                perror("read");
                status = 1;
                goto cleanup;
            }
            blockread += read_res;
        }
        res = ccn_seqw_write(w, buf, blockread);
        while (res == -1) {
            if (ccn_run(ccn, 100) < 0) {
                fprintf(stderr, "Lost connection to ccnd: %s\n",
                        strerror(ccn_geterror(ccn)));
                exit(1);
            }
            res = ccn_seqw_write(w, buf, blockread);
        }
        if (res != blockread)
            abort(); /* hmm, ccn_seqw_write did a short write or something */
        blockread = 0;
    }
    
cleanup:
    // flush out any remaining data and close
    if (blockread > 0) {
        res = ccn_seqw_write(w, buf, blockread);
        while (res == -1) {
            if (ccn_run(ccn, 100) < 0) {
                fprintf(stderr, "Lost connection to ccnd: %s\n",
                        strerror(ccn_geterror(ccn)));
                exit(1);
            }
            res = ccn_seqw_write(w, buf, blockread);
        }
    }
    ccn_seqw_close(w);
    ccn_run(ccn, 1);
    free(buf);
    buf = NULL;
    ccn_charbuf_destroy(&name);
    ccn_destroy(&ccn);
    exit(status);
}
Esempio n. 15
0
int 
verify_key(const unsigned char *ccnb, 
		struct ccn_parsed_ContentObject *pco,
		int content_type){
	if ( nlsr->debugging )
		printf("verify key called\n");
	int ret=-1;
	//int res;
	
	if ( contain_key_name(ccnb, pco) == 1){
		
		struct ccn_charbuf *key_name=get_key_name(ccnb, pco);
		struct ccn_charbuf *key_uri = ccn_charbuf_create();
		ccn_uri_append(key_uri, key_name->buf, key_name->length, 0);
		if ( nlsr->debugging )
			printf("Key Name from Incoming Content: %s\n",ccn_charbuf_as_string(key_uri));
		int key_type=get_key_type_from_key_name(key_name);
		if ( nlsr->debugging )		
			printf("Key Type: %d \n",key_type);

		struct ccn_charbuf *result = ccn_charbuf_create();
		struct ccn_parsed_ContentObject temp_pco = {0};
		int get_flags = 0;
		get_flags |= CCN_GET_NOKEYWAIT;
		int counter = 0;
		while(ccn_get(nlsr->ccn, key_name, NULL, 500, result, &temp_pco, NULL, 
										get_flags) < 0 && counter < 3) counter++;

		int chk_verify=ccn_verify_content(nlsr->ccn,ccnb,pco);		

		if ( chk_verify == 0 ){
			if ( nlsr->debugging )
				printf("Content verification Successful :)\n");

			if ( counter == 3){
				if ( nlsr->debugging )
					printf("Could not retrieve key by name !!!\n");
			}
			else{
				if ( key_type == ROOT_KEY ){
					ret=0;
				}
				else{
					if ( nlsr->isStrictHierchicalKeyCheck ){
						int key_name_test=check_key_name_hierarchy(ccnb,
																	pco,
																	key_type,
																	content_type);
						if ( key_name_test == 1){
							ret=verify_key(result->buf,&temp_pco,content_type);
						}
					}
					else{ 
						ret=verify_key(result->buf,&temp_pco,content_type);
					}
				}
			}
		}
		ccn_charbuf_destroy(&result);
		ccn_charbuf_destroy(&key_uri);
		ccn_charbuf_destroy(&key_name);
		return ret;
	}

	return ret;
}
Esempio n. 16
0
int
main(int argc, char **argv)
{
    const char *progname = argv[0];
    struct ccn *ccn = NULL;
    struct ccn_charbuf *name = NULL;
    struct ccn_seqwriter *w = NULL;
    long blocksize = 1024;
    int torepo = 0;
    int i;
    int status = 0;
    int res;
    ssize_t read_res;
    unsigned char *buf = NULL;
    while ((res = getopt(argc, argv, "hrb:")) != -1) {
        switch (res) {
            case 'b':
                blocksize = atol(optarg);
                if (blocksize <= 0 || blocksize > 4096)
                    usage(progname);
                break;
            case 'r':
                torepo = 1;
                break;
            default:
            case 'h':
                usage(progname);
                break;
        }
    }
    argc -= optind;
    argv += optind;
    if (argv[0] == NULL)
        usage(progname);
    name = ccn_charbuf_create();
    res = ccn_name_from_uri(name, argv[0]);
    if (res < 0) {
        fprintf(stderr, "%s: bad ccnx URI: %s\n", progname, argv[0]);
        exit(1);
    }
    if (argv[1] != NULL)
        fprintf(stderr, "%s warning: extra arguments ignored\n", progname);

    ccn = ccn_create();
    if (ccn_connect(ccn, NULL) == -1) {
        perror("Could not connect to ccnd");
        exit(1);
    }
    
    buf = calloc(1, blocksize);
    
    w = ccn_seqw_create(ccn, name);
    if (w == NULL) {
        fprintf(stderr, "ccn_seqw_create failed\n");
        exit(1);
    }
    if (torepo) {
        struct ccn_charbuf *name_v = ccn_charbuf_create();
        ccn_seqw_get_name(w, name_v);
        ccn_name_from_uri(name_v, "%C1.R.sw");
        ccn_name_append_nonce(name_v);
        ccn_get(ccn, name_v, NULL, 2000, NULL, NULL, NULL, 0);
        ccn_charbuf_destroy(&name_v);
    }
    for (i = 0;; i++) {
        ccn_run(ccn, 1);
        read_res = read(0, buf, blocksize);
        if (read_res < 0) {
            perror("read");
            read_res = 0;
            status = 1;
        }
        if (read_res == 0) {
            ccn_seqw_close(w);
            w = NULL;
            status = 0;
            break;
        }
        res = ccn_seqw_write(w, buf, read_res);
        while (res == -1) {
            ccn_run(ccn, 100);
            res = ccn_seqw_write(w, buf, read_res);
        }
        if (res != read_res)
            abort(); /* hmm, ccn_seqw_write did a short write or something */
    }
    ccn_run(ccn, 1);
    free(buf);
    buf = NULL;
    ccn_charbuf_destroy(&name);
    ccn_destroy(&ccn);
    exit(status);
}