encodedecodetest.c

Go to the documentation of this file.
00001 /**
00002  * @file encodedecodetest.c
00003  * Unit tests for CCNx C library.
00004  *
00005  * A CCNx program.
00006  *
00007  * Copyright (C) 2009-2011 Palo Alto Research Center, Inc.
00008  *
00009  * This work is free software; you can redistribute it and/or modify it under
00010  * the terms of the GNU General Public License version 2 as published by the
00011  * Free Software Foundation.
00012  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00013  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00015  * for more details. You should have received a copy of the GNU General Public
00016  * License along with this program; if not, write to the
00017  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020  
00021 #include <fcntl.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 
00029 #include <ccn/ccn.h>
00030 #include <ccn/bloom.h>
00031 #include <ccn/uri.h>
00032 #include <ccn/digest.h>
00033 #include <ccn/keystore.h>
00034 #include <ccn/signing.h>
00035 #include <ccn/random.h>
00036 
00037 struct path {
00038     int count;
00039     char * comps[];
00040 };
00041 struct path * path_create(char * strpath) {
00042     char * p = strpath;
00043     int slash_count = 0;
00044     int i = 0;
00045     struct path * path;
00046 
00047     if (strlen(strpath) < 1) {
00048         return NULL;
00049     }
00050     while (*p != '\0') {
00051         if (*p++ == '/') slash_count++;
00052     }
00053     path = malloc(sizeof(int) + sizeof(char *)*(slash_count+1));
00054     path->comps[0] = strtok(strdup(strpath), "/");
00055     path->count = 0;
00056     while (path->comps[i++]) {
00057         path->comps[i] = strtok(NULL, "/");
00058         path->count++;
00059     }
00060     return path;
00061 }
00062 void path_destroy(struct path **path) {
00063     free(*path);
00064     *path = NULL;
00065 }
00066 
00067 int 
00068 encode_message(struct ccn_charbuf *message, struct path * name_path,
00069                char *data, size_t len, struct ccn_charbuf *signed_info,
00070                const void *pkey, const char *digest_algorithm) {
00071     struct ccn_charbuf *path = ccn_charbuf_create();
00072     int i;
00073     int res;
00074 
00075     if (path == NULL || ccn_name_init(path) == -1) {
00076         fprintf(stderr, "Failed to allocate or initialize content path\n");
00077         return -1;
00078     }
00079 
00080     for (i = 0; i < name_path->count; i++) {
00081         ccn_name_append_str(path, name_path->comps[i]);
00082     }
00083 
00084     res = ccn_encode_ContentObject(message, path, signed_info, data, len, digest_algorithm, pkey);
00085 
00086     if (res != 0) {
00087         fprintf(stderr, "Failed to encode ContentObject\n");
00088     }
00089 
00090     ccn_charbuf_destroy(&path);
00091     return (res);
00092 }
00093 
00094 int 
00095 decode_message(struct ccn_charbuf *message, struct path * name_path, char *data, size_t len,
00096                const void *verkey) {
00097     struct ccn_parsed_ContentObject content;
00098     struct ccn_indexbuf *comps = ccn_indexbuf_create();
00099     const unsigned char * content_value;
00100     size_t content_length;
00101     
00102     int res = 0;
00103     int i;
00104     
00105     memset(&content, 0x33, sizeof(content));
00106 
00107     if (ccn_parse_ContentObject(message->buf, message->length, &content, comps) != 0) {
00108         printf("Decode failed to parse object\n");
00109         res = -1;
00110     }
00111 
00112     if (comps->n-1 != name_path->count) {
00113         printf("Decode got wrong number of path components: %d vs. %d\n", 
00114                (int)(comps->n-1), name_path->count);
00115         res = -1;
00116     }
00117     for (i=0; i<name_path->count; i++) {
00118         if (ccn_name_comp_strcmp(message->buf, comps, i, name_path->comps[i]) != 0) {
00119             printf("Decode mismatch on path component %d\n", i);
00120             res = -1;
00121         }
00122     }
00123     if (ccn_content_get_value(message->buf, message->length, &content,
00124                               &content_value, &content_length) != 0) {
00125         printf("Cannot retrieve content value\n");
00126         res = -1;
00127     } else if (content_length != len) {
00128         printf("Decode mismatch on content length %d vs. %d\n", 
00129                (int)content_length, (int)len);
00130         res = -1;
00131     } else if (memcmp(content_value, data, len) != 0) {
00132         printf("Decode mismatch of content\n");
00133         res = -1;
00134     }
00135 
00136     if (ccn_verify_signature(message->buf, message->length, &content, verkey) != 1) {
00137         printf("Signature did not verify\n");
00138         res = -1;
00139     }
00140 
00141     ccn_indexbuf_destroy(&comps);
00142     return res;
00143     
00144 }
00145 
00146 int
00147 expected_res(int res, char code)
00148 {
00149     if (code == '*')
00150         return(1);
00151     if (code == '-')
00152         return(res < 0);
00153     if (code == '+')
00154         return(res > 0);
00155     if ('0' <= code && code <= '9')
00156         return(res == (code - '0'));
00157     abort(); // test program bug!!!
00158     /* NOTREACHED */
00159 }
00160 
00161 static char all_chars_percent_encoded[256 * 3 + 1]; /* Computed */
00162 
00163 static void init_all_chars_percent_encoded(void) {
00164     struct ccn_charbuf *c;
00165     int i;
00166     c = ccn_charbuf_create();
00167     for (i = 0; i < 256; i+=2) {
00168         ccn_charbuf_putf(c, "%%%02x%%%02X", i, i+1);
00169     }
00170     if (c->length >= sizeof(all_chars_percent_encoded))
00171         c->length = sizeof(all_chars_percent_encoded) - 1;
00172     memcpy(all_chars_percent_encoded, c->buf, c->length);
00173     ccn_charbuf_destroy(&c);
00174 }
00175 
00176 static const char *all_chars_percent_encoded_canon =
00177  "ccnx:/"
00178  "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F"
00179  "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F"
00180  "%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F"
00181  "0123456789%3A%3B%3C%3D%3E%3F"
00182  "%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_"
00183  "%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F"
00184  "%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F"
00185  "%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F"
00186  "%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF"
00187  "%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF"
00188  "%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF"
00189  "%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF"
00190  "%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF"
00191  "%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
00192 
00193 int
00194 main (int argc, char *argv[]) {
00195     struct ccn_charbuf *buffer = ccn_charbuf_create();
00196     struct ccn_charbuf *signed_info = ccn_charbuf_create();
00197     struct ccn_skeleton_decoder dd = {0};
00198     ssize_t res;
00199     char *outname = NULL;
00200     int fd;
00201     int result = 0;
00202     char * contents[] = {"INVITE sip:foo@parc.com SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:jthornto@13.2.117.52>;tag=2105643453\nTo: Test User <sip:foo@parc.com>\nCall-ID: 119424355@127.0.0.1\nCSeq: 20 INVITE\nContact: <sip:jthornto@127.0.0.1:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length:   448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", 
00203  
00204                          "Quaer #%2d zjduer  badone",
00205                          "",
00206                          NULL};
00207     char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/119424355@127.0.0.1/id", 
00208                        "/d/e/f",
00209                        "/zero/length/content",
00210                        NULL};
00211     struct path * cur_path = NULL;
00212     struct ccn_keystore *keystore = ccn_keystore_create();
00213     char *home = getenv("HOME");
00214     char *keystore_suffix = "/.ccnx/.ccnx_keystore";
00215     char *keystore_name = NULL;
00216 
00217     int i;
00218 
00219     while ((i = getopt(argc, argv, "k:o:")) != -1) {
00220         switch (i) {
00221             case 'k':
00222                 keystore_name = optarg;
00223                 break;
00224             case 'o':
00225                 outname = optarg;
00226                 break;
00227             default:
00228                 printf("Usage: %s [-k <keystore>] [-o <outfilename>]\n", argv[0]);
00229                 exit(1);
00230         }
00231     }
00232     
00233 
00234     if (keystore_name == NULL && home == NULL) {
00235         printf("Unable to determine home directory for keystore\n");
00236         exit(1);
00237     }
00238     if (keystore_name == NULL) {
00239         keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1);
00240         strcat(keystore_name, home);
00241         strcat(keystore_name, keystore_suffix);
00242     }
00243 
00244     if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) {
00245         printf("Failed to initialize keystore\n");
00246         exit(1);
00247     }
00248 
00249     printf("Creating signed_info\n");
00250     res = ccn_signed_info_create(signed_info,
00251                                  /*pubkeyid*/ccn_keystore_public_key_digest(keystore),
00252                                  /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore),
00253                                  /*datetime*/NULL,
00254                                  /*type*/CCN_CONTENT_GONE,
00255                                  /*freshness*/ 42,
00256                                  /*finalblockid*/NULL,
00257                                  /*keylocator*/NULL);
00258     if (res < 0) {
00259         printf("Failed to create signed_info!\n");
00260     }
00261     
00262     res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length);
00263     if (!(res == signed_info->length && dd.state == 0)) {
00264         printf("Failed to decode signed_info!  Result %d State %d\n", (int)res, dd.state);
00265         result = 1;
00266     }
00267     memset(&dd, 0, sizeof(dd));
00268     printf("Done with signed_info\n");
00269 
00270     printf("Encoding sample message data length %d\n", (int)strlen(contents[0]));
00271     cur_path = path_create(paths[0]);
00272     if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info,
00273                        ccn_keystore_private_key(keystore), ccn_keystore_digest_algorithm(keystore))) {
00274         printf("Failed to encode message!\n");
00275     } else {
00276         printf("Encoded sample message length is %d\n", (int)buffer->length);
00277 
00278         res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length);
00279         if (!(res == buffer->length && dd.state == 0)) {
00280             printf("Failed to decode!  Result %d State %d\n", (int)res, dd.state);
00281             result = 1;
00282         }
00283         if (outname != NULL) {
00284             fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
00285             if (fd == -1)
00286                 perror(outname);
00287             res = write(fd, buffer->buf, buffer->length);
00288             close(fd);
00289         }
00290         if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) {
00291             result = 1;
00292         }
00293         printf("Expect signature verification failure: ");
00294         if (buffer->length >= 20)
00295             buffer->buf[buffer->length - 20] += 1;
00296         if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) {
00297             result = 1;
00298         }
00299     }
00300     path_destroy(&cur_path);
00301     ccn_charbuf_destroy(&buffer);
00302     printf("Done with sample message\n");
00303     
00304     /* Now exercise as unit tests */
00305     
00306     for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) {
00307         printf("Unit test case %d\n", i);
00308         cur_path = path_create(paths[i]);
00309         buffer = ccn_charbuf_create();
00310         if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info,
00311                        ccn_keystore_private_key(keystore), ccn_keystore_digest_algorithm(keystore))) {
00312             printf("Failed encode\n");
00313             result = 1;
00314         } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) {
00315             printf("Failed decode\n");
00316             result = 1;
00317         }
00318         path_destroy(&cur_path);
00319         ccn_charbuf_destroy(&buffer);
00320     }
00321     
00322     /* Test the uri encode / decode routines */
00323         
00324     init_all_chars_percent_encoded();
00325     const char *uri_tests[] = {
00326         "_+4", "ccnx:/this/is/a/test",       "",     "ccnx:/this/is/a/test",
00327         ".+4", "../test2?x=2",              "?x=2", "ccnx:/this/is/a/test2",
00328         "_-X", "../should/error",           "",     "",
00329         "_+2", "/missing/scheme",           "",     "ccnx:/missing/scheme",
00330         ".+0", "../../../../../././#/",     "#/",   "ccnx:/",
00331         ".+1", all_chars_percent_encoded,   "",     all_chars_percent_encoded_canon,
00332         "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon,
00333         ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....",
00334         "_-X", "/%3G?bad-pecent-encode",    "",     "",
00335         "_-X", "/%3?bad-percent-encode",    "",     "",
00336         "_-X", "/%#bad-percent-encode",    "",     "",
00337         "_+3", "ccnx://joe@example.com:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri",
00338         NULL, NULL, NULL, NULL
00339     };
00340     const char **u;
00341     struct ccn_charbuf *uri_out = ccn_charbuf_create();
00342     buffer = ccn_charbuf_create();
00343     for (u = uri_tests; *u != NULL; u += 4, i++) {
00344         printf("Unit test case %d\n", i);
00345         if (u[0][0] != '.')
00346             buffer->length = 0;
00347         res = ccn_name_from_uri(buffer, u[1]);
00348         if (!expected_res(res, u[0][1])) {
00349             printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res);
00350             result = 1;
00351         }
00352         if (res >= 0) {
00353             if (res > strlen(u[1])) {
00354                 printf("Failed: ccn_name_from_uri long res %d\n", (int)res);
00355                 result = 1;
00356             }
00357             else if (0 != strcmp(u[1] + res, u[2])) {
00358                 printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res);
00359                 result = 1;
00360             }
00361             uri_out->length = 0;
00362             res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
00363             if (!expected_res(res, u[0][2])) {
00364                 printf("Failed: ccn_uri_append wrong res %d\n", (int)res);
00365                 result = 1;
00366             }
00367             if (res >= 0) {
00368                 if (uri_out->length != strlen(u[3])) {
00369                     printf("Failed: ccn_uri_append produced wrong number of characters\n");
00370                     result = 1;
00371                 }
00372                 ccn_charbuf_reserve(uri_out, 1)[0] = 0;
00373                 if (0 != strcmp((const char *)uri_out->buf, u[3])) {
00374                     printf("Failed: ccn_uri_append produced wrong output\n");
00375                     printf("Expected: %s\n", u[3]);
00376                     printf("  Actual: %s\n", (const char *)uri_out->buf);
00377                     result = 1;
00378                 }
00379             }
00380         }
00381     }
00382     ccn_charbuf_destroy(&buffer);
00383     ccn_charbuf_destroy(&uri_out);
00384     printf("Name marker tests\n");
00385     do {
00386         const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81";
00387         const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE";
00388         const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF";
00389         const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00";
00390 
00391         printf("Unit test case %d\n", i++);
00392         buffer = ccn_charbuf_create();
00393         uri_out = ccn_charbuf_create();
00394         res = ccn_name_init(buffer);
00395         res |= ccn_name_append_str(buffer, "example.com");
00396         res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0);
00397         res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1);
00398         res |= ccn_name_append_numeric(buffer, 0xFE, 0);
00399         res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL);
00400         res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL);
00401         res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129);
00402         res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
00403         if (res < 0) {
00404             printf("Failed: name marker tests had negative res\n");
00405             result = 1;
00406         }
00407         if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) {
00408             printf("Failed: name marker tests produced wrong output\n");
00409             printf("Expected: %s\n", expected_uri);
00410             printf("  Actual: %s\n", (const char *)uri_out->buf);
00411             result = 1;
00412         }
00413         res = ccn_name_chop(buffer, NULL, 100);
00414         if (res != -1) {
00415             printf("Failed: ccn_name_chop did not produce error \n");
00416             result = 1;
00417         }
00418         res = ccn_name_chop(buffer, NULL, 4);
00419         if (res != 4) {
00420             printf("Failed: ccn_name_chop got wrong length\n");
00421             result = 1;
00422         }
00423         uri_out->length = 0;
00424         ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
00425         if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) {
00426             printf("Failed: ccn_name_chop botch\n");
00427             printf("Expected: %s\n", expected_chopped_uri);
00428             printf("  Actual: %s\n", (const char *)uri_out->buf);
00429             result = 1;
00430         }
00431         res = ccn_name_next_sibling(buffer);
00432         if (res != 4) {
00433             printf("Failed: ccn_name_next_sibling got wrong length\n");
00434             result = 1;
00435         }
00436         uri_out->length = 0;
00437         ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
00438         if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) {
00439             printf("Failed: ccn_name_next_sibling botch\n");
00440             printf("Expected: %s\n", expected_bumped_uri);
00441             printf("  Actual: %s\n", (const char *)uri_out->buf);
00442             result = 1;
00443         }
00444         ccn_name_next_sibling(buffer);
00445         uri_out->length = 0;
00446         ccn_uri_append(uri_out, buffer->buf, buffer->length, 1);
00447         if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) {
00448             printf("Failed: ccn_name_next_sibling botch\n");
00449             printf("Expected: %s\n", expected_bumped2_uri);
00450             printf("  Actual: %s\n", (const char *)uri_out->buf);
00451             result = 1;
00452         }
00453         ccn_charbuf_destroy(&buffer);
00454         ccn_charbuf_destroy(&uri_out);
00455     } while (0);
00456     printf("Message digest tests\n");
00457     do {
00458         printf("Unit test case %d\n", i++);
00459         struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256);
00460         if (dg == NULL) {
00461             printf("Failed: ccn_digest_create returned NULL\n");
00462             result = 1;
00463             break;
00464         }
00465         printf("Unit test case %d\n", i++);
00466         const unsigned char expected_digest[] = {
00467             0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0
00468         };
00469         unsigned char actual_digest[sizeof(expected_digest)] = {0};
00470         const char *data = "Content-centric";
00471         if (ccn_digest_size(dg) != sizeof(expected_digest)) {
00472             printf("Failed: wrong digest size\n");
00473             result = 1;
00474             break;
00475         }
00476         printf("Unit test case %d\n", i++);
00477         ccn_digest_init(dg);
00478         res = ccn_digest_update(dg, data, strlen(data));
00479         if (res != 0)
00480             printf("Warning: check res %d\n", (int)res);
00481         printf("Unit test case %d\n", i++);
00482         res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest));
00483         if (res != 0)
00484             printf("Warning: check res %d\n", (int)res);
00485         if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) {
00486             printf("Failed: wrong digest\n");
00487             result = 1;
00488             break;
00489         }
00490     } while (0);
00491     printf("Really basic PRNG test\n");
00492     do {
00493         unsigned char r1[42];
00494         unsigned char r2[42];
00495         printf("Unit test case %d\n", i++);
00496         ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */
00497         ccn_random_bytes(r1, sizeof(r1));
00498         memcpy(r2, r1, sizeof(r2));
00499         ccn_random_bytes(r2, sizeof(r2));
00500         if (0 == memcmp(r1, r2, sizeof(r2))) {
00501             printf("Failed: badly broken PRNG\n");
00502             result = 1;
00503             break;
00504         }
00505     } while (0);
00506     printf("Bloom filter tests\n");
00507     do {
00508         unsigned char seed1[4] = "1492";
00509         const char *a[13] = {
00510             "one", "two", "three", "four",
00511             "five", "six", "seven", "eight",
00512             "nine", "ten", "eleven", "twelve",
00513             "thirteen"
00514         };
00515         struct ccn_bloom *b1 = NULL;
00516         struct ccn_bloom *b2 = NULL;
00517         int j, k, t1, t2;
00518         unsigned short us;
00519         
00520         printf("Unit test case %d\n", i++);
00521         b1 = ccn_bloom_create(13, seed1);
00522         
00523         for (j = 0; j < 13; j++)
00524             if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
00525         if (j < 13) {
00526             printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]);
00527             result = 1;
00528             break;
00529         }
00530         printf("Unit test case %d\n", i++);
00531         for (j = 0; j < 13; j++)
00532             ccn_bloom_insert(b1, a[j], strlen(a[j]));
00533         for (j = 0; j < 13; j++)
00534             if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break;
00535         if (j < 13) {
00536             printf("Failed: \"%s\" not found when it should have been\n", a[j]);
00537             result = 1;
00538             break;
00539         }
00540         printf("Unit test case %d\n", i++);
00541         for (j = 0, k = 0; j < 13; j++)
00542             if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1)))
00543                 k++;
00544         if (k > 0) {
00545             printf("Mmm, found %d false positives\n", k);
00546             if (k > 2) {
00547                 result = 1;
00548                 break;
00549             }
00550         }
00551         unsigned char seed2[5] = "aqfb\0";
00552         for (; seed2[3] <= 'f'; seed2[3]++) {
00553             printf("Unit test case %d (%4s)    ", i++, seed2);
00554             b2 = ccn_bloom_create(13, seed2);
00555             for (j = 0; j < 13; j++)
00556                 ccn_bloom_insert(b2, a[j], strlen(a[j]));
00557             for (j = 0, k = 0, us = ~0; us > 0; us--) {
00558                 t1 = ccn_bloom_match(b1, &us, sizeof(us));
00559                 t2 = ccn_bloom_match(b2, &us, sizeof(us));
00560                 j += (t1 | t2);
00561                 k += (t1 & t2);
00562             }
00563             printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1));
00564             if (k > 12) {
00565                 printf("Failed: Bloom seeding may not be effective\n");
00566                 result = 1;
00567             }
00568             ccn_bloom_destroy(&b2);
00569         }
00570         ccn_bloom_destroy(&b1);
00571     } while (0);
00572     printf("ccn_sign_content() tests\n");
00573     do {
00574         struct ccn *h = ccn_create();
00575         struct ccn_charbuf *co = ccn_charbuf_create();
00576         struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT;
00577         struct ccn_parsed_ContentObject pco = {0};
00578         struct ccn_charbuf *name = ccn_charbuf_create();
00579         
00580         printf("Unit test case %d\n", i++);
00581         ccn_name_from_uri(name, "ccnx:/test/data/%00%42");
00582         res = ccn_sign_content(h, co, name, NULL, "DATA", 4);
00583         if (res != 0) {
00584             printf("Failed: res == %d\n", (int)res);
00585             result = 1;
00586         }
00587         sparm.template_ccnb = ccn_charbuf_create();
00588         res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL);
00589         if (res != 0) {
00590             printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res);
00591             result = 1;
00592             break;
00593         }
00594         ccn_charbuf_append(sparm.template_ccnb,
00595             co->buf + pco.offset[CCN_PCO_B_SignedInfo],
00596             pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]);
00597         sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP;
00598         printf("Unit test case %d\n", i++);
00599         res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
00600         if (res != 0) {
00601             printf("Failed: res == %d\n", (int)res);
00602             result = 1;
00603         }
00604         printf("Unit test case %d\n", i++);
00605         sparm.sp_flags = -1;
00606         res = ccn_sign_content(h, co, name, &sparm, "DATA", 4);
00607         if (res != -1) {
00608             printf("Failed: res == %d\n", (int)res);
00609             result = 1;
00610         }
00611         ccn_charbuf_destroy(&name);
00612         ccn_charbuf_destroy(&sparm.template_ccnb);
00613         ccn_charbuf_destroy(&co);
00614         ccn_destroy(&h);
00615     } while (0);
00616     printf("link tests\n");
00617     do {
00618         struct ccn_charbuf *l = ccn_charbuf_create();
00619         struct ccn_charbuf *name = ccn_charbuf_create();
00620         struct ccn_parsed_Link pl = {0};
00621         struct ccn_buf_decoder decoder;
00622         struct ccn_buf_decoder *d;
00623         struct ccn_indexbuf *comps = ccn_indexbuf_create();
00624         printf("Unit test case %d\n", i++);
00625         ccn_name_from_uri(name, "ccnx:/test/link/name");
00626         ccnb_append_Link(l, name, "label", NULL);
00627         d = ccn_buf_decoder_start(&decoder, l->buf, l->length);
00628         res = ccn_parse_Link(d, &pl, comps);
00629         if (res != 3 /* components in name */) {
00630             printf("Failed: ccn_parse_Link res == %d\n", (int)res);
00631             result = 1;
00632         }        
00633     } while (0);
00634     
00635     exit(result);
00636 }
Generated on Tue Aug 21 14:54:18 2012 for Content-Centric Networking in C by  doxygen 1.6.3