00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <errno.h>
00025 #include <stdint.h>
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <sys/errno.h>
00030 #include <sys/stat.h>
00031 #include <sys/types.h>
00032 #include <unistd.h>
00033 #include <ccn/ccn.h>
00034 #include <ccn/charbuf.h>
00035 #include <ccn/ccn_private.h>
00036 #include <ccn/keystore.h>
00037 #include <ccn/schedule.h>
00038 #include <ccn/sockaddrutil.h>
00039 #include <ccn/uri.h>
00040 #include "ccnd_private.h"
00041
00042 #if 0
00043 #define GOT_HERE ccnd_msg(ccnd, "at ccnd_internal_client.c:%d", __LINE__);
00044 #else
00045 #define GOT_HERE
00046 #endif
00047 #define CCND_NOTICE_NAME "notice.txt"
00048
00049 #ifndef CCND_TEST_100137
00050 #define CCND_TEST_100137 0
00051 #endif
00052
00053 #ifndef CCND_PING
00054
00055 #define CCND_PING 1
00056 #endif
00057
00058 static void ccnd_start_notice(struct ccnd_handle *ccnd);
00059
00060 static struct ccn_charbuf *
00061 ccnd_init_service_ccnb(struct ccnd_handle *ccnd, const char *baseuri, int freshness)
00062 {
00063 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
00064 struct ccn *h = ccnd->internal_client;
00065 struct ccn_charbuf *name = ccn_charbuf_create();
00066 struct ccn_charbuf *pubid = ccn_charbuf_create();
00067 struct ccn_charbuf *pubkey = ccn_charbuf_create();
00068 struct ccn_charbuf *keyid = ccn_charbuf_create();
00069 struct ccn_charbuf *cob = ccn_charbuf_create();
00070 int res;
00071
00072 res = ccn_get_public_key(h, NULL, pubid, pubkey);
00073 if (res < 0) abort();
00074 ccn_name_from_uri(name, baseuri);
00075 ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1);
00076 ccn_charbuf_append_string(keyid, ".M.K");
00077 ccn_charbuf_append_value(keyid, 0, 1);
00078 ccn_charbuf_append_charbuf(keyid, pubid);
00079 ccn_name_append(name, keyid->buf, keyid->length);
00080 ccn_create_version(h, name, 0, ccnd->starttime, ccnd->starttime_usec * 1000);
00081 sp.template_ccnb = ccn_charbuf_create();
00082 ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG);
00083 ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG);
00084 ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG);
00085 ccn_charbuf_append_charbuf(sp.template_ccnb, name);
00086 ccn_charbuf_append_closer(sp.template_ccnb);
00087
00088
00089
00090
00091 ccn_charbuf_append_closer(sp.template_ccnb);
00092 ccn_charbuf_append_closer(sp.template_ccnb);
00093 sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR;
00094 ccn_name_from_uri(name, "%00");
00095 sp.sp_flags |= CCN_SP_FINAL_BLOCK;
00096 sp.type = CCN_CONTENT_KEY;
00097 sp.freshness = freshness;
00098 res = ccn_sign_content(h, cob, name, &sp, pubkey->buf, pubkey->length);
00099 if (res != 0) abort();
00100 ccn_charbuf_destroy(&name);
00101 ccn_charbuf_destroy(&pubid);
00102 ccn_charbuf_destroy(&pubkey);
00103 ccn_charbuf_destroy(&keyid);
00104 ccn_charbuf_destroy(&sp.template_ccnb);
00105 return(cob);
00106 }
00107
00108
00109
00110
00111 #define MORECOMPS_MASK 0x007F
00112 #define MUST_VERIFY 0x0080
00113 #define MUST_VERIFY1 (MUST_VERIFY + 1)
00114 #define OPER_MASK 0xFF00
00115 #define OP_PING 0x0000
00116 #define OP_NEWFACE 0x0200
00117 #define OP_DESTROYFACE 0x0300
00118 #define OP_PREFIXREG 0x0400
00119 #define OP_SELFREG 0x0500
00120 #define OP_UNREG 0x0600
00121 #define OP_NOTICE 0x0700
00122 #define OP_SERVICE 0x0800
00123
00124
00125
00126 static enum ccn_upcall_res
00127 ccnd_answer_req(struct ccn_closure *selfp,
00128 enum ccn_upcall_kind kind,
00129 struct ccn_upcall_info *info)
00130 {
00131 struct ccn_charbuf *msg = NULL;
00132 struct ccn_charbuf *name = NULL;
00133 struct ccn_charbuf *keylocator = NULL;
00134 struct ccn_charbuf *signed_info = NULL;
00135 struct ccn_charbuf *reply_body = NULL;
00136 struct ccnd_handle *ccnd = NULL;
00137 int res = 0;
00138 int start = 0;
00139 int end = 0;
00140 int morecomps = 0;
00141 const unsigned char *final_comp = NULL;
00142 size_t final_size = 0;
00143 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
00144
00145 switch (kind) {
00146 case CCN_UPCALL_FINAL:
00147 free(selfp);
00148 return(CCN_UPCALL_RESULT_OK);
00149 case CCN_UPCALL_INTEREST:
00150 break;
00151 case CCN_UPCALL_CONSUMED_INTEREST:
00152 return(CCN_UPCALL_RESULT_OK);
00153 default:
00154 return(CCN_UPCALL_RESULT_ERR);
00155 }
00156 ccnd = (struct ccnd_handle *)selfp->data;
00157 if ((ccnd->debug & 128) != 0)
00158 ccnd_debug_ccnb(ccnd, __LINE__, "ccnd_answer_req", NULL,
00159 info->interest_ccnb, info->pi->offset[CCN_PI_E]);
00160 morecomps = selfp->intdata & MORECOMPS_MASK;
00161 if ((info->pi->answerfrom & CCN_AOK_NEW) == 0 &&
00162 selfp->intdata != OP_SERVICE &&
00163 selfp->intdata != OP_NOTICE)
00164 return(CCN_UPCALL_RESULT_OK);
00165 if (info->matched_comps >= info->interest_comps->n)
00166 goto Bail;
00167 if (selfp->intdata != OP_PING &&
00168 selfp->intdata != OP_NOTICE &&
00169 selfp->intdata != OP_SERVICE &&
00170 info->pi->prefix_comps != info->matched_comps + morecomps)
00171 goto Bail;
00172 if (morecomps == 1) {
00173 res = ccn_name_comp_get(info->interest_ccnb, info->interest_comps,
00174 info->matched_comps,
00175 &final_comp, &final_size);
00176 if (res < 0)
00177 goto Bail;
00178 }
00179 if ((selfp->intdata & MUST_VERIFY) != 0) {
00180 struct ccn_parsed_ContentObject pco = {0};
00181
00182 res = ccn_parse_ContentObject(final_comp, final_size, &pco, NULL);
00183 if (res < 0) {
00184 ccnd_debug_ccnb(ccnd, __LINE__, "co_parse_failed", NULL,
00185 info->interest_ccnb, info->pi->offset[CCN_PI_E]);
00186 goto Bail;
00187 }
00188 res = ccn_verify_content(info->h, final_comp, &pco);
00189 if (res != 0) {
00190 ccnd_debug_ccnb(ccnd, __LINE__, "co_verify_failed", NULL,
00191 info->interest_ccnb, info->pi->offset[CCN_PI_E]);
00192 goto Bail;
00193 }
00194 }
00195 sp.freshness = 10;
00196 switch (selfp->intdata & OPER_MASK) {
00197 case OP_PING:
00198 reply_body = ccn_charbuf_create();
00199 sp.freshness = (info->pi->prefix_comps == info->matched_comps) ? 60 : 5;
00200 res = 0;
00201 break;
00202 case OP_NEWFACE:
00203 reply_body = ccn_charbuf_create();
00204 res = ccnd_req_newface(ccnd, final_comp, final_size, reply_body);
00205 break;
00206 case OP_DESTROYFACE:
00207 reply_body = ccn_charbuf_create();
00208 res = ccnd_req_destroyface(ccnd, final_comp, final_size, reply_body);
00209 break;
00210 case OP_PREFIXREG:
00211 reply_body = ccn_charbuf_create();
00212 res = ccnd_req_prefixreg(ccnd, final_comp, final_size, reply_body);
00213 break;
00214 case OP_SELFREG:
00215 reply_body = ccn_charbuf_create();
00216 res = ccnd_req_selfreg(ccnd, final_comp, final_size, reply_body);
00217 break;
00218 case OP_UNREG:
00219 reply_body = ccn_charbuf_create();
00220 res = ccnd_req_unreg(ccnd, final_comp, final_size, reply_body);
00221 break;
00222 case OP_NOTICE:
00223 ccnd_start_notice(ccnd);
00224 goto Bail;
00225 break;
00226 case OP_SERVICE:
00227 if (ccnd->service_ccnb == NULL)
00228 ccnd->service_ccnb = ccnd_init_service_ccnb(ccnd, CCNDID_LOCAL_URI, 600);
00229 if (ccn_content_matches_interest(
00230 ccnd->service_ccnb->buf,
00231 ccnd->service_ccnb->length,
00232 1,
00233 NULL,
00234 info->interest_ccnb,
00235 info->pi->offset[CCN_PI_E],
00236 info->pi
00237 )) {
00238 ccn_put(info->h, ccnd->service_ccnb->buf,
00239 ccnd->service_ccnb->length);
00240 res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
00241 goto Finish;
00242 }
00243
00244 if (ccnd->neighbor_ccnb == NULL)
00245 ccnd->neighbor_ccnb = ccnd_init_service_ccnb(ccnd, CCNDID_NEIGHBOR_URI, 5);
00246 if (ccn_content_matches_interest(
00247 ccnd->neighbor_ccnb->buf,
00248 ccnd->neighbor_ccnb->length,
00249 1,
00250 NULL,
00251 info->interest_ccnb,
00252 info->pi->offset[CCN_PI_E],
00253 info->pi
00254 )) {
00255 ccn_put(info->h, ccnd->neighbor_ccnb->buf,
00256 ccnd->neighbor_ccnb->length);
00257 res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
00258 goto Finish;
00259 }
00260 goto Bail;
00261 break;
00262 default:
00263 goto Bail;
00264 }
00265 if (res < 0)
00266 goto Bail;
00267 if (res == CCN_CONTENT_NACK)
00268 sp.type = res;
00269 msg = ccn_charbuf_create();
00270 name = ccn_charbuf_create();
00271 start = info->pi->offset[CCN_PI_B_Name];
00272 end = info->interest_comps->buf[info->pi->prefix_comps];
00273 ccn_charbuf_append(name, info->interest_ccnb + start, end - start);
00274 ccn_charbuf_append_closer(name);
00275 res = ccn_sign_content(info->h, msg, name, &sp,
00276 reply_body->buf, reply_body->length);
00277 if (res < 0)
00278 goto Bail;
00279 if ((ccnd->debug & 128) != 0)
00280 ccnd_debug_ccnb(ccnd, __LINE__, "ccnd_answer_req_response", NULL,
00281 msg->buf, msg->length);
00282 res = ccn_put(info->h, msg->buf, msg->length);
00283 if (res < 0)
00284 goto Bail;
00285 if (CCND_TEST_100137)
00286 ccn_put(info->h, msg->buf, msg->length);
00287 res = CCN_UPCALL_RESULT_INTEREST_CONSUMED;
00288 goto Finish;
00289 Bail:
00290 res = CCN_UPCALL_RESULT_ERR;
00291 Finish:
00292 ccn_charbuf_destroy(&msg);
00293 ccn_charbuf_destroy(&name);
00294 ccn_charbuf_destroy(&keylocator);
00295 ccn_charbuf_destroy(&reply_body);
00296 ccn_charbuf_destroy(&signed_info);
00297 return(res);
00298 }
00299
00300 static int
00301 ccnd_internal_client_refresh(struct ccn_schedule *sched,
00302 void *clienth,
00303 struct ccn_scheduled_event *ev,
00304 int flags)
00305 {
00306 struct ccnd_handle *ccnd = clienth;
00307 int microsec = 0;
00308 if ((flags & CCN_SCHEDULE_CANCEL) == 0 &&
00309 ccnd->internal_client != NULL &&
00310 ccnd->internal_client_refresh == ev) {
00311 microsec = ccn_process_scheduled_operations(ccnd->internal_client);
00312 if (microsec > ev->evint)
00313 microsec = ev->evint;
00314 }
00315 if (microsec <= 0 && ccnd->internal_client_refresh == ev)
00316 ccnd->internal_client_refresh = NULL;
00317 return(microsec);
00318 }
00319
00320 #define CCND_ID_TEMPL "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
00321
00322 static void
00323 ccnd_uri_listen(struct ccnd_handle *ccnd, const char *uri,
00324 ccn_handler p, intptr_t intdata)
00325 {
00326 struct ccn_charbuf *name;
00327 struct ccn_charbuf *uri_modified = NULL;
00328 struct ccn_closure *closure;
00329 struct ccn_indexbuf *comps;
00330 const unsigned char *comp;
00331 size_t comp_size;
00332 size_t offset;
00333 int reg_wanted = 1;
00334
00335 name = ccn_charbuf_create();
00336 ccn_name_from_uri(name, uri);
00337 comps = ccn_indexbuf_create();
00338 if (ccn_name_split(name, comps) < 0)
00339 abort();
00340 if (ccn_name_comp_get(name->buf, comps, 1, &comp, &comp_size) >= 0) {
00341 if (comp_size == 32 && 0 == memcmp(comp, CCND_ID_TEMPL, 32)) {
00342
00343 offset = comp - name->buf;
00344 memcpy(name->buf + offset, ccnd->ccnd_id, 32);
00345 uri_modified = ccn_charbuf_create();
00346 ccn_uri_append(uri_modified, name->buf, name->length, 1);
00347 uri = (char *)uri_modified->buf;
00348 reg_wanted = 0;
00349 }
00350 }
00351 closure = calloc(1, sizeof(*closure));
00352 closure->p = p;
00353 closure->data = ccnd;
00354 closure->intdata = intdata;
00355
00356 if (reg_wanted)
00357 ccnd_reg_uri(ccnd, uri,
00358 0,
00359 CCN_FORW_CHILD_INHERIT | CCN_FORW_ACTIVE,
00360 0x7FFFFFFF);
00361 ccn_set_interest_filter(ccnd->internal_client, name, closure);
00362 ccn_charbuf_destroy(&name);
00363 ccn_charbuf_destroy(&uri_modified);
00364 ccn_indexbuf_destroy(&comps);
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 static void
00374 ccnd_reg_ccnx_ccndid(struct ccnd_handle *ccnd)
00375 {
00376 struct ccn_charbuf *name;
00377 struct ccn_charbuf *uri;
00378
00379 name = ccn_charbuf_create();
00380 ccn_name_from_uri(name, "ccnx:/ccnx");
00381 ccn_name_append(name, ccnd->ccnd_id, 32);
00382 uri = ccn_charbuf_create();
00383 ccn_uri_append(uri, name->buf, name->length, 1);
00384 ccnd_reg_uri(ccnd, ccn_charbuf_as_string(uri),
00385 0,
00386 (CCN_FORW_CHILD_INHERIT |
00387 CCN_FORW_ACTIVE |
00388 CCN_FORW_CAPTURE |
00389 CCN_FORW_ADVERTISE ),
00390 0x7FFFFFFF);
00391 ccn_charbuf_destroy(&name);
00392 ccn_charbuf_destroy(&uri);
00393 }
00394
00395 #ifndef CCN_PATH_VAR_TMP
00396 #define CCN_PATH_VAR_TMP "/var/tmp"
00397 #endif
00398
00399
00400
00401
00402
00403
00404 #ifndef CCND_KEYSTORE_PASS
00405 #define CCND_KEYSTORE_PASS "\010\043\103\375\327\237\152\351\155"
00406 #endif
00407
00408 int
00409 ccnd_init_internal_keystore(struct ccnd_handle *ccnd)
00410 {
00411 struct ccn_charbuf *temp = NULL;
00412 struct ccn_charbuf *cmd = NULL;
00413 struct ccn_charbuf *culprit = NULL;
00414 struct stat statbuf;
00415 const char *dir = NULL;
00416 int res = -1;
00417 char *keystore_path = NULL;
00418 struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT;
00419
00420 if (ccnd->internal_client == NULL)
00421 return(-1);
00422 temp = ccn_charbuf_create();
00423 cmd = ccn_charbuf_create();
00424 dir = getenv("CCND_KEYSTORE_DIRECTORY");
00425 if (dir != NULL && dir[0] == '/')
00426 ccn_charbuf_putf(temp, "%s/", dir);
00427 else
00428 ccn_charbuf_putf(temp, CCN_PATH_VAR_TMP "/.ccnx-user%d/", (int)geteuid());
00429 res = stat(ccn_charbuf_as_string(temp), &statbuf);
00430 if (res == -1) {
00431 if (errno == ENOENT)
00432 res = mkdir(ccn_charbuf_as_string(temp), 0700);
00433 if (res != 0) {
00434 culprit = temp;
00435 goto Finish;
00436 }
00437 }
00438 ccn_charbuf_putf(temp, ".ccnd_keystore_%s", ccnd->portstr);
00439 keystore_path = strdup(ccn_charbuf_as_string(temp));
00440 res = stat(keystore_path, &statbuf);
00441 if (res == 0)
00442 res = ccn_load_default_key(ccnd->internal_client, keystore_path, CCND_KEYSTORE_PASS);
00443 if (res >= 0)
00444 goto Finish;
00445
00446 res = ccn_keystore_file_init(keystore_path, CCND_KEYSTORE_PASS, "CCND-internal", 0, 0);
00447 if (res != 0) {
00448 culprit = temp;
00449 goto Finish;
00450 }
00451 res = ccn_load_default_key(ccnd->internal_client, keystore_path, CCND_KEYSTORE_PASS);
00452 if (res != 0)
00453 culprit = temp;
00454 Finish:
00455 if (culprit != NULL) {
00456 ccnd_msg(ccnd, "%s: %s:\n", ccn_charbuf_as_string(culprit), strerror(errno));
00457 culprit = NULL;
00458 }
00459 res = ccn_chk_signing_params(ccnd->internal_client, NULL, &sp, NULL, NULL, NULL);
00460 if (res != 0)
00461 abort();
00462 memcpy(ccnd->ccnd_id, sp.pubid, sizeof(ccnd->ccnd_id));
00463 ccn_charbuf_destroy(&temp);
00464 ccn_charbuf_destroy(&cmd);
00465 if (keystore_path != NULL)
00466 free(keystore_path);
00467 return(res);
00468 }
00469
00470 static int
00471 post_face_notice(struct ccnd_handle *ccnd, unsigned faceid)
00472 {
00473 struct face *face = ccnd_face_from_faceid(ccnd, faceid);
00474 struct ccn_charbuf *msg = ccn_charbuf_create();
00475 int res = -1;
00476 int port;
00477
00478
00479 if (face == NULL)
00480 ccn_charbuf_putf(msg, "destroyface(%u);\n", faceid);
00481 else {
00482 ccn_charbuf_putf(msg, "newface(%u, 0x%x", faceid, face->flags);
00483 if (face->addr != NULL &&
00484 (face->flags & (CCN_FACE_INET | CCN_FACE_INET6)) != 0) {
00485 ccn_charbuf_putf(msg, ", ");
00486 port = ccn_charbuf_append_sockaddr(msg, face->addr);
00487 if (port < 0)
00488 msg->length--;
00489 else if (port > 0)
00490 ccn_charbuf_putf(msg, ":%d", port);
00491 }
00492 ccn_charbuf_putf(msg, ");\n", faceid);
00493 }
00494 res = ccn_seqw_write(ccnd->notice, msg->buf, msg->length);
00495 ccn_charbuf_destroy(&msg);
00496 return(res);
00497 }
00498
00499 static int
00500 ccnd_notice_push(struct ccn_schedule *sched,
00501 void *clienth,
00502 struct ccn_scheduled_event *ev,
00503 int flags)
00504 {
00505 struct ccnd_handle *ccnd = clienth;
00506 struct ccn_indexbuf *chface = NULL;
00507 int i = 0;
00508 int j = 0;
00509 int microsec = 0;
00510 int res = 0;
00511
00512 if ((flags & CCN_SCHEDULE_CANCEL) == 0 &&
00513 ccnd->notice != NULL &&
00514 ccnd->notice_push == ev &&
00515 ccnd->chface != NULL) {
00516 chface = ccnd->chface;
00517 ccn_seqw_batch_start(ccnd->notice);
00518 for (i = 0; i < chface->n && res != -1; i++)
00519 res = post_face_notice(ccnd, chface->buf[i]);
00520 ccn_seqw_batch_end(ccnd->notice);
00521 for (j = 0; i < chface->n; i++, j++)
00522 chface->buf[j] = chface->buf[i];
00523 chface->n = j;
00524 if (res == -1)
00525 microsec = 3000;
00526 }
00527 if (microsec <= 0)
00528 ccnd->notice_push = NULL;
00529 return(microsec);
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539 void
00540 ccnd_face_status_change(struct ccnd_handle *ccnd, unsigned faceid)
00541 {
00542 struct ccn_indexbuf *chface = ccnd->chface;
00543 if (chface != NULL) {
00544 ccn_indexbuf_set_insert(chface, faceid);
00545 if (ccnd->notice_push == NULL)
00546 ccnd->notice_push = ccn_schedule_event(ccnd->sched, 2000,
00547 ccnd_notice_push,
00548 NULL, 0);
00549 }
00550 }
00551
00552 static void
00553 ccnd_start_notice(struct ccnd_handle *ccnd)
00554 {
00555 struct ccn *h = ccnd->internal_client;
00556 struct ccn_charbuf *name = NULL;
00557 struct face *face = NULL;
00558 int i;
00559
00560 if (h == NULL)
00561 return;
00562 if (ccnd->notice != NULL)
00563 return;
00564 if (ccnd->chface != NULL) {
00565
00566 ccnd_msg(ccnd, "ccnd_internal_client.c:%d Huh?", __LINE__);
00567 ccn_indexbuf_destroy(&ccnd->chface);
00568 }
00569 name = ccn_charbuf_create();
00570 ccn_name_from_uri(name, "ccnx:/ccnx");
00571 ccn_name_append(name, ccnd->ccnd_id, 32);
00572 ccn_name_append_str(name, CCND_NOTICE_NAME);
00573 ccnd->notice = ccn_seqw_create(h, name);
00574 ccnd->chface = ccn_indexbuf_create();
00575 for (i = 0; i < ccnd->face_limit; i++) {
00576 face = ccnd->faces_by_faceid[i];
00577 if (face != NULL)
00578 ccn_indexbuf_set_insert(ccnd->chface, face->faceid);
00579 }
00580 if (ccnd->chface->n > 0)
00581 ccnd_face_status_change(ccnd, ccnd->chface->buf[0]);
00582 ccn_charbuf_destroy(&name);
00583 }
00584
00585 int
00586 ccnd_internal_client_start(struct ccnd_handle *ccnd)
00587 {
00588 struct ccn *h;
00589 if (ccnd->internal_client != NULL)
00590 return(-1);
00591 if (ccnd->face0 == NULL)
00592 abort();
00593 ccnd->internal_client = h = ccn_create();
00594 if (ccnd_init_internal_keystore(ccnd) < 0) {
00595 ccn_destroy(&ccnd->internal_client);
00596 return(-1);
00597 }
00598 #if (CCND_PING+0)
00599 ccnd_uri_listen(ccnd, "ccnx:/ccnx/ping",
00600 &ccnd_answer_req, OP_PING);
00601 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/ping",
00602 &ccnd_answer_req, OP_PING);
00603 #endif
00604 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/newface",
00605 &ccnd_answer_req, OP_NEWFACE + MUST_VERIFY1);
00606 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/destroyface",
00607 &ccnd_answer_req, OP_DESTROYFACE + MUST_VERIFY1);
00608 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/prefixreg",
00609 &ccnd_answer_req, OP_PREFIXREG + MUST_VERIFY1);
00610 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/selfreg",
00611 &ccnd_answer_req, OP_SELFREG + MUST_VERIFY1);
00612 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/unreg",
00613 &ccnd_answer_req, OP_UNREG + MUST_VERIFY1);
00614 ccnd_uri_listen(ccnd, "ccnx:/ccnx/" CCND_ID_TEMPL "/" CCND_NOTICE_NAME,
00615 &ccnd_answer_req, OP_NOTICE);
00616 ccnd_uri_listen(ccnd, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd",
00617 &ccnd_answer_req, OP_SERVICE);
00618 ccnd_uri_listen(ccnd, "ccnx:/%C1.M.S.neighborhood",
00619 &ccnd_answer_req, OP_SERVICE);
00620 ccnd_reg_ccnx_ccndid(ccnd);
00621 ccnd_reg_uri(ccnd, "ccnx:/%C1.M.S.localhost",
00622 0,
00623 (CCN_FORW_CHILD_INHERIT |
00624 CCN_FORW_ACTIVE |
00625 CCN_FORW_LOCAL ),
00626 0x7FFFFFFF);
00627 ccnd->internal_client_refresh \
00628 = ccn_schedule_event(ccnd->sched, 50000,
00629 ccnd_internal_client_refresh,
00630 NULL, CCN_INTEREST_LIFETIME_MICROSEC);
00631 return(0);
00632 }
00633
00634 void
00635 ccnd_internal_client_stop(struct ccnd_handle *ccnd)
00636 {
00637 ccnd->notice = NULL;
00638 if (ccnd->notice_push != NULL)
00639 ccn_schedule_cancel(ccnd->sched, ccnd->notice_push);
00640 ccn_indexbuf_destroy(&ccnd->chface);
00641 ccn_destroy(&ccnd->internal_client);
00642 ccn_charbuf_destroy(&ccnd->service_ccnb);
00643 ccn_charbuf_destroy(&ccnd->neighbor_ccnb);
00644 if (ccnd->internal_client_refresh != NULL)
00645 ccn_schedule_cancel(ccnd->sched, ccnd->internal_client_refresh);
00646 }