int ccnb_append_dhcp_content(struct ccn_charbuf *c, int count, const struct ccn_dhcp_entry *head) { int res; int i; const struct ccn_dhcp_entry *de = head; res = ccnb_element_begin(c, CCN_DTAG_Entry); res |= ccnb_tagged_putf(c, CCN_DTAG_Count, "%d", count); for (i = 0; i < count; i ++) { if (de == NULL) { fprintf(stderr, "Error: number of ccn_dhcp_entry does not match\n"); break; } if (de->name_prefix != NULL && de->name_prefix->length > 0) res |= ccn_charbuf_append(c, de->name_prefix->buf, de->name_prefix->length); if (de->address != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Host, "%s", de->address); if (de->port != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Port, "%s", de->port); de = de->next; } res |= ccnb_element_end(c); return res; }
int ccnb_append_forwarding_entry(struct ccn_charbuf *c, const struct ccn_forwarding_entry *fe) { int res; res = ccnb_element_begin(c, CCN_DTAG_ForwardingEntry); if (fe->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", fe->action); if (fe->name_prefix != NULL && fe->name_prefix->length > 0) res |= ccn_charbuf_append(c, fe->name_prefix->buf, fe->name_prefix->length); if (fe->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, fe->ccnd_id, fe->ccnd_id_size); if (fe->faceid != ~0) res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u", fe->faceid); if (fe->flags >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_ForwardingFlags, "%d", fe->flags); if (fe->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", fe->lifetime); res |= ccnb_element_end(c); return(res); }
/*********** <Interest> <Name/> <AnswerOriginKind>19</AnswerOriginKind> <Scope>0</Scope> </Interest> **********/ struct ccn_charbuf * local_scope_rm_template(void) { struct ccn_charbuf *templ = ccn_charbuf_create(); 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_AnswerOriginKind, "%2d", (CCN_AOK_EXPIRE | CCN_AOK_DEFAULT)); ccnb_tagged_putf(templ, CCN_DTAG_Scope, "0"); ccnb_element_end(templ); /* </Interest> */ return(templ); }
/*********************************** * Append a StatusResponse * * @param buf is the buffer to append to. * @param errcode is a 3-digit error code. * It should be documented in StatusResponse.txt. * @param errtext is human-readable text (may be NULL). * @returns 0 for success or -1 for error. */ int ccn_encode_StatusResponse(struct ccn_charbuf *buf, int errcode, const char *errtext) { int res = 0; if (errcode < 100 || errcode > 999) return(-1); res |= ccn_charbuf_append_tt(buf, CCN_DTAG_StatusResponse, CCN_DTAG); res |= ccnb_tagged_putf(buf, CCN_DTAG_StatusCode, "%d", errcode); if (errtext != NULL && errtext[0] != 0) res |= ccnb_tagged_putf(buf, CCN_DTAG_StatusText, "%s", errtext); res |= ccn_charbuf_append_closer(buf); return(res); }
static int process_int_attribute(struct ccn_charbuf *interest, enum ccn_dtag tag, PyObject *py_obj_Interest, const char *attr_name) { PyObject *py_attr; int val, r; r = is_attr_set(py_obj_Interest, attr_name, &py_attr); if (r <= 0) return r; val = _pyccn_Int_AsLong(py_attr); Py_DECREF(py_attr); if (PyErr_Occurred()) return -1; #if 0 r = ccn_charbuf_append_tt(interest, tag, CCN_DTAG); JUMP_IF_NEG_MEM(r, error); r = ccnb_append_number(interest, val); JUMP_IF_NEG_MEM(r, error); r = ccn_charbuf_append_closer(interest); /* </Tag> */ JUMP_IF_NEG_MEM(r, error); #endif r = ccnb_tagged_putf(interest, tag, "%d", val); JUMP_IF_NEG_MEM(r, error); return 1; error: return -1; }
struct ccndc_data * ccndc_initialize_data(void) { struct ccndc_data *self; const char *msg = "Unable to initialize ccndc"; int res; self = calloc(1, sizeof(*self)); if (self == NULL) { ON_ERROR_EXIT (-1, msg); } self->ccn_handle = ccn_create(); ON_ERROR_EXIT(ccn_connect(self->ccn_handle, NULL), "Unable to connect to local ccnd"); ON_ERROR_EXIT(ccndc_get_ccnd_id(self), "Unable to obtain ID of local ccnd"); /* Set up an Interest template to indicate scope 1 (Local) */ self->local_scope_template = ccn_charbuf_create(); res = ccnb_element_begin(self->local_scope_template, CCN_DTAG_Interest); res |= ccnb_element_begin(self->local_scope_template, CCN_DTAG_Name); res |= ccnb_element_end(self->local_scope_template); /* </Name> */ res |= ccnb_tagged_putf(self->local_scope_template, CCN_DTAG_Scope, "1"); res |= ccnb_element_end(self->local_scope_template); /* </Interest> */ ON_ERROR_EXIT(res, msg); /* Create a null name */ self->no_name = ccn_charbuf_create(); ON_ERROR_EXIT(ccn_name_init(self->no_name), msg); self->lifetime = (~0U) >> 1; return self; }
/* * Append AnswerOriginKind element to partially constructed Interest, * requesting to not generate new content. */ static void answer_passive(struct ccn_charbuf *templ, int allow_stale) { int aok = CCN_AOK_CS; if (allow_stale) aok |= CCN_AOK_STALE; ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%d", aok); }
/* * utility, may need to be exported, to append the encoding of a * slice to a charbuf */ static int append_slice(struct ccn_charbuf *c, struct ccns_slice *s) { int res = 0; int i; res |= ccnb_element_begin(c, CCN_DTAG_SyncConfigSlice); res |= ccnb_tagged_putf(c, CCN_DTAG_SyncVersion, "%u", SLICE_VERSION); res |= ccn_charbuf_append_charbuf(c, s->topo); res |= ccn_charbuf_append_charbuf(c, s->prefix); res |= ccnb_element_begin(c, CCN_DTAG_SyncConfigSliceList); for (i = 0; i < s->nclauses ; i++) { res |= ccnb_tagged_putf(c, CCN_DTAG_SyncConfigSliceOp, "%u", 0); res |= ccn_charbuf_append_charbuf(c, s->clauses[i]); } res |= ccnb_element_end(c); res |= ccnb_element_end(c); return (res); }
int get_content_by_content_name(char *content_name, unsigned char **content_data, char *orig_router) { int ret=-1; struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; struct ccn_charbuf *resultbuf = NULL; struct ccn_parsed_ContentObject pcobuf = { 0 }; int res; int allow_stale = 1; int content_only = 1; int scope = -1; const unsigned char *ptr,*ptr_in; size_t length,length_in; int resolve_version = CCN_V_HIGHEST; int timeout_ms = 3000; const unsigned lifetime_default = CCN_INTEREST_LIFETIME_SEC << 12; unsigned lifetime_l12 = lifetime_default; int get_flags = 0; name = ccn_charbuf_create(); res = ccn_name_from_uri(name,content_name); if (res < 0) { fprintf(stderr, "Bad ccn URI: %s\n", content_name); ccn_charbuf_destroy(&name); return ret; } if (allow_stale || lifetime_l12 != lifetime_default || scope != -1) { 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> */ if (allow_stale) { ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ } if (scope != -1) { ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope); } if (lifetime_l12 != lifetime_default) { /* * Choose the interest lifetime so there are at least 3 * expressions (in the unsatisfied case). */ unsigned char buf[3] = { 0 }; int i; for (i = sizeof(buf) - 1; i >= 0; i--, lifetime_l12 >>= 8) buf[i] = lifetime_l12 & 0xff; ccnb_append_tagged_blob(templ, CCN_DTAG_InterestLifetime, buf, sizeof(buf)); }
int ccnb_append_strategy_selection(struct ccn_charbuf *c, const struct ccn_strategy_selection *ss) { int ch; int i; int len; int res; res = ccnb_element_begin(c, CCN_DTAG_StrategySelection); if (ss->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", ss->action); if (ss->name_prefix != NULL && ss->name_prefix->length > 0) res |= ccn_charbuf_append(c, ss->name_prefix->buf, ss->name_prefix->length); if (ss->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, ss->ccnd_id, ss->ccnd_id_size); if (ss->strategyid != NULL) { len = strlen(ss->strategyid); for (i = 0; i < len; i++) { ch = ss->strategyid[i]; if (!(('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ('0' <= ch && ch <= '9') || (ch == '_'))) res |= -1; } if (len > 0) { res |= ccnb_tagged_putf(c, CCN_DTAG_StrategyID, "%.15s", ss->strategyid); if (len >= STRATEGY_ID_MAX_SIZE) res |= -1; } } if (ss->parameters != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_StrategyParameters, "%s", ss->parameters); if (ss->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", ss->lifetime); res |= ccnb_element_end(c); return(res); }
/* * initialize local data */ void init_data(struct ccn_charbuf *local_scope_template, struct ccn_charbuf *no_name) { ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append_tt(local_scope_template, CCN_DTAG_Name, CCN_DTAG); ccn_charbuf_append_closer(local_scope_template); /* </Name> */ ccnb_tagged_putf(local_scope_template, CCN_DTAG_Scope, "1"); ccn_charbuf_append_closer(local_scope_template); /* </Interest> */ ccn_name_init(no_name); }
struct ccn_charbuf * make_scope1_template(void) { struct ccn_charbuf *templ = NULL; templ = ccn_charbuf_create_n(16); 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, "%u", 1); ccnb_element_end(templ); /* </Interest> */ return(templ); }
struct ccn_charbuf* CcnH_localScopeTempl(void) { if (CcnH_localScopeTempl_inst == NULL) { CcnH_localScopeTempl_inst = ccn_charbuf_create(); ccn_charbuf_append_tt(CcnH_localScopeTempl_inst, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append_tt(CcnH_localScopeTempl_inst, CCN_DTAG_Name, CCN_DTAG); ccn_charbuf_append_closer(CcnH_localScopeTempl_inst); ccnb_tagged_putf(CcnH_localScopeTempl_inst, CCN_DTAG_Scope, "1"); ccn_charbuf_append_closer(CcnH_localScopeTempl_inst); } return CcnH_localScopeTempl_inst; }
/* * make_template: construct an interest template containing the specified scope * An unlimited scope is passed in as 3, and the omission of the scope * field from the template indicates this. */ struct ccn_charbuf * make_template(int scope) { struct ccn_charbuf *templ = NULL; 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> */ if (0 <= scope && scope <= 2) ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope); ccn_charbuf_append_closer(templ); /* </Interest> */ return(templ); }
/* * make_template: construct an interest template containing the specified scope * An unlimited scope is passed in as 3, and the omission of the scope * field from the template indicates this. */ struct ccn_charbuf * make_template(int scope) { struct ccn_charbuf *templ = NULL; templ = ccn_charbuf_create(); ccnb_element_begin(templ, CCN_DTAG_Interest); ccnb_element_begin(templ, CCN_DTAG_Name); ccnb_element_end(templ); /* </Name> */ if (0 <= scope && scope <= 2) ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope); ccnb_element_end(templ); /* </Interest> */ return(templ); }
void CcnCC_sendContent(CcnCC self, struct ccn_charbuf* name, TimeSpan expires, void* data, size_t size) { struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; if (expires >= 0) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expires / 1000); sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS; ccn_charbuf_append_closer(sp.template_ccnb); } struct ccn_charbuf* content = ccn_charbuf_create(); if (0 == ccn_sign_content(self->ccnh, content, name, &sp, data, size)) { ccn_put(self->ccnh, content->buf, content->length); } ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&content); }
/** * Creates a template for ccn interest fetch * * @param allow_stale * @param scope */ struct ccn_charbuf* CCNGet::make_template(int allow_stale, int scope) { 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_MaxSuffixComponents, CCN_DTAG); ccnb_append_number(templ, 1); ccn_charbuf_append_closer(templ); /* </MaxSuffixComponents> */ if (allow_stale) { ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccnb_append_number(templ, CCN_AOK_DEFAULT | CCN_AOK_STALE); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ } if (scope >= 0 && scope <= 2) { ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", scope); } ccn_charbuf_append_closer(templ); /* </Interest> */ return(templ); }
/** * Marshal an internal face instance representation into ccnb form */ int ccnb_append_face_instance(struct ccn_charbuf *c, const struct ccn_face_instance *fi) { int res; res = ccnb_element_begin(c, CCN_DTAG_FaceInstance); if (fi->action != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s", fi->action); if (fi->ccnd_id_size != 0) res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest, fi->ccnd_id, fi->ccnd_id_size); if (fi->faceid != ~0) res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u", fi->faceid); if (fi->descr.ipproto >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_IPProto, "%d", fi->descr.ipproto); if (fi->descr.address != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Host, "%s", fi->descr.address); if (fi->descr.port != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_Port, "%s", fi->descr.port); if (fi->descr.source_address != NULL) res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastInterface, "%s", fi->descr.source_address); if (fi->descr.mcast_ttl >= 0 && fi->descr.mcast_ttl != 1) res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastTTL, "%d", fi->descr.mcast_ttl); if (fi->lifetime >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", fi->lifetime); res |= ccnb_element_end(c); return(res); }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *pname = NULL; struct ccn_charbuf *temp = NULL; struct ccn_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 ccn_content_type content_type = CCN_CONTENT_DATA; struct ccn_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 ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; while ((res = getopt(argc, argv, "e:fhk:lvV:p:t:w:x:")) != -1) { switch (res) { case 'e': if (extopt == NULL) extopt = ccn_charbuf_create(); fd = open(optarg, O_RDONLY); if (fd < 0) { perror(optarg); exit(1); } for (;;) { read_res = read(fd, ccn_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 = CCN_CONTENT_DATA; break; } if (0 == strcasecmp(optarg, "ENCR")) { content_type = CCN_CONTENT_ENCR; break; } if (0 == strcasecmp(optarg, "GONE")) { content_type = CCN_CONTENT_GONE; break; } if (0 == strcasecmp(optarg, "KEY")) { content_type = CCN_CONTENT_KEY; break; } if (0 == strcasecmp(optarg, "LINK")) { content_type = CCN_CONTENT_LINK; break; } if (0 == strcasecmp(optarg, "NACK")) { content_type = CCN_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 = 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); } 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 = ccn_charbuf_create(); ccn_charbuf_append(pname, name->buf, name->length); if (prefixcomps >= 0) { res = ccn_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 ccnd */ ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); 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 = ccn_create_version(ccn, name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0); if (res < 0) { fprintf(stderr, "%s: ccn_create_version() failed\n", progname); exit(1); } if (postver != NULL) { res = ccn_name_from_uri(name, postver); if (res < 0) { fprintf(stderr, "-V %s: invalid name suffix\n", postver); exit(0); } } } temp = ccn_charbuf_create(); /* Ask for a FinalBlockID if appropriate. */ if (setfinal) sp.sp_flags |= CCN_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_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expire); sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS; ccn_charbuf_append_closer(sp.template_ccnb); } /* Set key locator, if supplied */ if (key_uri != NULL) { struct ccn_charbuf *c = ccn_charbuf_create(); res = ccn_name_from_uri(c, key_uri); if (res < 0) { fprintf(stderr, "%s is not a valid ccnx URI\n", key_uri); exit(1); } if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG); ccn_charbuf_append(sp.template_ccnb, c->buf, c->length); ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_append_closer(sp.template_ccnb); sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_destroy(&c); } if (extopt != NULL && extopt->length > 0) { if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_append_tagged_blob(sp.template_ccnb, CCN_DTAG_ExtOpt, extopt->buf, extopt->length); sp.sp_flags |= CCN_SP_TEMPL_EXT_OPT; ccn_charbuf_append_closer(sp.template_ccnb); } /* Create the signed content object, ready to go */ temp->length = 0; res = ccn_sign_content(ccn, 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 = ccn_put(ccn, temp->buf, temp->length); if (res < 0) { fprintf(stderr, "ccn_put failed (res == %d)\n", res); exit(1); } } else { in_interest.data = temp; /* Set up a handler for interests */ res = ccn_set_interest_filter(ccn, pname, &in_interest); if (res < 0) { fprintf(stderr, "Failed to register interest (res == %d)\n", res); exit(1); } res = ccn_run(ccn, timeout); if (in_interest.intdata == 0) { if (verbose) fprintf(stderr, "Nobody's interested\n"); exit(1); } } if (verbose) { struct ccn_charbuf *uri = ccn_charbuf_create(); uri->length = 0; ccn_uri_append(uri, name->buf, name->length, 1); printf("wrote %s\n", ccn_charbuf_as_string(uri)); ccn_charbuf_destroy(&uri); } ccn_destroy(&ccn); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&pname); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&extopt); exit(status); }
int main(int argc, char **argv) { struct ccn *ccn = NULL; struct ccn_charbuf *c = NULL; struct ccn_charbuf *templ = NULL; struct upcalldata *data = NULL; int i; int n; int res; long counter = 0; struct ccn_closure *cl = NULL; int timeout_ms = 500; const char *env_timeout = getenv("CCN_LINGER"); const char *env_verify = getenv("CCN_VERIFY"); const char *env_scope = getenv("CCN_SCOPE"); if (argv[1] == NULL || argv[2] != NULL) usage(argv[0]); if (env_timeout != NULL && (i = atoi(env_timeout)) > 0) timeout_ms = i * 1000; c = ccn_charbuf_create(); res = ccn_name_from_uri(c, argv[1]); if (res < 0) usage(argv[0]); ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } data = calloc(1, sizeof(*data)); data->magic = 856372; data->warn = 1492; data->counter = &counter; data->option = 0; if (env_verify && *env_verify) data->option |= MUST_VERIFY; data->scope = -1; if (env_scope != NULL && (i = atoi(env_scope)) >= 0) data->scope = i; cl = calloc(1, sizeof(*cl)); cl->p = &incoming_content; cl->data = data; if (data->scope > -1) { 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> */ ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope); ccn_charbuf_append_closer(templ); /* </Interest> */ } ccn_express_interest(ccn, c, cl, templ); ccn_charbuf_destroy(&templ); cl = NULL; data = NULL; for (i = 0;; i++) { n = counter; ccn_run(ccn, timeout_ms); /* stop if we run dry for 1/2 sec */ fflush(stdout); if (counter == n) break; } ccn_destroy(&ccn); ccn_charbuf_destroy(&c); exit(0); }
enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *c = NULL; struct ccn_charbuf *comp = NULL; struct ccn_charbuf *uri = NULL; struct ccn_charbuf *templ = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; struct ccn_indexbuf *comps = NULL; int matched_comps = 0; int res; int i; struct upcalldata *data = selfp->data; if (data->magic != 856372) abort(); if (kind == CCN_UPCALL_FINAL) return(CCN_UPCALL_RESULT_OK); if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(CCN_UPCALL_RESULT_REEXPRESS); if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) { if ((data->option & MUST_VERIFY) != 0) return(CCN_UPCALL_RESULT_VERIFY); } else if (kind != CCN_UPCALL_CONTENT) abort(); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; comps = info->content_comps; matched_comps = info->pi->prefix_comps; c = ccn_charbuf_create(); uri = ccn_charbuf_create(); templ = ccn_charbuf_create(); /* note that comps->n is 1 greater than the number of explicit components */ if (matched_comps > comps->n) { ccn_uri_append(c, ccnb, ccnb_size, 1); fprintf(stderr, "How did this happen? %s\n", ccn_charbuf_as_string(uri)); exit(1); } data->counter[0]++; /* Recover the same prefix as before */ ccn_name_init(c); res = ccn_name_append_components(c, info->interest_ccnb, info->interest_comps->buf[0], info->interest_comps->buf[matched_comps]); if (res < 0) abort(); comp = ccn_charbuf_create(); ccn_name_init(comp); if (matched_comps + 1 == comps->n) { /* Reconstruct the implicit ContentObject digest component */ ccn_digest_ContentObject(ccnb, info->pco); ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes); } else if (matched_comps < comps->n) { ccn_name_append_components(comp, ccnb, comps->buf[matched_comps], comps->buf[matched_comps + 1]); } res = ccn_uri_append(uri, comp->buf, comp->length, 0); if (res < 0 || uri->length < 1) fprintf(stderr, "*** Error: ccnls line %d res=%d\n", __LINE__, res); else { if (uri->length == 1) ccn_charbuf_append(uri, ".", 1); printf("%s%s\n", ccn_charbuf_as_string(uri) + 1, kind == CCN_UPCALL_CONTENT ? " [verified]" : " [unverified]"); } ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append(templ, c->buf, c->length); /* Name */ if (matched_comps == comps->n) { /* The interest supplied the digest component */ ccn_charbuf_destroy(&comp); /* * We can't rely on the Exclude filter to keep from seeing this, so * say that we need at least one more name component. */ ccn_charbuf_append_tt(templ, CCN_DTAG_MinSuffixComponents, CCN_DTAG); ccn_charbuf_append_tt(templ, 1, CCN_UDATA); ccn_charbuf_append(templ, "1", 1); ccn_charbuf_append_closer(templ); /* </MinSuffixComponents> */ } else { data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0])); data->excl[data->n_excl++] = comp; comp = NULL; } qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare); ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG); for (i = 0; i < data->n_excl; i++) { comp = data->excl[i]; if (comp->length < 4) abort(); ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2); } comp = NULL; ccn_charbuf_append_closer(templ); /* </Exclude> */ ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%d", CCN_AOK_CS); if (data->scope > -1) ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope); ccn_charbuf_append_closer(templ); /* </Interest> */ if (templ->length > data->warn) { fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length); data->warn = data->warn * 8 / 5; } ccn_express_interest(info->h, c, selfp, templ); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&c); ccn_charbuf_destroy(&uri); return(CCN_UPCALL_RESULT_OK); }
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); }
/** * Append ChildSelector to partially constructed Interest, meaning * prefer to send rightmost available. */ static void answer_highest(struct ccn_charbuf *templ) { ccnb_tagged_putf(templ, CCN_DTAG_ChildSelector, "1"); }
/** * Create SignedInfo. * * * @param c is used to hold the result. * @param publisher_key_id points to the digest of the publisher key id. * @param publisher_key_id_size is the size in bytes(32) of the pub key digest * @param timestamp holds the timestamp, as a ccnb-encoded blob, or is NULL to use the current time. * @param type indicates the Type of the ContentObject. * @param freshness is the FreshnessSeconds value, or -1 to omit. * @param finalblockid holds the FinalBlockID, as a ccnb-encoded blob, or is NULL to omit. * @param key_locator is the ccnb-encoded KeyLocator element, or NULL to omit. * @returns 0 for success or -1 for error. */ int ccn_signed_info_create(struct ccn_charbuf *c, const void *publisher_key_id, /* input, sha256 hash */ size_t publisher_key_id_size, /* input, 32 for sha256 hashes */ const struct ccn_charbuf *timestamp,/* input ccnb blob, NULL for "now" */ enum ccn_content_type type, /* input */ int freshness, /* input, -1 means omit */ const struct ccn_charbuf *finalblockid, /* input, NULL means omit */ const struct ccn_charbuf *key_locator) /* input, optional, ccnb encoded */ { int res = 0; const char fakepubkeyid[32] = {0}; if (publisher_key_id != NULL && publisher_key_id_size != 32) return(-1); res |= ccn_charbuf_append_tt(c, CCN_DTAG_SignedInfo, CCN_DTAG); res |= ccn_charbuf_append_tt(c, CCN_DTAG_PublisherPublicKeyDigest, CCN_DTAG); if (publisher_key_id != NULL) { res |= ccn_charbuf_append_tt(c, publisher_key_id_size, CCN_BLOB); res |= ccn_charbuf_append(c, publisher_key_id, publisher_key_id_size); } else { /* XXX - obtain the default publisher key id and append it */ res |= ccn_charbuf_append_tt(c, sizeof(fakepubkeyid), CCN_BLOB); res |= ccn_charbuf_append(c, fakepubkeyid, sizeof(fakepubkeyid)); } res |= ccn_charbuf_append_closer(c); res |= ccn_charbuf_append_tt(c, CCN_DTAG_Timestamp, CCN_DTAG); if (timestamp != NULL) res |= ccn_charbuf_append_charbuf(c, timestamp); else res |= ccnb_append_now_blob(c, CCN_MARKER_NONE); res |= ccn_charbuf_append_closer(c); if (type != CCN_CONTENT_DATA) { res |= ccn_charbuf_append_tt(c, CCN_DTAG_Type, CCN_DTAG); res |= ccn_charbuf_append_tt(c, 3, CCN_BLOB); res |= ccn_charbuf_append_value(c, type, 3); res |= ccn_charbuf_append_closer(c); } if (freshness >= 0) res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d", freshness); if (finalblockid != NULL) { res |= ccn_charbuf_append_tt(c, CCN_DTAG_FinalBlockID, CCN_DTAG); res |= ccn_charbuf_append_charbuf(c, finalblockid); res |= ccn_charbuf_append_closer(c); } if (key_locator != NULL) { /* key_locator is a sub-type that should already be encoded */ res |= ccn_charbuf_append_charbuf(c, key_locator); } res |= ccn_charbuf_append_closer(c); return(res == 0 ? 0 : -1); }