ccnr_util.c

Go to the documentation of this file.
00001 /**
00002  * @file ccnr_util.c
00003  * 
00004  * Part of ccnr -  CCNx Repository Daemon.
00005  *
00006  */
00007 
00008 /*
00009  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00010  *
00011  * This work is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the
00013  * Free Software Foundation.
00014  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00015  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00017  * for more details. You should have received a copy of the GNU General Public
00018  * License along with this program; if not, write to the
00019  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022  
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <limits.h>
00026 #include <netdb.h>
00027 #include <poll.h>
00028 #include <signal.h>
00029 #include <stddef.h>
00030 #include <stdint.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <time.h>
00035 #include <unistd.h>
00036 #include <arpa/inet.h>
00037 #include <sys/time.h>
00038 #include <sys/socket.h>
00039 #include <sys/stat.h>
00040 #include <sys/types.h>
00041 #include <sys/un.h>
00042 #include <netinet/in.h>
00043 
00044 #include <ccn/bloom.h>
00045 #include <ccn/ccn.h>
00046 #include <ccn/ccn_private.h>
00047 #include <ccn/charbuf.h>
00048 #include <ccn/face_mgmt.h>
00049 #include <ccn/hashtb.h>
00050 #include <ccn/indexbuf.h>
00051 #include <ccn/schedule.h>
00052 #include <ccn/reg_mgmt.h>
00053 #include <ccn/uri.h>
00054 
00055 #include "ccnr_private.h"
00056 
00057 #include "ccnr_util.h"
00058 
00059 PUBLIC struct ccn_charbuf *
00060 r_util_charbuf_obtain(struct ccnr_handle *h)
00061 {
00062     struct ccn_charbuf *c = h->scratch_charbuf;
00063     if (c == NULL)
00064         return(ccn_charbuf_create());
00065     h->scratch_charbuf = NULL;
00066     c->length = 0;
00067     return(c);
00068 }
00069 
00070 PUBLIC void
00071 r_util_charbuf_release(struct ccnr_handle *h, struct ccn_charbuf *c)
00072 {
00073     c->length = 0;
00074     if (h->scratch_charbuf == NULL)
00075         h->scratch_charbuf = c;
00076     else
00077         ccn_charbuf_destroy(&c);
00078 }
00079 
00080 PUBLIC struct ccn_indexbuf *
00081 r_util_indexbuf_obtain(struct ccnr_handle *h)
00082 {
00083     struct ccn_indexbuf *c = h->scratch_indexbuf;
00084     if (c == NULL)
00085         return(ccn_indexbuf_create());
00086     h->scratch_indexbuf = NULL;
00087     c->n = 0;
00088     return(c);
00089 }
00090 
00091 PUBLIC void
00092 r_util_indexbuf_release(struct ccnr_handle *h, struct ccn_indexbuf *c)
00093 {
00094     c->n = 0;
00095     if (h->scratch_indexbuf == NULL)
00096         h->scratch_indexbuf = c;
00097     else
00098         ccn_indexbuf_destroy(&c);
00099 }
00100 
00101 PUBLIC void
00102 r_util_reseed(struct ccnr_handle *h)
00103 {
00104     int fd;
00105     ssize_t res;
00106     
00107     res = -1;
00108     fd = open("/dev/urandom", O_RDONLY);
00109     if (fd != -1) {
00110         res = read(fd, h->seed, sizeof(h->seed));
00111         close(fd);
00112     }
00113     if (res != sizeof(h->seed)) {
00114         h->seed[1] = (unsigned short)getpid(); /* better than no entropy */
00115         h->seed[2] = (unsigned short)time(NULL);
00116     }
00117     /*
00118      * The call to seed48 is needed by cygwin, and should be harmless
00119      * on other platforms.
00120      */
00121     seed48(h->seed);
00122 }
00123 
00124 PUBLIC void
00125 r_util_gettime(const struct ccn_gettime *self, struct ccn_timeval *result)
00126 {
00127     struct ccnr_handle *h = self->data;
00128     struct timeval now = {0};
00129     gettimeofday(&now, 0);
00130     result->s = now.tv_sec;
00131     result->micros = now.tv_usec;
00132     h->sec = now.tv_sec;
00133     h->usec = now.tv_usec;
00134 }
00135 
00136 PUBLIC int
00137 r_util_timecmp(long secA, unsigned usecA, long secB, unsigned usecB)
00138 {
00139     if (secA < secB) return (-1);
00140     if (secA > secB) return (1);
00141     if (usecA < usecB) return (-1);
00142     if (usecA > usecB) return (1);
00143     return (0);
00144 }
00145 PUBLIC intmax_t
00146 r_util_segment_from_component(const unsigned char *ccnb, size_t start, size_t stop)
00147 {
00148     const unsigned char *data = NULL;
00149     size_t len = 0;
00150     intmax_t segment;
00151     int i;
00152     
00153     if (start < stop) {
00154         ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb, start, stop, &data, &len);
00155         if (len > 0 && data != NULL && data[0] == 0 && len <= (1 + sizeof(intmax_t))) {
00156             // parse big-endian encoded number with leading 0 byte
00157             segment = 0;
00158             for (i = 1; i < len; i++) {
00159                 segment = segment * 256 + data[i];
00160             }
00161             return(segment);
00162         }
00163     }
00164     return(-1);
00165 }
00166 /**
00167  * Compare a name component at index i to bytes in buf and return 0
00168  * if they are equal length and equal value.
00169  * In the case of inequality, a negative or positive value is returned,
00170  * according to the canonical ordering of names.
00171  */
00172 int
00173 r_util_name_comp_compare(const unsigned char *data,
00174                          const struct ccn_indexbuf *indexbuf,
00175                          unsigned int i, const void *buf, size_t length)
00176 {
00177     const unsigned char *comp_ptr;
00178     size_t comp_size;
00179     
00180     if (ccn_name_comp_get(data, indexbuf, i, &comp_ptr, &comp_size) != 0)
00181         return(-1);
00182     if (comp_size < length)
00183         return(-1);
00184     if (comp_size > length)
00185         return(1);
00186     return(memcmp(comp_ptr, buf, length));
00187 }
00188 /**
00189  * Given a ccnb encoded content object, the parsed form, and name components
00190  * report whether this is the last (FinalBlockID) segment of a stream.
00191  * This is very similar to ccn_is_final_block()
00192  */
00193 PUBLIC int
00194 r_util_is_final_pco(const unsigned char *ccnb,
00195              struct ccn_parsed_ContentObject *pco,
00196              struct ccn_indexbuf *comps)
00197 {
00198     if (ccnb == NULL || pco == NULL)
00199         return(0);
00200     if (pco->offset[CCN_PCO_B_FinalBlockID] !=
00201         pco->offset[CCN_PCO_E_FinalBlockID]) {
00202         const unsigned char *finalid = NULL;
00203         size_t finalid_size = 0;
00204         const unsigned char *nameid = NULL;
00205         size_t nameid_size = 0;
00206         ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
00207                             pco->offset[CCN_PCO_B_FinalBlockID],
00208                             pco->offset[CCN_PCO_E_FinalBlockID],
00209                             &finalid,
00210                             &finalid_size);
00211         if (comps->n < 2) return(-1);
00212         ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb,
00213                             comps->buf[comps->n - 2],
00214                             comps->buf[comps->n - 1],
00215                             &nameid,
00216                             &nameid_size);
00217         if (finalid_size == nameid_size &&
00218             0 == memcmp(finalid, nameid, nameid_size))
00219             return(1);
00220     }
00221     return(0);
00222 }
00223 

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