ccnbasicconfig.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnbasicconfig.c
00003  * Bring up a link to another ccnd.
00004  *
00005  * This is a very basic version that just registers a single prefix, possibly
00006  * creating a new face in the process.  Symbolic proto, host, and port are not
00007  * handled.  You might want to consider looking at ccndc instead.
00008  *
00009  * A CCNx command-line utility.
00010  *
00011  * Copyright (C) 2009-2010 Palo Alto Research Center, Inc.
00012  *
00013  * This work is free software; you can redistribute it and/or modify it under
00014  * the terms of the GNU General Public License version 2 as published by the
00015  * Free Software Foundation.
00016  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00017  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00019  * for more details. You should have received a copy of the GNU General Public
00020  * License along with this program; if not, write to the
00021  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00022  * Boston, MA 02110-1301, USA.
00023  */
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <unistd.h>
00028 #include <ccn/bloom.h>
00029 #include <ccn/ccn.h>
00030 #include <ccn/ccnd.h>
00031 #include <ccn/charbuf.h>
00032 #include <ccn/uri.h>
00033 #include <ccn/face_mgmt.h>
00034 #include <ccn/reg_mgmt.h>
00035 #include <ccn/sockcreate.h>
00036 #include <ccn/signing.h>
00037 #include <ccn/keystore.h>
00038 
00039 static void
00040 usage(const char *progname)
00041 {
00042     fprintf(stderr,
00043             "%s ccnx:/prefix/to/register proto host [port]\n"
00044             "   Bring up a link to another ccnd, registering a prefix\n",
00045             progname);
00046     exit(1);
00047 }
00048 
00049 #define CHKRES(resval) chkres((resval), __LINE__)
00050 
00051 static void
00052 chkres(int res, int lineno)
00053 {
00054     if (res >= 0)
00055         return;
00056     fprintf(stderr, "failure at "
00057                     "ccnbasicconfig.c"
00058                     ":%d (res = %d)\n", lineno, res);
00059     exit(1);
00060 }
00061 
00062 int
00063 main(int argc, char **argv)
00064 {
00065     struct ccn *h = NULL;
00066     struct ccn_charbuf *name = NULL;
00067     struct ccn_charbuf *null_name = NULL;
00068     struct ccn_charbuf *name_prefix = NULL;
00069     struct ccn_charbuf *newface = NULL;
00070     struct ccn_charbuf *prefixreg = NULL;
00071     struct ccn_charbuf *resultbuf = NULL;
00072     struct ccn_charbuf *temp = NULL;
00073     struct ccn_charbuf *templ = NULL;
00074     const unsigned char *ptr = NULL;
00075     size_t length = 0;
00076     const char *arg = NULL;
00077     const char *progname = NULL;
00078     struct ccn_parsed_ContentObject pcobuf = {0};
00079     struct ccn_face_instance face_instance_storage = {0};
00080     struct ccn_face_instance *face_instance = &face_instance_storage;
00081     struct ccn_forwarding_entry forwarding_entry_storage = {0};
00082     struct ccn_forwarding_entry *forwarding_entry = &forwarding_entry_storage;
00083     struct ccn_charbuf *signed_info = NULL;
00084     struct ccn_charbuf *keylocator = NULL;
00085     struct ccn_keystore *keystore = NULL;
00086     long expire = -1;
00087     unsigned char ccndid_storage[32] = {0};
00088     const unsigned char *ccndid = NULL;
00089     size_t ccndid_size = 0;
00090     int res;
00091     int opt;
00092     
00093     progname = argv[0];
00094     while ((opt = getopt(argc, argv, "h")) != -1) {
00095         switch (opt) {
00096             case 'h':
00097             default:
00098                 usage(progname);
00099         }
00100     }
00101 
00102     /* Sanity check the URI and argument count */
00103     arg = argv[optind];
00104     if (arg == NULL)
00105         usage(progname);
00106     name = ccn_charbuf_create();
00107     res = ccn_name_from_uri(name, arg);
00108     if (res < 0) {
00109         fprintf(stderr, "%s: bad ccn URI: %s\n", progname, arg);
00110         exit(1);
00111     }
00112     if (argc - optind < 3 || argc - optind > 4)
00113         usage(progname);
00114     
00115     h = ccn_create();
00116     res = ccn_connect(h, NULL);
00117     if (res < 0) {
00118         ccn_perror(h, "ccn_connect");
00119         exit(1);
00120     }
00121 
00122     newface = ccn_charbuf_create();
00123     temp = ccn_charbuf_create();
00124     templ = ccn_charbuf_create();
00125     signed_info = ccn_charbuf_create();
00126     resultbuf = ccn_charbuf_create();
00127     name_prefix = ccn_charbuf_create();
00128     null_name = ccn_charbuf_create();
00129     CHKRES(ccn_name_init(null_name));
00130 
00131     keystore = ccn_keystore_create();
00132         
00133     face_instance->action = "newface";
00134     face_instance->descr.ipproto = atoi(argv[optind + 1]); // XXX - 6 = tcp or 17 = udp
00135     face_instance->descr.address = argv[optind + 2];
00136     face_instance->descr.port = argv[optind + 3];
00137     if (face_instance->descr.port == NULL)
00138         face_instance->descr.port = CCN_DEFAULT_UNICAST_PORT;
00139     face_instance->descr.mcast_ttl = -1;
00140     face_instance->lifetime = (~0U) >> 1;
00141     
00142     CHKRES(res = ccnb_append_face_instance(newface, face_instance));
00143     temp->length = 0;
00144     CHKRES(ccn_charbuf_putf(temp, "%s/.ccnx/.ccnx_keystore", getenv("HOME")));
00145     res = ccn_keystore_init(keystore,
00146                             ccn_charbuf_as_string(temp),
00147                             "Th1s1sn0t8g00dp8ssw0rd.");
00148     CHKRES(res);
00149 
00150     /* Construct a key locator containing the key itself */
00151     keylocator = ccn_charbuf_create();
00152     ccn_charbuf_append_tt(keylocator, CCN_DTAG_KeyLocator, CCN_DTAG);
00153     ccn_charbuf_append_tt(keylocator, CCN_DTAG_Key, CCN_DTAG);
00154     CHKRES(ccn_append_pubkey_blob(keylocator, ccn_keystore_public_key(keystore)));
00155     ccn_charbuf_append_closer(keylocator);      /* </Key> */
00156     ccn_charbuf_append_closer(keylocator);      /* </KeyLocator> */
00157     res = ccn_signed_info_create(signed_info,
00158                                  /* pubkeyid */ ccn_keystore_public_key_digest(keystore),
00159                                  /* publisher_key_id_size */ ccn_keystore_public_key_digest_length(keystore),
00160                                  /* datetime */ NULL,
00161                                  /* type */ CCN_CONTENT_DATA,
00162                                  /* freshness */ expire,
00163                                  /* finalblockid */ NULL,
00164                                  keylocator);
00165     if (res < 0) {
00166         fprintf(stderr, "Failed to create signed_info (res == %d)\n", res);
00167         exit(1);
00168     }
00169     
00170     temp->length = 0;
00171     res = ccn_encode_ContentObject(temp,
00172                                    null_name,
00173                                    signed_info,
00174                                    newface->buf,
00175                                    newface->length,
00176                                    NULL,
00177                                    ccn_keystore_private_key(keystore));
00178     CHKRES(res);
00179     
00180     /* Set up our Interest template to indicate scope 1 */
00181         templ->length = 0;
00182         ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG);
00183         ccn_charbuf_append_tt(templ, CCN_DTAG_Name, CCN_DTAG);
00184         ccn_charbuf_append_closer(templ);       /* </Name> */
00185         ccnb_tagged_putf(templ, CCN_DTAG_Scope, "1");
00186         ccn_charbuf_append_closer(templ);       /* </Interest> */
00187 
00188     /* We need to figure out our local ccnd's CCIDID */
00189     name->length = 0;
00190     CHKRES(res = ccn_name_from_uri(name, "ccnx:/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY"));
00191     CHKRES(res = ccn_get(h, name, templ, 200, resultbuf, &pcobuf, NULL, 0));
00192     res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest,
00193                         resultbuf->buf,
00194                         pcobuf.offset[CCN_PCO_B_PublisherPublicKeyDigest],
00195                         pcobuf.offset[CCN_PCO_E_PublisherPublicKeyDigest],
00196                         &ccndid, &ccndid_size);
00197     CHKRES(res);
00198     if (ccndid_size > sizeof(ccndid_storage))
00199         CHKRES(-1);
00200     memcpy(ccndid_storage, ccndid, ccndid_size);
00201     ccndid = ccndid_storage;
00202     
00203     /* Create the new face */
00204     CHKRES(ccn_name_init(name));
00205     CHKRES(ccn_name_append_str(name, "ccnx"));
00206     CHKRES(ccn_name_append(name, ccndid, ccndid_size));
00207     CHKRES(ccn_name_append(name, "newface", 7));
00208     CHKRES(ccn_name_append(name, temp->buf, temp->length));
00209     res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0);
00210     if (res < 0) {
00211         fprintf(stderr, "no response from face creation request\n");
00212         exit(1);
00213     }
00214     ptr = resultbuf->buf;
00215     length = resultbuf->length;
00216     res = ccn_content_get_value(resultbuf->buf, resultbuf->length, &pcobuf, &ptr, &length);
00217     CHKRES(res);
00218     face_instance = ccn_face_instance_parse(ptr, length);
00219     if (face_instance == NULL)
00220         CHKRES(res = -1);
00221     CHKRES(face_instance->faceid);
00222     
00223     /* Finally, register the prefix */
00224     name_prefix->length = 0;
00225     CHKRES(ccn_name_from_uri(name_prefix, arg));
00226     forwarding_entry->action = "prefixreg";
00227     forwarding_entry->name_prefix = name_prefix;
00228     forwarding_entry->faceid = face_instance->faceid;
00229     forwarding_entry->lifetime = (~0U) >> 1;
00230     prefixreg = ccn_charbuf_create();
00231     CHKRES(res = ccnb_append_forwarding_entry(prefixreg, forwarding_entry));
00232     temp->length = 0;
00233     res = ccn_encode_ContentObject(temp,
00234                                    null_name,
00235                                    signed_info,
00236                                    prefixreg->buf,
00237                                    prefixreg->length,
00238                                    NULL,
00239                                    ccn_keystore_private_key(keystore));
00240     CHKRES(res);
00241     CHKRES(ccn_name_init(name));
00242     CHKRES(ccn_name_append_str(name, "ccnx"));
00243     CHKRES(ccn_name_append(name, ccndid, ccndid_size));
00244     CHKRES(ccn_name_append_str(name, "prefixreg"));
00245     CHKRES(ccn_name_append(name, temp->buf, temp->length));
00246     res = ccn_get(h, name, templ, 1000, resultbuf, &pcobuf, NULL, 0);
00247     if (res < 0) {
00248         fprintf(stderr, "no response from prefix registration request\n");
00249         exit(1);
00250     }
00251     fprintf(stderr, "Prefix %s will be forwarded to face %d\n", arg, face_instance->faceid);
00252 
00253     /* We're about to exit, so don't bother to free everything. */
00254     ccn_destroy(&h);
00255     exit(res < 0);
00256 }

Generated on Thu Feb 16 00:43:59 2012 for Content-Centric Networking in C by  doxygen 1.5.6