int ccnl_mgmt_crypto(struct ccnl_relay_s *ccnl, char *type, unsigned char *buf, int buflen) { struct ccnl_face_s *from; DEBUGMSG(DEBUG,"ccnl_crypto type: %s\n", type); if(!strcmp(type, "verify")){ int seqnum = 0; int verified = ccnl_crypto_extract_verify_reply(&buf, &buflen, &seqnum); unsigned char *msg, *msg2; char cmd[500]; int len = ccnl_crypto_extract_msg(&buf, &buflen, &msg), len2 = 0; struct ccnl_face_s *from; //DEBUGMSG(DEBUG,"VERIFIED: %d, MSG_LEN: %d\n", verified, len); int scope=3, aok=3, minsfx=0, maxsfx=CCNL_MAX_NAME_COMP, contlen; struct ccnl_buf_s *buf1 = 0, *nonce=0, *ppkd=0; struct ccnl_prefix_s *p = 0; struct ccnl_buf_s *msg2_buf; unsigned char *content = 0; msg2 = (char *) ccnl_malloc(sizeof(char) * len + 200); len2 = ccnl_ccnb_mkHeader(msg2,CCN_DTAG_NAME, CCN_TT_DTAG); memcpy(msg2+len2, msg, len); len2 +=len; msg2[len2++] = 0; from = ccnl->faces; while(from){ if(from->faceid == seqnum) break; from = from->next; } buf1 = ccnl_ccnb_extract(&msg2, &len2, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (p->complen[2] < sizeof(cmd)) { memcpy(cmd, p->comp[2], p->complen[2]); cmd[p->complen[2]] = '\0'; } else strcpy(cmd, "cmd-is-too-long-to-display"); msg2_buf = ccnl_buf_new((char *)msg2, len2); ccnl_mgmt_handle(ccnl, msg2_buf, p, from, cmd, verified); ccnl_free(msg2_buf); }else if(!strcmp(type, "sign")){ char *sig = (char *) ccnl_malloc(sizeof(char)* CCNL_MAX_PACKET_SIZE); unsigned char *out; unsigned char *msg; int siglen = 0, seqnum = 0, len, len1; struct ccnl_buf_s *retbuf; ccnl_crypto_extract_sign_reply(&buf, &buflen, sig, &siglen, &seqnum); len = ccnl_crypto_extract_msg(&buf, &buflen, &msg); out = (char *) ccnl_malloc(sizeof(unsigned char)*len + sizeof(unsigned char)*siglen + 4096); len1 = ccnl_ccnb_mkHeader(out, CCN_DTAG_CONTENTOBJ, CCN_TT_DTAG); // content if(siglen > 0) len1 += ccnl_crypto_add_signature(out+len1, sig, siglen); memcpy(out+len1, msg, len); len1 +=len; out[len1++] = 0; // end-of-interest from = ccnl->faces; while(from){ if(from->faceid == seqnum) break; from = from->next; } retbuf = ccnl_buf_new((char *)out, len1); if(seqnum >= 0){ ccnl_face_enqueue(ccnl, from, retbuf); }else{ struct ccnl_prefix_s *prefix_a = 0; struct ccnl_content_s *c = 0; struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0; unsigned char *content = 0; char *ht = (char *) ccnl_malloc(sizeof(char)*20); int contlen; pkt = ccnl_ccnb_extract(&out, &len1, 0, 0, 0, 0, &prefix_a, &nonce, &ppkd, &content, &contlen); if (!pkt) { DEBUGMSG(WARNING, " parsing error\n"); goto Done; } if (prefix_a) { //DEBUGMSG(DEBUG, "%s", prefix_a->comp); //ccnl_free(prefix_a); } //prefix_a = (struct ccnl_prefix_s *)ccnl_malloc(sizeof(struct ccnl_prefix_s)); prefix_a->compcnt = 2; prefix_a->comp = (unsigned char **) ccnl_malloc(sizeof(unsigned char*)*2); prefix_a->comp[0] = "mgmt"; sprintf(ht, "seqnum-%d", -seqnum); prefix_a->comp[1] = ht; prefix_a->complen = (int *) ccnl_malloc(sizeof(int)*2); prefix_a->complen[0] = strlen("mgmt"); prefix_a->complen[1] = strlen(ht); c = ccnl_content_new(ccnl, CCNL_SUITE_CCNB, &pkt, &prefix_a, &ppkd, content, contlen); if (!c) goto Done; ccnl_content_serve_pending(ccnl, c); ccnl_content_add2cache(ccnl, c); } Done: ccnl_free(out); } return 0; }
int ccnl_ccnb_forwarder(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc= -1, scope=3, aok=3, minsfx=0, maxsfx=CCNL_MAX_NAME_COMP, contlen; struct ccnl_buf_s *buf = 0, *nonce=0, *ppkd=0; struct ccnl_interest_s *i = 0; struct ccnl_content_s *c = 0; struct ccnl_prefix_s *p = 0; unsigned char *content = 0; DEBUGMSG(99, "ccnl/ccnb forwarder (%d bytes left)\n", *datalen); buf = ccnl_ccnb_extract(data, datalen, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); goto Done; } if (nonce && ccnl_nonce_find_or_append(relay, nonce)) { DEBUGMSG(6, " dropped because of duplicate nonce\n"); goto Skip; } if (buf->data[0] == 0x01 && buf->data[1] == 0xd2) { // interest DEBUGMSG(6, " interest=<%s>\n", ccnl_prefix_to_path(p)); ccnl_print_stats(relay, STAT_RCV_I); //log count recv_interest if (p->compcnt > 0 && p->comp[0][0] == (unsigned char) 0xc1) goto Skip; if (p->compcnt == 4 && !memcmp(p->comp[0], "ccnx", 4)) { rc = ccnl_mgmt(relay, buf, p, from); goto Done; } // CONFORM: Step 1: if ( aok & 0x01 ) { // honor "answer-from-existing-content-store" flag for (c = relay->contents; c; c = c->next) { if (c->suite != CCNL_SUITE_CCNB) continue; if (!ccnl_i_prefixof_c(p, minsfx, maxsfx, c)) continue; if (ppkd && !buf_equal(ppkd, c->details.ccnb.ppkd)) continue; // FIXME: should check stale bit in aok here DEBUGMSG(7, " matching content for interest, content %p\n", (void *) c); ccnl_print_stats(relay, STAT_SND_C); //log sent_c if (from->ifndx >= 0) ccnl_face_enqueue(relay, from, buf_dup(c->pkt)); else ccnl_app_RX(relay, c); goto Skip; } } // CONFORM: Step 2: check whether interest is already known for (i = relay->pit; i; i = i->next) { if (i->suite == CCNL_SUITE_CCNB && !ccnl_prefix_cmp(i->prefix, NULL, p, CMP_EXACT) && i->details.ccnb.minsuffix == minsfx && i->details.ccnb.maxsuffix == maxsfx && ((!ppkd && !i->details.ccnb.ppkd) || buf_equal(ppkd, i->details.ccnb.ppkd)) ) break; } if (!i) { // this is a new/unknown I request: create and propagate i = ccnl_interest_new(relay, from, CCNL_SUITE_CCNB, &buf, &p, minsfx, maxsfx); if (ppkd) i->details.ccnb.ppkd = ppkd, ppkd = NULL; if (i) { // CONFORM: Step 3 (and 4) DEBUGMSG(7, " created new interest entry %p\n", (void *) i); if (scope > 2) ccnl_interest_propagate(relay, i); } } else if (scope > 2 && (from->flags & CCNL_FACE_FLAGS_FWDALLI)) { DEBUGMSG(7, " old interest, nevertheless propagated %p\n", (void *) i); ccnl_interest_propagate(relay, i); } if (i) { // store the I request, for the incoming face (Step 3) DEBUGMSG(7, " appending interest entry %p\n", (void *) i); ccnl_interest_append_pending(i, from); } } else { // content DEBUGMSG(6, " content=<%s>\n", ccnl_prefix_to_path(p)); ccnl_print_stats(relay, STAT_RCV_C); //log count recv_content #ifdef USE_SIGNATURES if (p->compcnt == 2 && !memcmp(p->comp[0], "ccnx", 4) && !memcmp(p->comp[1], "crypto", 6) && from == relay->crypto_face) { rc = ccnl_crypto(relay, buf, p, from); goto Done; } #endif /*USE_SIGNATURES*/ // CONFORM: Step 1: for (c = relay->contents; c; c = c->next) if (buf_equal(c->pkt, buf)) goto Skip; // content is dup c = ccnl_content_new(relay, CCNL_SUITE_CCNB, &buf, &p, &ppkd, content, contlen); if (c) { // CONFORM: Step 2 (and 3) if (!ccnl_content_serve_pending(relay, c)) { // unsolicited content // CONFORM: "A node MUST NOT forward unsolicited data [...]" DEBUGMSG(7, " removed because no matching interest\n"); free_content(c); goto Skip; } if (relay->max_cache_entries != 0) { // it's set to -1 or a limit DEBUGMSG(7, " adding content to cache\n"); ccnl_content_add2cache(relay, c); } else { DEBUGMSG(7, " content not added to cache\n"); free_content(c); } } } Skip: rc = 0; Done: free_prefix(p); free_3ptr_list(buf, nonce, ppkd); return rc; }
int ccnl_nfn(struct ccnl_relay_s *ccnl, // struct ccnl_buf_s *orig, struct ccnl_prefix_s *prefix, struct ccnl_face_s *from, struct configuration_s *config, struct ccnl_interest_s *interest, int suite, int start_locally) { int num_of_required_thunks = 0; int thunk_request = 0; struct ccnl_buf_s *res = NULL; char str[CCNL_MAX_PACKET_SIZE]; int i, len = 0; DEBUGMSG(TRACE, "ccnl_nfn(%p, %s, %p, config=%p)\n", (void*)ccnl, ccnl_prefix_to_path(prefix), (void*)from, (void*)config); // prefix = ccnl_prefix_dup(prefix); DEBUGMSG(DEBUG, "Namecomps: %s \n", ccnl_prefix_to_path(prefix)); if (config){ suite = config->suite; thunk_request = config->fox_state->thunk_request; goto restart; //do not do parsing thunks again } from->flags = CCNL_FACE_FLAGS_STATIC; if (ccnl_nfn_thunk_already_computing(ccnl, prefix)) { DEBUGMSG(DEBUG, "Computation for this interest is already running\n"); return -1; } if (ccnl_nfnprefix_isTHUNK(prefix)) thunk_request = 1; // Checks first if the interest has a routing hint and then searches for it locally. // If it exisits, the computation is started locally, otherwise it is directly forwarded without entering the AM. // Without this mechanism, there will be situations where several nodes "overtake" a computation // applying the same strategy and, potentially, all executing it locally (after trying all arguments). // TODO: this is not an elegant solution and should be improved on, because the clients cannot send a // computation with a routing hint on which the network applies a strategy if the routable name // does not exist (because each node will just forward it without ever taking it into an abstract machine). // encoding the routing hint more explicitely as well as additonal information (e.g. already tried names) // could solve the problem. More generally speaking, additional state describing the exact situation will be required. if (interest && interest->prefix->compcnt > 1) { // forward interests with outsourced components struct ccnl_prefix_s *copy = ccnl_prefix_dup(prefix); copy->compcnt -= (1 + thunk_request); DEBUGMSG(DEBUG, " checking local available of %s\n", ccnl_prefix_to_path(copy)); ccnl_nfnprefix_clear(copy, CCNL_PREFIX_NFN | CCNL_PREFIX_THUNK); if (!ccnl_nfn_local_content_search(ccnl, NULL, copy)) { free_prefix(copy); ccnl_interest_propagate(ccnl, interest); return 0; } free_prefix(copy); start_locally = 1; } //put packet together #ifdef USE_SUITE_CCNTLV if (prefix->suite == CCNL_SUITE_CCNTLV) { len = prefix->complen[prefix->compcnt-1] - 4; memcpy(str, prefix->comp[prefix->compcnt-1] + 4, len); str[len] = '\0'; } else #endif { len = prefix->complen[prefix->compcnt-1]; memcpy(str, prefix->comp[prefix->compcnt-1], len); str[len] = '\0'; } if (prefix->compcnt > 1) len += sprintf(str + len, " "); for (i = 0; i < prefix->compcnt-1; i++) { #ifdef USE_SUITE_CCNTLV if (prefix->suite == CCNL_SUITE_CCNTLV) len += sprintf(str+len,"/%.*s",prefix->complen[i]-4,prefix->comp[i]+4); else #endif len += sprintf(str+len,"/%.*s",prefix->complen[i],prefix->comp[i]); } DEBUGMSG(DEBUG, "expr is <%s>\n", str); //search for result here... if found return... if (thunk_request) num_of_required_thunks = ccnl_nfn_count_required_thunks(str); ++ccnl->km->numOfRunningComputations; restart: res = Krivine_reduction(ccnl, str, thunk_request, start_locally, num_of_required_thunks, &config, prefix, suite); //stores result if computed if (res) { struct ccnl_prefix_s *copy; struct ccnl_content_s *c; DEBUGMSG(INFO,"Computation finished: res: %.*s size: %d bytes. Running computations: %d\n", res->datalen, res->data, res->datalen, ccnl->km->numOfRunningComputations); if (config && config->fox_state->thunk_request) { // ccnl_nfn_remove_thunk_from_prefix(config->prefix); ccnl_nfnprefix_clear(config->prefix, CCNL_PREFIX_THUNK); } copy = ccnl_prefix_dup(config->prefix); c = ccnl_nfn_result2content(ccnl, ©, res->data, res->datalen); c->flags = CCNL_CONTENT_FLAGS_STATIC; set_propagate_of_interests_to_1(ccnl, c->name); ccnl_content_serve_pending(ccnl,c); ccnl_content_add2cache(ccnl, c); --ccnl->km->numOfRunningComputations; DBL_LINKED_LIST_REMOVE(ccnl->km->configuration_list, config); ccnl_nfn_freeConfiguration(config); ccnl_free(res); } #ifdef USE_NACK else if(config->local_done){ struct ccnl_content_s *nack; nack = ccnl_nfn_result2content(ccnl, &config->prefix, (unsigned char*)":NACK", 5); ccnl_content_serve_pending(ccnl, nack); } #endif return 0; }
int ccnl_core_RX_i_or_c(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc = -1, scope = 3, aok = 3, minsfx = 0, maxsfx = CCNL_MAX_NAME_COMP, contlen; struct ccnl_buf_s *buf = 0, *nonce = 0, *ppkd = 0; struct ccnl_interest_s *i = 0; struct ccnl_content_s *c = 0; struct ccnl_prefix_s *p = 0; unsigned char *content = 0; DEBUGMSG(1, "ccnl_core_RX_i_or_c: (%d bytes left)\n", *datalen); buf = ccnl_extract_prefix_nonce_ppkd(data, datalen, &scope, &aok, &minsfx, &maxsfx, &p, &nonce, &ppkd, &content, &contlen); if (!buf) { DEBUGMSG(6, " parsing error or no prefix\n"); goto Done; } if (nonce && ccnl_nonce_find_or_append(relay, nonce)) { DEBUGMSG(6, " dropped because of duplicate nonce\n"); goto Skip; } if (buf->data[0] == 0x01 && buf->data[1] == 0xd2) { // interest DEBUGMSG(1, "ccnl_core_RX_i_or_c: interest=<%s>\n", ccnl_prefix_to_path(p)); from->stat.received_interest++; if (p->compcnt > 0 && p->comp[0][0] == (unsigned char) 0xc1) { goto Skip; } if (p->compcnt == 4 && !memcmp(p->comp[0], "ccnx", 4)) { DEBUGMSG(1, "it's a mgnt msg!\n"); rc = ccnl_mgmt(relay, buf, p, from); DEBUGMSG(1, "mgnt processing done!\n"); goto Done; } // CONFORM: Step 1: if (aok & 0x01) { // honor "answer-from-existing-content-store" flag for (c = relay->contents; c; c = c->next) { if (!ccnl_i_prefixof_c(p, ppkd, minsfx, maxsfx, c)) { continue; } // FIXME: should check stale bit in aok here DEBUGMSG(7, " matching content for interest, content %p\n", (void *) c); from->stat.send_content[c->served_cnt % CCNL_MAX_CONTENT_SERVED_STAT]++; c->served_cnt++; if (from->ifndx >= 0) { ccnl_face_enqueue(relay, from, buf_dup(c->pkt)); } goto Skip; } } // CONFORM: Step 2: check whether interest is already known for (i = relay->pit; i; i = i->next) { if (!ccnl_prefix_cmp(i->prefix, NULL, p, CMP_EXACT) && i->minsuffix == minsfx && i->maxsuffix == maxsfx && ((!ppkd && !i->ppkd) || buf_equal(ppkd, i->ppkd))) { break; } } if (!i) { // this is a new/unknown I request: create and propagate i = ccnl_interest_new(relay, from, &buf, &p, minsfx, maxsfx, &ppkd); if (i) { // CONFORM: Step 3 (and 4) DEBUGMSG(7, " created new interest entry %p\n", (void *) i); if (scope > 2) { ccnl_interest_propagate(relay, i); } } } else if (scope > 2 && (from->flags & CCNL_FACE_FLAGS_FWDALLI)) { DEBUGMSG(7, " old interest, nevertheless propagated %p\n", (void *) i); ccnl_interest_propagate(relay, i); } if (i) { // store the I request, for the incoming face (Step 3) DEBUGMSG(7, " appending interest entry %p\n", (void *) i); ccnl_interest_append_pending(i, from); } } else { // content DEBUGMSG(6, " content=<%s>\n", ccnl_prefix_to_path(p)); from->stat.received_content++; // CONFORM: Step 1: for (c = relay->contents; c; c = c->next) { if (buf_equal(c->pkt, buf)) { DEBUGMSG(1, "content is dup: skip\n"); goto Skip; } } c = ccnl_content_new(relay, &buf, &p, &ppkd, content, contlen); if (c) { // CONFORM: Step 2 (and 3) if (!ccnl_content_serve_pending(relay, c, from)) { // unsolicited content // CONFORM: "A node MUST NOT forward unsolicited data [...]" DEBUGMSG(7, " removed because no matching interest\n"); free_content(c); goto Skip; } #if CCNL_DYNAMIC_FIB else { /* content has matched an interest, we consider this name as available on this face */ ccnl_content_learn_name_route(relay, c->name, from, relay->fib_threshold_prefix, 0); } #endif if (relay->max_cache_entries != 0) { // it's set to -1 or a limit DEBUGMSG(7, " adding content to cache\n"); ccnl_content_add2cache(relay, c); } else { DEBUGMSG(7, " content not added to cache\n"); free_content(c); } } } Skip: rc = 0; Done: free_prefix(p); free_3ptr_list(buf, nonce, ppkd); DEBUGMSG(1, "leaving\n"); return rc; }