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