void ccn_uri_append_percentescaped(struct ccn_charbuf *c, const unsigned char *data, size_t size) { size_t i; unsigned char ch; for (i = 0; i < size && data[i] == '.'; i++) continue; /* For a component that consists solely of zero or more dots, add 3 more */ if (i == size) ccn_charbuf_append(c, "...", 3); for (i = 0; i < size; i++) { ch = data[i]; /* * Leave unescaped only the generic URI unreserved characters. * See RFC 3986. Here we assume the compiler uses ASCII. */ if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '-' || ch == '.' || ch == '_' || ch == '~') ccn_charbuf_append(c, &(data[i]), 1); else ccn_charbuf_putf(c, "%%%02X", (unsigned)ch); } }
/* * utility, may need to be exported, to parse the buffer into a given slice * structure. */ static int slice_parse(struct ccns_slice *s, const unsigned char *p, size_t size) { int res = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); uintmax_t version; int op; int start; struct ccn_charbuf *clause = NULL; if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSlice)) return (-1); ccn_buf_advance(d); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncVersion)) return (-1); ccn_buf_advance(d); ccn_parse_uintmax(d, &version); ccn_buf_check_close(d); if (version != SLICE_VERSION) return (-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->topo); res = ccn_charbuf_append(s->topo, p + start, d->decoder.token_index - start); if (res < 0) return(-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->prefix); res = ccn_charbuf_append(s->prefix, p + start, d->decoder.token_index - start); if (res < 0) return(-1); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceList)) return(-1); ccn_buf_advance(d); clause = ccn_charbuf_create(); if (clause == NULL) return(-1); while (ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceOp)) { ccn_buf_advance(d); op = ccn_parse_nonNegativeInteger(d); // op is a small integer ccn_buf_check_close(d); if (op != 0) break; ccn_charbuf_reset(clause); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) break; res = ccn_charbuf_append(clause, p + start, d->decoder.token_index - start); ccns_slice_add_clause(s, clause); } ccn_charbuf_destroy(&clause); ccn_buf_check_close(d); /* </SyncConfigSliceList> */ ccn_buf_check_close(d); /* </SyncConfigSlice> */ if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return(-1); return(0); }
/* * ccn_append_uri_component: * This takes as input the escaped URI component at s and appends it * to c. This does not do any ccnb-related stuff. * Processing stops at an error or if an unescaped nul, '/', '?', or '#' is found. * A component that consists solely of dots gets special treatment to reverse * the addition of ... by ccn_uri_append_percentescaped. Since '.' is an unreserved * character, percent-encoding is not supposed to change meaning and hence * the dot processing happens after percent-encoding is removed. * A positive return value indicates there were unescaped reserved or * non-printable characters found. This might warrant some extra checking * by the caller. * A return value of -1 indicates the component was "..", so the caller * will need to do something extra to handle this as appropriate. * A return value of -2 indicates the component was empty or ".", so the caller * should do nothing with it. * A return value of -3 indicates a bad %-escaped sequence. * If cont is not NULL, *cont is set to the number of input characters processed. */ int ccn_append_uri_component(struct ccn_charbuf *c, const char *s, size_t limit, size_t *cont) { size_t start = c->length; size_t i; int err = 0; int d1, d2; unsigned char ch; for (i = 0; i < limit; i++) { ch = s[i]; switch (ch) { case 0: case '/': case '?': case '#': limit = i; break; case '%': if (i + 3 > limit || (d1 = hexit(s[i+1])) < 0 || (d2 = hexit(s[i+2])) < 0 ) { return(-3); } ch = d1 * 16 + d2; i += 2; ccn_charbuf_append(c, &ch, 1); break; case ':': case '[': case ']': case '@': case '!': case '$': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case ';': case '=': err++; /* FALLTHROUGH */ default: if (ch <= ' ' || ch > '~') err++; ccn_charbuf_append(c, &ch, 1); break; } } for (i = start; i < c->length && c->buf[i] == '.'; i++) continue; if (i == c->length) { /* all dots */ i -= start; if (i <= 1) { c->length = start; err = -2; } else if (i == 2) { c->length = start; err = -1; } else c->length -= 3; } if (cont != NULL) *cont = limit; return(err); }
/** * Construct a new face instance based on the given address and port * This face instance is only used to send new face request */ static struct ccn_face_instance *construct_face(const unsigned char *ccndid, size_t ccndid_size, const char *address, const char *port) { struct ccn_face_instance *fi = calloc(1, sizeof(*fi)); char rhostnamebuf[NI_MAXHOST]; char rhostportbuf[NI_MAXSERV]; struct addrinfo hints = {.ai_family = AF_UNSPEC, .ai_flags = (AI_ADDRCONFIG), .ai_socktype = SOCK_DGRAM}; struct addrinfo *raddrinfo = NULL; struct ccn_charbuf *store = ccn_charbuf_create(); int host_off = -1; int port_off = -1; int res; res = getaddrinfo(address, port, &hints, &raddrinfo); if (res != 0 || raddrinfo == NULL) { fprintf(stderr, "Error: getaddrinfo\n"); return NULL; } res = getnameinfo(raddrinfo->ai_addr, raddrinfo->ai_addrlen, rhostnamebuf, sizeof(rhostnamebuf), rhostportbuf, sizeof(rhostportbuf), NI_NUMERICHOST | NI_NUMERICSERV); freeaddrinfo(raddrinfo); if (res != 0) { fprintf(stderr, "Error: getnameinfo\n"); return NULL; } fi->store = store; fi->descr.ipproto = IPPROTO_UDP; fi->descr.mcast_ttl = CCN_FIB_MCASTTTL; fi->lifetime = CCN_FIB_LIFETIME; ccn_charbuf_append(store, "newface", strlen("newface") + 1); host_off = store->length; ccn_charbuf_append(store, rhostnamebuf, strlen(rhostnamebuf) + 1); port_off = store->length; ccn_charbuf_append(store, rhostportbuf, strlen(rhostportbuf) + 1); char *b = (char *)store->buf; fi->action = b; fi->descr.address = b + host_off; fi->descr.port = b + port_off; fi->descr.source_address = NULL; fi->ccnd_id = ccndid; fi->ccnd_id_size = ccndid_size; return fi; }
static int do_ping(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags) { struct ccn_ping_client *client = clienth; if (client->total >= 0 && client->sent >= client->total) return 0; struct ccn_charbuf *name = ccn_charbuf_create(); long int rnum; char rnumstr[20]; int res; ccn_charbuf_append(name, client->prefix->buf, client->prefix->length); if (client->number < 0) rnum = random(); else { rnum = client->number; client->number ++; } memset(&rnumstr, 0, 20); sprintf(rnumstr, "%ld", rnum); ccn_name_append_str(name, rnumstr); res = ccn_express_interest(client->h, name, client->closure, NULL); add_ccn_ping_entry(client, name, rnum); client->sent ++; sta.sent ++; ccn_charbuf_destroy(&name); if (res >= 0) return client->interval * 1000000; else return 0; }
/** * Make a new fdholder corresponding to the fd */ PUBLIC struct fdholder * r_io_record_fd(struct ccnr_handle *h, int fd, void *who, socklen_t wholen, int setflags) { int res; struct fdholder *fdholder = NULL; res = fcntl(fd, F_SETFL, O_NONBLOCK); if (res == -1) ccnr_msg(h, "fcntl: %s", strerror(errno)); fdholder = calloc(1, sizeof(*fdholder)); if (fdholder == NULL) return(fdholder); fdholder->name = ccn_charbuf_create(); if (fdholder->name == NULL) abort(); if (who != NULL) ccn_charbuf_append(fdholder->name, who, wholen); fdholder->filedesc = fd; init_face_flags(h, fdholder, setflags); res = r_io_enroll_face(h, fdholder); if (res == -1) { ccn_charbuf_destroy(&fdholder->name); free(fdholder); fdholder = NULL; } return(fdholder); }
static struct ccn_charbuf * ccn_charbuf_duplicate(struct ccn_charbuf *c) { struct ccn_charbuf *ans = ccn_charbuf_create(); ccn_charbuf_append(ans, c->buf, c->length); return(ans); }
static struct ccn_charbuf * resolve_templ(struct ccn_charbuf *templ, unsigned const char *vcomp, int size) { if (templ == NULL) templ = ccn_charbuf_create(); if (size < 3 || size > 16) { ccn_charbuf_destroy(&templ); return(NULL); } templ->length = 0; 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_Exclude, CCN_DTAG); append_filter_all(templ); ccn_charbuf_append_tt(templ, CCN_DTAG_Component, CCN_DTAG); ccn_charbuf_append_tt(templ, size, CCN_BLOB); ccn_charbuf_append(templ, vcomp, size); ccn_charbuf_append_closer(templ); /* </Component> */ append_future_vcomp(templ); append_filter_all(templ); ccn_charbuf_append_closer(templ); /* </Exclude> */ answer_highest(templ); answer_passive(templ); ccn_charbuf_append_closer(templ); /* </Interest> */ return(templ); }
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); }
/** * Write some data to a seqwriter. * * This is roughly analogous to a write(2) call in non-blocking mode. * * The current implementation returns an error and refuses the new data if * it does not fit in the current buffer. * That is, there are no partial writes. * In this case, the caller should ccn_run() for a little while and retry. * * It is also an error to attempt to write more than 4096 bytes. * * @returns the size written, or -1 for an error. In case of an error, * the caller may test ccn_geterror() for values of EAGAIN or * EINVAL from errno.h. */ int ccn_seqw_write(struct ccn_seqwriter *w, const void *buf, size_t size) { struct ccn_charbuf *cob = NULL; int res; int ans; if (w == NULL || w->cl.data != w) return(-1); if (w->buffer == NULL || size > MAX_DATA_SIZE) return(ccn_seterror(w->h, EINVAL)); ans = size; if (size + w->buffer->length > MAX_DATA_SIZE) ans = ccn_seterror(w->h, EAGAIN); else if (size != 0) ccn_charbuf_append(w->buffer, buf, size); if (w->interests_possibly_pending && (w->batching == 0 || ans == -1)) { cob = seqw_next_cob(w); if (cob != NULL) { res = ccn_put(w->h, cob->buf, cob->length); if (res >= 0) { if (w->seqnum == 0) { w->cob0 = cob; cob = NULL; } w->buffer->length = 0; w->seqnum++; w->interests_possibly_pending = 0; } ccn_charbuf_destroy(&cob); } } return(ans); }
struct ccn_charbuf* CcnbOR_read(CcnbOR self) { if (NBS_error(self->nbs)) { self->error = true; return NULL; } uint8_t* buf = (uint8_t*)malloc(2048); size_t readSize = NBS_read(self->nbs, buf, 2048, NULL); if (readSize == 0) { free(buf); return NULL; } ssize_t consumeSize = ccn_skeleton_decode(self->rd, buf, readSize); if (self->rd->state < 0) self->error = true; else ccn_charbuf_append(self->cbuf, buf, consumeSize); if (consumeSize < readSize) NBS_pushback(self->nbs, buf, consumeSize, readSize - consumeSize, NULL); else free(buf); if (CCN_FINAL_DSTATE(self->rd->state)) { struct ccn_charbuf* cbuf = self->cbuf; self->cbuf = ccn_charbuf_create(); CcnbOR_clear(self); return cbuf; } return NULL; }
/** * Parses a ccnb-encoded element expected to contain a UDATA string. * @param d is the decoder * @param dtag is the expected dtag value * @param store - on success, the string value is appended to store, * with null termination. * @returns the offset into the store buffer of the copied value, or -1 for error. * If a parse error occurs, d->decoder.state is set to a negative value. * If the element is not present, -1 is returned but no parse error * is indicated. */ int ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store) { const unsigned char *p = NULL; size_t size = 0; int res; if (ccn_buf_match_dtag(d, dtag)) { ccn_buf_advance(d); if (d->decoder.state >= 0 && CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) { res = store->length; p = d->buf + d->decoder.index; size = d->decoder.numval; ccn_buf_advance(d); } ccn_buf_check_close(d); if (d->decoder.state >= 0) { // XXX - should check for valid utf-8 data. res = store->length; if (size > 0) ccn_charbuf_append(store, p, size); ccn_charbuf_append_value(store, 0, 1); return(res); } } return(-1); }
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; }
/** * Append AnswerOriginKind=1 to partially constructed Interest, meaning * do not generate new content. */ static void answer_passive(struct ccn_charbuf *templ) { ccn_charbuf_append_tt(templ, CCN_DTAG_AnswerOriginKind, CCN_DTAG); ccn_charbuf_append_tt(templ, 1, CCN_UDATA); ccn_charbuf_append(templ, "1", 1); ccn_charbuf_append_closer(templ); /* </AnswerOriginKind> */ }
int ccn_charbuf_append_closer(struct ccn_charbuf *c) { int res; const unsigned char closer = CCN_CLOSE; res = ccn_charbuf_append(c, &closer, 1); return(res); }
// replace_name() // Helper function to replace names in content objects // Could build another version that works on already parsed content objects // But as seen below it would be better to use a modified encoding call that // didn't include the name at all. // int replace_name(struct ccn_charbuf* dest, unsigned char* src, size_t src_size, struct ccn_charbuf* name) { struct ccn_parsed_ContentObject* pco = (struct ccn_parsed_ContentObject*) calloc(sizeof(struct ccn_parsed_ContentObject), 1); int res = 0; res = ccn_parse_ContentObject(src,src_size, pco, NULL); if (res < 0) { free(pco); return (res); } ccn_charbuf_append_tt(dest, CCN_DTAG_ContentObject, CCN_DTAG); ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_Signature]], pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]); ccn_charbuf_append_charbuf(dest, name); // Already tagged ccn_charbuf_append(dest, &src[pco->offset[CCN_PCO_B_SignedInfo]], pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]); ccnb_append_tagged_blob(dest, CCN_DTAG_Content, NULL, 0); ccn_charbuf_append_closer(dest); free(pco); return (0); }
int ccn_dhcp_content_parse(const unsigned char *p, size_t size, struct ccn_dhcp_entry *tail) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); int i; int count; struct ccn_dhcp_entry *de = tail; if (ccn_buf_match_dtag(d, CCN_DTAG_Entry)) { ccn_buf_advance(d); count = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_Count); for (i = 0; i < count; i ++) { struct ccn_charbuf *store = ccn_charbuf_create(); size_t start; size_t end; int host_off = -1; int port_off = -1; de->next = calloc(1, sizeof(*de)); de = de->next; memset(de, 0, sizeof(*de)); de->store = store; de->next = NULL; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { de->name_prefix = ccn_charbuf_create(); start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(de->name_prefix, p + start, end - start); } else de->name_prefix = NULL; host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store); port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store); char *b = (char *)store->buf; char *h = b + host_off; char *p = b + port_off; if (host_off >= 0) memcpy((void *)de->address, h, strlen(h)); if (port_off >= 0) memcpy((void *)de->port, p, strlen(p)); } } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_dhcp_content_destroy(tail->next); return count; }
struct ccn_charbuf* SockAddr_hashkey(SockAddr self) { if (self->hashkey == NULL) self->hashkey = ccn_charbuf_create(); else ccn_charbuf_reset(self->hashkey); switch (self->addr->sa_family) { case AF_INET6: { struct sockaddr_in6* sin6 = (struct sockaddr_in6*)self->addr; ccn_charbuf_append(self->hashkey, &(sin6->sin6_addr), sizeof(struct in6_addr)); ccn_charbuf_append(self->hashkey, &(sin6->sin6_port), sizeof(in_port_t)); } break; case AF_PACKET: { struct sockaddr_ll* sll = (struct sockaddr_ll*)self->addr; ccn_charbuf_append(self->hashkey, &(sll->sll_addr), sll->sll_halen); } break; default: ccn_charbuf_append(self->hashkey, self->addr, self->addrlen); break; } return self->hashkey; }
static void append_future_vcomp(struct ccn_charbuf *templ) { /* One beyond a distant future version stamp */ unsigned char b[7] = {CCN_MARKER_VERSION + 1, 0, 0, 0, 0, 0, 0}; ccn_charbuf_append_tt(templ, CCN_DTAG_Component, CCN_DTAG); ccn_charbuf_append_tt(templ, sizeof(b), CCN_BLOB); ccn_charbuf_append(templ, b, sizeof(b)); ccn_charbuf_append_closer(templ); /* </Component> */ }
/* * This appends a tagged, valid, fully-saturated Bloom filter, useful for * excluding everything between two 'fenceposts' in an Exclude construct. */ static void append_bf_all(struct ccn_charbuf *c) { unsigned char bf_all[9] = { 3, 1, 'A', 0, 0, 0, 0, 0, 0xFF }; const struct ccn_bloom_wire *b = ccn_bloom_validate_wire(bf_all, sizeof(bf_all)); if (b == NULL) abort(); ccn_charbuf_append_tt(c, CCN_DTAG_Bloom, CCN_DTAG); ccn_charbuf_append_tt(c, sizeof(bf_all), CCN_BLOB); ccn_charbuf_append(c, bf_all, sizeof(bf_all)); ccn_charbuf_append_closer(c); }
int ccn_uri_append(struct ccn_charbuf *c, const unsigned char *ccnb, size_t size, int includescheme) { int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) ccn_buf_advance_past_element(d); } if (!ccn_buf_match_dtag(d, CCN_DTAG_Name)) return(-1); if (includescheme) ccn_charbuf_append_string(c, "ccnx:"); ccn_buf_advance(d); while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); compsize = 0; if (ccn_buf_match_blob(d, &comp, &compsize)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); ncomp += 1; ccn_charbuf_append(c, "/", 1); ccn_uri_append_percentescaped(c, comp, compsize); } ccn_buf_check_close(d); if (d->decoder.state < 0) return (d->decoder.state); if (ncomp == 0) ccn_charbuf_append(c, "/", 1); return(ncomp); }
/** * Create a seqwriter for writing data to a versioned, segmented stream. * * @param name is a ccnb-encoded Name. It will be provided with a version * based on the current time unless it already ends in a version * component. */ struct ccn_seqwriter * ccn_seqw_create(struct ccn *h, struct ccn_charbuf *name) { struct ccn_seqwriter *w = NULL; struct ccn_charbuf *nb = NULL; struct ccn_charbuf *nv = NULL; int res; w = calloc(1, sizeof(*w)); if (w == NULL) return(NULL); nb = ccn_charbuf_create(); ccn_charbuf_append(nb, name->buf, name->length); nv = ccn_charbuf_create(); ccn_charbuf_append(nv, name->buf, name->length); res = ccn_create_version(h, nv, CCN_V_NOW, 0, 0); if (res < 0 || nb == NULL) { ccn_charbuf_destroy(&nv); ccn_charbuf_destroy(&nb); free(w); return(NULL); } w->cl.p = &seqw_incoming_interest; w->cl.data = w; w->nb = nb; w->nv = nv; w->buffer = ccn_charbuf_create(); w->h = h; w->seqnum = 0; w->interests_possibly_pending = 1; res = ccn_set_interest_filter(h, nb, &(w->cl)); if (res < 0) { ccn_charbuf_destroy(&w->nb); ccn_charbuf_destroy(&w->nv); ccn_charbuf_destroy(&w->buffer); free(w); return(NULL); } return(w); }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending out the data messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsink *me = (Gstccnxsink *) data; struct ccn_charbuf *filtName; struct ccn_charbuf *temp; int res = 0; GST_DEBUG ("CCNxSink event: *** event thread starting"); temp = ccn_charbuf_create (); filtName = ccn_charbuf_create (); /* A closure is what defines what to do when an inbound interest arrives */ if ((me->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("closure alloc failed")); return; } /* We setup the closure to contain the sink element context reference, and also tell it what function to call */ me->ccn_closure->data = me; me->ccn_closure->p = new_interests; me->timeouts = 0; ccn_charbuf_append (filtName, me->name->buf, me->name->length); /* This call will set up a handler for interests we expect to get from clients */ // hDump(DUMP_ADDR(filtName->buf), DUMP_SIZE(filtName->length)); ccn_set_interest_filter (me->ccn, filtName, me->ccn_closure); GST_DEBUG ("CCNxSink event: interest filter registered\n"); /* Some debugging information */ temp->length = 0; ccn_uri_append (temp, me->name->buf, me->name->length, TRUE); GST_DEBUG ("CCNxSink event: using uri: %s\n", ccn_charbuf_as_string (temp)); /* Now that the interest is registered, we loop around waiting for something to do */ /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* and then we check our fifo queue for work to do. That's about it! */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { GST_DEBUG ("CCNxSink event: *** looping"); res = ccn_run (me->ccn, 50); check_fifo (me); if (res < 0 && ccn_get_connection_fd (me->ccn) == -1) { GST_DEBUG ("CCNxSink event: need to reconnect..."); /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (me->ccn, ccndHost ()); } } GST_DEBUG ("CCNxSink event: *** event thread ending"); }
static void init_all_chars_mixed_encoded(void) { struct ccn_charbuf *c; int i; c = ccn_charbuf_create(); ccn_charbuf_append(c, "=", 1); for (i = 0; i < 256; i+=2) { ccn_charbuf_putf(c, "%02x%02X", i, i+1); } if (c->length >= sizeof(all_chars_mixed_encoded)) c->length = sizeof(all_chars_mixed_encoded) - 1; memcpy(all_chars_mixed_encoded, c->buf, c->length); ccn_charbuf_destroy(&c); }
static int ccn_encode_Signature(struct ccn_charbuf *buf, const char *digest_algorithm, const void *witness, size_t witness_size, const struct ccn_signature *signature, size_t signature_size) { int res = 0; if (signature == NULL) return(-1); res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Signature, CCN_DTAG); if (digest_algorithm != NULL) { res |= ccn_charbuf_append_tt(buf, CCN_DTAG_DigestAlgorithm, CCN_DTAG); res |= ccn_charbuf_append_tt(buf, strlen(digest_algorithm), CCN_UDATA); res |= ccn_charbuf_append_string(buf, digest_algorithm); res |= ccn_charbuf_append_closer(buf); } if (witness != NULL) { res |= ccn_charbuf_append_tt(buf, CCN_DTAG_Witness, CCN_DTAG); res |= ccn_charbuf_append_tt(buf, witness_size, CCN_BLOB); res |= ccn_charbuf_append(buf, witness, witness_size); res |= ccn_charbuf_append_closer(buf); } res |= ccn_charbuf_append_tt(buf, CCN_DTAG_SignatureBits, CCN_DTAG); res |= ccn_charbuf_append_tt(buf, signature_size, CCN_BLOB); res |= ccn_charbuf_append(buf, signature, signature_size); res |= ccn_charbuf_append_closer(buf); res |= ccn_charbuf_append_closer(buf); return(res == 0 ? 0 : -1); }
static PyObject * Name_obj_from_ccn_parsed(PyObject *py_content_object) { struct ccn_charbuf *content_object; struct ccn_parsed_ContentObject *parsed_content_object; PyObject *py_ccn_name; PyObject *py_Name; struct ccn_charbuf *name; size_t name_begin, name_end, s; int r; assert(CCNObject_IsValid(CONTENT_OBJECT, py_content_object)); content_object = CCNObject_Get(CONTENT_OBJECT, py_content_object); parsed_content_object = _pyccn_content_object_get_pco(py_content_object); if (!parsed_content_object) return NULL; name_begin = parsed_content_object->offset[CCN_PCO_B_Name]; name_end = parsed_content_object->offset[CCN_PCO_E_Name]; s = name_end - name_begin; debug("ContentObject_from_ccn_parsed Name len=%zd\n", s); if (parsed_content_object->name_ncomps <= 0) { PyErr_SetString(g_PyExc_CCNNameError, "No name stored (or name is" " invalid) in parsed content object"); return NULL; } py_ccn_name = CCNObject_New_charbuf(NAME, &name); if (!py_ccn_name) return NULL; r = ccn_charbuf_append(name, &content_object->buf[name_begin], s); if (r < 0) { Py_DECREF(py_ccn_name); return PyErr_NoMemory(); } #if DEBUG_MSG debug("Name: "); dump_charbuf(name, stderr); debug("\n"); #endif py_Name = Name_obj_from_ccn(py_ccn_name); Py_DECREF(py_ccn_name); return py_Name; }
int NdnMediaProcess::checkInterest() { int res = 0; QHash<QString,UserDataBuf *>::iterator it; ruMutex->lock(); for ( it = qhRemoteUser.begin(); it != qhRemoteUser.end(); ++it ) { if (!it.value()->interested) { /* Use a template to express our order preference for the first packet. */ struct ccn_charbuf *templ = ccn_charbuf_create(); struct ccn_charbuf *path = 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); ccn_charbuf_append_tt(templ, CCN_DTAG_ChildSelector, CCN_DTAG); ccn_charbuf_append_tt(templ, 1, CCN_UDATA); ccn_charbuf_append(templ, "1", 1); /* low bit 1: rightmost */ ccn_charbuf_append_closer(templ); /*<ChildSelector>*/ ccn_charbuf_append_closer(templ); ccn_name_from_uri(path, it.key().toLocal8Bit().constData()); ccn_name_append_str(path, "audio"); if (res >= 0) { if (it.value()->data_buf.callback->p == NULL) {fprintf(stderr, "data_buf.callback is NULL!\n"); exit(1); } /* int c = 0; while (pthread_mutex_trylock(&ccn_mutex) != 0) { c++; if (c > 10000000) { fprintf(stderr, "cannot obtain lock! %s:%d\n", __FILE__, __LINE__); std::exit(1); } } */ pthread_mutex_lock(&ccn_mutex); res = ccn_express_interest(ndnState.ccn, path, it.value()->data_buf.callback, templ); pthread_mutex_unlock(&ccn_mutex); it.value()->interested = 1; fprintf(stderr, "short interest sent\n"); } if (res < 0) { fprintf(stderr, "sending the first interest failed\n"); exit(1); } ccn_charbuf_destroy(&path); ccn_charbuf_destroy(&templ); } } ruMutex->unlock(); return res; }
Name ParsedContentObject::keyName() const { if (m_pco.offset[CCN_PCO_E_KeyName_Name] > m_pco.offset[CCN_PCO_B_KeyName_Name]) { CharbufPtr ptr = boost::make_shared<Charbuf>(); ccn_charbuf_append(ptr->getBuf(), head(m_bytes) + m_pco.offset[CCN_PCO_B_KeyName_Name], m_pco.offset[CCN_PCO_E_KeyName_Name] - m_pco.offset[CCN_PCO_B_KeyName_Name]); return Name(*ptr); } else { return Name(); } }
/** * Append a tagged BLOB * * This is a ccnb-encoded element with containing the BLOB as content * @param c is the buffer to append to. * @param dtag is the element's dtab * @param data points to the binary data * @param size is the size of the data, in bytes * @returns 0 for success or -1 for error. */ int ccnb_append_tagged_blob(struct ccn_charbuf *c, enum ccn_dtag dtag, const void *data, size_t size) { int res; res = ccn_charbuf_append_tt(c, dtag, CCN_DTAG); if (size != 0) { res |= ccn_charbuf_append_tt(c, size, CCN_BLOB); res |= ccn_charbuf_append(c, data, size); } res |= ccn_charbuf_append_closer(c); return(res == 0 ? 0 : -1); }
/** * Append a ccnb start marker * * This forms the basic building block of ccnb-encoded data. * @param c is the buffer to append to. * @param val is the numval, intepreted according to tt (see enum ccn_tt). * @param tt is the type field. * @returns 0 for success or -1 for error. */ int ccn_charbuf_append_tt(struct ccn_charbuf *c, size_t val, enum ccn_tt tt) { unsigned char buf[1+8*((sizeof(val)+6)/7)]; unsigned char *p = &(buf[sizeof(buf)-1]); int n = 1; p[0] = (CCN_TT_HBIT & ~CCN_CLOSE) | ((val & CCN_MAX_TINY) << CCN_TT_BITS) | (CCN_TT_MASK & tt); val >>= (7-CCN_TT_BITS); while (val != 0) { (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CCN_CLOSE; n++; val >>= 7; } return(ccn_charbuf_append(c, p, n)); }