static void run_client(int max_cnt) { printf("client (pid=%" PRIkernel_pid "): start\n", thread_getpid()); handle = ndn_app_create(); if (handle == NULL) { printf("client (pid=%" PRIkernel_pid "): cannot create app handle\n", thread_getpid()); return; } max_count = max_cnt; count = 0; begin = xtimer_now_usec(); if (send_interest() == NDN_APP_ERROR) { printf("client (pid=%" PRIkernel_pid "): cannot send interest" " (%"PRIu32")\n", handle->id, count); ndn_app_destroy(handle); return; } ndn_app_run(handle); ndn_app_destroy(handle); }
static int on_data(ndn_block_t* interest, ndn_block_t* data) { (void)interest; (void)data; /* ndn_block_t name; int r = ndn_data_get_name(data, &name); assert(r == 0); printf("client (pid=%" PRIkernel_pid "): data received, name=", handle->id); ndn_name_print(&name); putchar('\n'); ndn_block_t content; r = ndn_data_get_content(data, &content); assert(r == 0); assert(content.len == 6); printf("client (pid=%" PRIkernel_pid "): content=%02X%02X%02X%02X\n", handle->id, *(content.buf + 2), *(content.buf + 3), *(content.buf + 4), *(content.buf + 5)); r = ndn_data_verify_signature(data, ecc_key_pub, sizeof(ecc_key_pub)); if (r != 0) printf("client (pid=%" PRIkernel_pid "): fail to verify signature\n", handle->id); else printf("client (pid=%" PRIkernel_pid "): signature valid\n", handle->id); */ if (++count != max_count) { if (send_interest() == NDN_APP_ERROR) { printf("client (pid=%" PRIkernel_pid "): cannot send interest" " (%"PRIu32")\n", handle->id, count); ndn_app_destroy(handle); return NDN_APP_ERROR; } } else { uint32_t end = xtimer_now_usec(); printf("client (pid=%"PRIkernel_pid"): total time = %"PRIu32 ", average = %"PRIu32"\n", handle->id, end - begin, (end-begin) / max_count); return NDN_APP_STOP; } return NDN_APP_CONTINUE; }
/** * This implements the default strategy. */ void ccnd_default_strategy_impl(struct ccnd_handle *h, struct strategy_instance *instance, struct ccn_strategy *strategy, enum ccn_strategy_op op, unsigned faceid) { struct pit_face_item *x = NULL; struct pit_face_item *p = NULL; struct strategy_state *npe = NULL; struct strategy_state *parent = NULL; struct nameprefix_state *sst[2] = {NULL}; struct strategy_state dummy = { MINE, CCN_NOFACEID, CCN_NOFACEID, 50000 }; unsigned best = CCN_NOFACEID; unsigned randlow, randrange; unsigned nleft; unsigned amt; int usec; if (strategy != NULL) { /* We will want access to the state for our prefix and its parent */ strategy_getstate(h, strategy, sst, 2); /* First get or initialize the parent nameprefix state */ if (sst[1] == NULL) parent = &dummy; else if (sst[1]->s[0] == CCN_UNINIT) { parent = (struct strategy_state *)sst[1]->s; *parent = dummy; } else if ((sst[1]->s[0] & CCN_MAGIC_MASK) == MINE) parent = (struct strategy_state *)sst[1]->s; /* Now get the state for the longer prefix */ npe = (struct strategy_state *)sst[0]->s; /* This one should not be NULL */ if ((npe->magic & CCN_AGED) != 0) { if ((npe->magic & CCN_MAGIC_MASK) != MINE) *npe = *parent; else npe->magic = MINE; } if (npe->magic != MINE) npe = &dummy; /* do not walk on somebody else's state */ } switch (op) { case CCNST_NOP: break; case CCNST_FIRST: best = npe->src; if (best == CCN_NOFACEID) best = npe->src = npe->osrc; /* Find our downstream; right now there should be just one. */ for (x = strategy->pfl; x != NULL; x = x->next) if ((x->pfi_flags & CCND_PFI_DNSTREAM) != 0) break; if (x == NULL || (x->pfi_flags & CCND_PFI_PENDING) == 0) return; if (best == CCN_NOFACEID) { randlow = 4000; randrange = 75000; } else { randlow = npe->usec; if (randlow < 2000) randlow = 100 + ccnd_random(h) % 4096U; randrange = (randlow + 1) / 2; } nleft = 0; for (p = strategy->pfl; p!= NULL; p = p->next) { if ((p->pfi_flags & CCND_PFI_UPSTREAM) != 0) { if (p->faceid == best) { /* we may have already sent in case of TAP */ if ((p->pfi_flags & CCND_PFI_UPENDING) == 0) p = send_interest(h, strategy->ie, x, p); strategy_settimer(h, strategy->ie, npe->usec, CCNST_TIMER); } else if ((p->pfi_flags & CCND_PFI_UPENDING) != 0) /* TAP interest has already been sent */; else if (p->faceid == npe->osrc) pfi_set_expiry_from_micros(h, strategy->ie, p, randlow); else { /* Want to preserve the order of the rest */ nleft++; p->pfi_flags |= CCND_PFI_SENDUPST; } } } if (nleft > 0) { /* Send remainder in order, with randomized timing */ amt = (2 * randrange + nleft - 1) / nleft; if (amt == 0) amt = 1; /* paranoia - should never happen */ usec = randlow; for (p = strategy->pfl; p!= NULL; p = p->next) { if ((p->pfi_flags & CCND_PFI_SENDUPST) != 0) { pfi_set_expiry_from_micros(h, strategy->ie, p, usec); usec += ccnd_random(h) % amt; } } } break; case CCNST_UPDATE: /* Just go ahead and send as prompted */ for (p = strategy->pfl; p!= NULL; p = p->next) { if ((p->pfi_flags & CCND_PFI_ATTENTION) != 0) { p->pfi_flags &= ~CCND_PFI_ATTENTION; p->pfi_flags |= CCND_PFI_SENDUPST; } } break; case CCNST_TIMER: /* * Our best choice has not responded in time. * Increase the predicted response. */ adjust_predicted_response(h, npe, CCN_NOFACEID); adjust_predicted_response(h, parent, CCN_NOFACEID); break; case CCNST_SATISFIED: /* Keep a little history about where matching content comes from. */ adjust_predicted_response(h, npe, faceid); adjust_predicted_response(h, parent, faceid); break; case CCNST_TIMEOUT: /* Interest has not been satisfied or refreshed */ break; case CCNST_INIT: break; /* No strategy private data needed */ case CCNST_EXPUP: break; case CCNST_EXPDN: break; case CCNST_REFRESH: break; case CCNST_FINALIZE: break; /* Nothing to clean up */ } }