struct ccn_charbuf* CcnH_signForwardingEntry(struct ccn* ccnh, CCNDID ccndid, struct ccn_forwarding_entry* fe) { struct ccn_charbuf* request = ccn_charbuf_create(); ccnb_append_forwarding_entry(request, fe); struct ccn_charbuf* emptyname = ccn_charbuf_create(); ccn_name_init(emptyname); struct ccn_charbuf* signed_request = ccn_charbuf_create(); ccn_sign_content(ccnh, signed_request, emptyname, NULL, request->buf, request->length); struct ccn_charbuf* reqname = ccn_charbuf_create(); ccn_name_from_uri(reqname, "ccnx:/ccnx"); ccn_name_append(reqname, ccndid, CCNDID_length); ccn_name_append_str(reqname, fe->action); ccn_name_append(reqname, signed_request->buf, signed_request->length); ccn_charbuf_destroy(&request); ccn_charbuf_destroy(&emptyname); ccn_charbuf_destroy(&signed_request); return reqname; }
// 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); }
/** * * 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; }
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); }