Ejemplo n.º 1
0
/**
 * Write a file named index/stable that contains the size of
 * repoFile1 when the repository is shut down.
 */
static int
r_store_write_stable_point(struct ccnr_handle *h)
{
    struct ccn_charbuf *path = NULL;
    struct ccn_charbuf *cb = NULL;
    int fd;
    
    path = ccn_charbuf_create();
    cb = ccn_charbuf_create();
    ccn_charbuf_putf(path, "%s/index/stable", h->directory);
    unlink(ccn_charbuf_as_string(path)); /* Should not exist, but just in case. */
    fd = open(ccn_charbuf_as_string(path),
              O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, 0666);
    if (fd == -1) {
        ccnr_msg(h, "cannot write stable mark %s: %s",
                 ccn_charbuf_as_string(path), strerror(errno));
        unlink(ccn_charbuf_as_string(path));
    }
    else {
        ccn_charbuf_putf(cb, "%ju", (uintmax_t)(h->stable));
        write(fd, cb->buf, cb->length);
        close(fd);
        if (CCNSHOULDLOG(h, dfsdf, CCNL_INFO))
            ccnr_msg(h, "Index marked stable - %s", ccn_charbuf_as_string(cb));
    }
    ccn_charbuf_destroy(&path);
    ccn_charbuf_destroy(&cb);
    return(0);
}
Ejemplo n.º 2
0
void
r_init_fail(struct ccnr_handle *ccnr, int line, const char *culprit, int err)
{
    if (err > 0)
        ccnr_msg(ccnr, "Startup failure %d %s - %s", line, culprit,
                 strerror(err));
    else {
        ccnr_msg(ccnr, "Startup failure %d %s - error %d", line, culprit, err);
    }
    ccnr->running = -1;
}
Ejemplo n.º 3
0
PUBLIC int
r_sendq_face_send_queue_insert(struct ccnr_handle *h,
                       struct fdholder *fdholder, struct content_entry *content)
{
    int ans = -1;
    int delay;
    enum cq_delay_class c;
    struct content_queue *q;
    if (fdholder == NULL || content == NULL || (fdholder->flags & CCNR_FACE_NOSEND) != 0)
        return(-1);
    c = choose_content_delay_class(h, fdholder->filedesc, r_store_content_flags(content));
    if (fdholder->q[c] == NULL)
        fdholder->q[c] = content_queue_create(h, fdholder, c);
    q = fdholder->q[c];
    if (q == NULL)
        return(-1);
    ans = ccn_indexbuf_set_insert(q->send_queue, r_store_content_cookie(h, content));
    if (q->sender == NULL) {
        delay = randomize_content_delay(h, q);
        q->ready = q->send_queue->n;
        q->sender = ccn_schedule_event(h->sched, delay,
                                       content_sender, q, fdholder->filedesc);
        if (CCNSHOULDLOG(h, LM_8, CCNL_FINER))
            ccnr_msg(h, "fdholder %u q %d delay %d usec", fdholder->filedesc, c, delay);
    }
    return (ans);
}
Ejemplo n.º 4
0
/**
 * Parses content object and sets content->flatname
 */
static int
r_store_set_flatname(struct ccnr_handle *h, struct content_entry *content,
                     struct ccn_parsed_ContentObject *pco)
{
    int res;
    struct ccn_charbuf *flatname = NULL;
    const unsigned char *msg = NULL;
    size_t size;
    
    msg = r_store_content_base(h, content);
    size = content->size;
    if (msg == NULL)
        goto Bail;
    flatname = ccn_charbuf_create();
    if (flatname == NULL)
        goto Bail;    
    res = ccn_parse_ContentObject(msg, size, pco, NULL);
    if (res < 0) {
        ccnr_msg(h, "error parsing ContentObject - code %d", res);
        goto Bail;
    }
    ccn_digest_ContentObject(msg, pco);
    if (pco->digest_bytes != 32)
        goto Bail;
    res = ccn_flatname_from_ccnb(flatname, msg, size);
    if (res < 0) goto Bail;
    res = ccn_flatname_append_component(flatname, pco->digest, pco->digest_bytes);
    if (res < 0) goto Bail;
    content->flatname = flatname;
    flatname = NULL;
    return(0);
Bail:
    ccn_charbuf_destroy(&flatname);
    return(-1);
}
Ejemplo n.º 5
0
/**
 * Get the specified numerical config value, subject to limits.
 */
intmax_t
r_init_confval(struct ccnr_handle *h, const char *key,
                     intmax_t lo, intmax_t hi, intmax_t deflt) {
    const char *s;
    intmax_t v;
    char *ep;
    
    if (!(lo <= deflt && deflt <= hi))
        abort();
    s = getenv(key);
    if (s != NULL && s[0] != 0) {
        ep = "x";
        v = strtoimax(s, &ep, 10);
        if (v != 0 || ep[0] == 0) {
            if (v > hi)
                v = hi;
            if (v < lo)
                v = lo;
            if (CCNSHOULDLOG(h, mmm, CCNL_FINEST))
                ccnr_msg(h, "Using %s=%jd", key, v);
            return(v);
        }
    }
    return (deflt);
}
Ejemplo n.º 6
0
/**
 * Make a new fdholder corresponding to the fd
 */
PUBLIC struct fdholder *
r_io_record_fd(struct ccnr_handle *h, int fd,
                  void *who, socklen_t wholen,
                  int setflags)
{
    int res;
    struct fdholder *fdholder = NULL;
    
    res = fcntl(fd, F_SETFL, O_NONBLOCK);
    if (res == -1)
        ccnr_msg(h, "fcntl: %s", strerror(errno));
    fdholder = calloc(1, sizeof(*fdholder));
    
    
    if (fdholder == NULL)
        return(fdholder);
    fdholder->name = ccn_charbuf_create();
    if (fdholder->name == NULL)
        abort();
    if (who != NULL)
        ccn_charbuf_append(fdholder->name, who, wholen);
    fdholder->filedesc = fd;
    init_face_flags(h, fdholder, setflags);
    res = r_io_enroll_face(h, fdholder);
    if (res == -1) {
        ccn_charbuf_destroy(&fdholder->name);
        free(fdholder);
        fdholder = NULL;
    }
    return(fdholder);
}
Ejemplo n.º 7
0
/**
 *  Evict recoverable content from in-memory buffers
 */
PUBLIC void
r_store_trim(struct ccnr_handle *h, unsigned long limit)
{
    struct content_entry *content = NULL;
    int checklimit;
    unsigned before;
    unsigned rover;
    unsigned mask;
    
    r_store_index_needs_cleaning(h);
    before = h->cob_count;
    if (before <= limit)
        return;
    checklimit = h->cookie_limit;
    mask = h->cookie_limit - 1;
    for (rover = (h->trim_rover & mask);
         checklimit > 0 && h->cob_count > limit;
         checklimit--, rover = (rover + 1) & mask) {
        content = h->content_by_cookie[rover];
        if (content != NULL)
            r_store_content_trim(h, content);
    }
    h->trim_rover = rover;
    if (CCNSHOULDLOG(h, sdf, CCNL_FINER))
        ccnr_msg(h, "trimmed %u cobs", before - h->cob_count);
}
Ejemplo n.º 8
0
/**
 *  Get the base address of the content object
 *
 * This may involve reading the object in.  Caller should not assume that
 * the address will stay valid after it relinquishes control, either by
 * returning or by calling routines that might invalidate objects.
 *
 */
PUBLIC const unsigned char *
r_store_content_base(struct ccnr_handle *h, struct content_entry *content)
{
    const unsigned char *ans = NULL;
    
    if (content->cob != NULL && content->cob->length == content->size) {
        ans = content->cob->buf;
        goto Finish;
    }
    if (content->accession == CCNR_NULL_ACCESSION)
        goto Finish;
    ans = r_store_content_mapped(h, content);
    if (ans != NULL)
        goto Finish;
    ans = r_store_content_read(h, content);
Finish:
    if (ans != NULL) {
        /* Sanity check - make sure first 2 and last 2 bytes are good */
        if (content->size < 5 || ans[0] != 0x04 || ans[1] != 0x82 ||
            ans[content->size - 1] != 0 || ans[content->size - 2] != 0) {
            bogon = ans; /* for debugger */
            ans = NULL;
        }
    }
    if (ans == NULL || CCNSHOULDLOG(h, xxxx, CCNL_FINEST))
        ccnr_msg(h, "r_store_content_base.%d returning %p (acc=0x%jx, cookie=%u)",
                 __LINE__,
                 ans,
                 ccnr_accession_encode(h, content->accession),
                 (unsigned)content->cookie);
    return(ans);
}
Ejemplo n.º 9
0
/**
 * Close an open file descriptor, and grumble about it.
 */
/* unused */ void
ccnr_close_fd(struct ccnr_handle *h, unsigned filedesc, int *pfd)
{
    int res;
    
    if (*pfd != -1) {
        int linger = 0;
        setsockopt(*pfd, SOL_SOCKET, SO_LINGER,
                   &linger, sizeof(linger));
        res = close(*pfd);
        if (res == -1)
            ccnr_msg(h, "close failed for fdholder %u fd=%d: %s (errno=%d)",
                     filedesc, *pfd, strerror(errno), errno);
        else if (CCNSHOULDLOG(h, io, CCNL_FINE))
            ccnr_msg(h, "closing fd %d while finalizing fdholder %u", *pfd, filedesc);
        *pfd = -1;
    }
}
Ejemplo n.º 10
0
extern void
SyncShutdown(struct SyncBaseStruct *bp) {
    char *here = "Sync.SyncShutdown";
    int debug = bp->debug;
    if (debug >= CCNL_INFO)
        ccnr_msg(bp->ccnr, "%s", here);
    // TBD: shutdown the hearbeat
    // TBD: unregister the prefixes
}
Ejemplo n.º 11
0
PUBLIC int
r_store_final(struct ccnr_handle *h, int stable) {
    int res;
    
    res = ccn_btree_destroy(&h->btree);
    if (res < 0)
        ccnr_msg(h, "r_store_final.%d-%d Errors while closing index", __LINE__, res);
    if (res >= 0 && stable)
        res = r_store_write_stable_point(h);
    return(res);
}
Ejemplo n.º 12
0
static int
r_store_fatal(struct ccnr_handle *h, const char *fn, int lineno)
{
    if (h != NULL) {
        ccnr_msg(h,
                 "fatal error in %s, line %d, errno %d%s",
                 fn, lineno, errno, strerror(errno));
    }
    abort();
    return(0);
}
Ejemplo n.º 13
0
/**
 * Read the former size of repoFile1 from index/stable, and remove
 * the latter.
 */
static void
r_store_read_stable_point(struct ccnr_handle *h)
{
    struct ccn_charbuf *path = NULL;
    struct ccn_charbuf *cb = NULL;
    int fd;
    int i;
    ssize_t rres;
    uintmax_t val;
    unsigned char c;
    
    path = ccn_charbuf_create();
    cb = ccn_charbuf_create();
    ccn_charbuf_putf(path, "%s/index/stable", h->directory);
    fd = open(ccn_charbuf_as_string(path), O_RDONLY, 0666);
    if (fd != -1) {
        rres = read(fd, ccn_charbuf_reserve(cb, 80), 80);
        if (rres > 0)
            cb->length = rres;
        close(fd);
        if (CCNSHOULDLOG(h, dfsdf, CCNL_INFO))
            ccnr_msg(h, "Last stable at %s", ccn_charbuf_as_string(cb));
    }
    for (val = 0, i = 0; i < cb->length; i++) {
        c = cb->buf[i];
        if ('0' <= c && c <= '9')
            val = val * 10 + (c - '0');
        else
            break;
    }
    if (i == 0 || i < cb->length) {
        ccnr_msg(h, "Bad stable mark - %s", ccn_charbuf_as_string(cb));
        h->stable = 0;
    }
    else {
        h->stable = val;
        unlink(ccn_charbuf_as_string(path));
    }
    ccn_charbuf_destroy(&path);
    ccn_charbuf_destroy(&cb);
}
Ejemplo n.º 14
0
static int
merge_files(struct ccnr_handle *h)
{
    int i, last_file;
    int res;
    struct ccn_charbuf *filename = ccn_charbuf_create();
    
    // first parse the file(s) making sure there are no errors
    for (i = 2;; i++) {
        filename->length = 0;
        ccn_charbuf_putf(filename, "repoFile%d", i);
        res = r_init_map_and_process_file(h, filename, 0);
        if (res == 1)
            break;
        if (res < 0) {
            ccnr_msg(h, "Error parsing repository file %s", ccn_charbuf_as_string(filename));
            return (-1);
        }
    }
    last_file = i - 1;
    
    for (i = 2; i <= last_file; i++) {
        filename->length = 0;
        ccn_charbuf_putf(filename, "repoFile%d", i);
        res = r_init_map_and_process_file(h, filename, 1);
        if (res < 0) {
            ccnr_msg(h, "Error in phase 2 incorporating repository file %s", ccn_charbuf_as_string(filename));
            return (-1);
        }
    }
    
    for (i = last_file; i > 1; --i) {
        filename->length = 0;
        ccn_charbuf_putf(filename, "%s/repoFile%d", h->directory, i);
        if (CCNSHOULDLOG(h, LM_128, CCNL_INFO))
            ccnr_msg(h, "unlinking %s", ccn_charbuf_as_string(filename));   
        unlink(ccn_charbuf_as_string(filename));
    }
    ccn_charbuf_destroy(&filename);
    return (0);
}
Ejemplo n.º 15
0
PUBLIC void
r_store_index_needs_cleaning(struct ccnr_handle *h)
{
    int k;
    if (h->btree != NULL && h->btree->io != NULL && h->btree->cleanreq > 0) {
        if (h->index_cleaner == NULL) {
            h->index_cleaner = ccn_schedule_event(h->sched,
                                                  CCN_BT_CLEAN_TICK_MICROS,
                                                  r_store_index_cleaner, NULL, 0);
            if (CCNSHOULDLOG(h, sdfsdffd, CCNL_FINER))
                ccnr_msg(h, "index cleaner started");
        }
        /* If necessary, clean in a hurry. */
        for (k = 30; /* Backstop to make sure we do not loop here */
             k > 0 && h->index_cleaner != NULL &&
             h->btree->io->openfds > CCN_BT_OPEN_NODES_LIMIT - 2; k--)
            r_store_index_cleaner(h->sched, h, h->index_cleaner, 0);
        if (k == 0)
            ccnr_msg(h, "index cleaner is in trouble");
    }
}
Ejemplo n.º 16
0
PUBLIC void
r_io_shutdown_client_fd(struct ccnr_handle *h, int fd)
{
    struct fdholder *fdholder = NULL;
    enum cq_delay_class c;
    int m;
    int res;
    
    fdholder = r_io_fdholder_from_fd(h, fd);
    if (fdholder == NULL) {
        ccnr_msg(h, "no fd holder for fd %d", fd);
        return;
    }
    if (fdholder == h->face0)
        (res = 0, h->face0 = NULL);
    else if ((fdholder->flags & CCNR_FACE_CCND))
        res = ccn_disconnect(h->direct_client);
    else
        res = close(fd);
    if (CCNSHOULDLOG(h, sdfdf, CCNL_INFO))
        ccnr_msg(h, "shutdown client fd=%d", fd);
    ccn_charbuf_destroy(&fdholder->inbuf);
    ccn_charbuf_destroy(&fdholder->outbuf);
    for (c = 0; c < CCN_CQ_N; c++)
        r_sendq_content_queue_destroy(h, &(fdholder->q[c]));
    for (m = 0; m < CCNR_FACE_METER_N; m++)
        ccnr_meter_destroy(&fdholder->meter[m]);
    if (h->fdholder_by_fd[fd] != fdholder) abort();
    h->fdholder_by_fd[fd] = NULL;
    ccn_charbuf_destroy(&fdholder->name);
    free(fdholder);
    if (h->active_in_fd == fd)
        h->active_in_fd = -1;
    if (h->active_out_fd == fd)
        h->active_out_fd = -1;
    if (h->repofile1_fd == fd)
        h->repofile1_fd = -1;
    // r_fwd_reap_needed(h, 250000);
}
Ejemplo n.º 17
0
/**
 * Accept an incoming DGRAM_STREAM connection, creating a new fdholder.
 * @returns fd of new socket, or -1 for an error.
 */
PUBLIC int
r_io_accept_connection(struct ccnr_handle *h, int listener_fd)
{
    struct sockaddr_storage who;
    socklen_t wholen = sizeof(who);
    int fd;
    struct fdholder *fdholder;

    fd = accept(listener_fd, (struct sockaddr *)&who, &wholen);
    if (fd == -1) {
        ccnr_msg(h, "accept: %s", strerror(errno));
        return(-1);
    }
    fdholder = r_io_record_fd(h, fd,
                            (struct sockaddr *)&who, wholen,
                            CCNR_FACE_UNDECIDED);
    if (fdholder == NULL)
        close_fd(&fd);
    else if (CCNSHOULDLOG(h, io, CCNL_INFO))
        ccnr_msg(h, "accepted client fd=%d id=%u", fd, fdholder->filedesc);
    return(fd);
}
Ejemplo n.º 18
0
PUBLIC int
r_io_open_repo_data_file(struct ccnr_handle *h, const char *name, int output)
{
    struct ccn_charbuf *temp = NULL;
    int fd = -1;
    struct fdholder *fdholder = NULL;

    temp = ccn_charbuf_create();
    ccn_charbuf_putf(temp, "%s/%s", h->directory, name);
    fd = open(ccn_charbuf_as_string(temp), output ? (O_CREAT | O_WRONLY | O_APPEND) : O_RDONLY, 0666);
    if (fd == -1) {
        if (CCNSHOULDLOG(h, sdf, CCNL_FINE))
            ccnr_msg(h, "open(%s): %s", ccn_charbuf_as_string(temp), strerror(errno));
        ccn_charbuf_destroy(&temp);
        return(-1);
    }
    fdholder = r_io_record_fd(h, fd,
                            temp->buf, temp->length,
                            CCNR_FACE_REPODATA | (output ? CCNR_FACE_NORECV : CCNR_FACE_NOSEND));
    if (fdholder == NULL)
        close_fd(&fd);
    else {
        if (!output) {
            /* Use a larger buffer for indexing an existing repo file */
            if (fdholder->inbuf == NULL) {
                fdholder->inbuf = ccn_charbuf_create();
                fdholder->bufoffset = 0;
            }
            if (fdholder->inbuf != NULL)
                ccn_charbuf_reserve(fdholder->inbuf, 256 * 1024);
        }
        if (CCNSHOULDLOG(h, sdf, CCNL_INFO))
            ccnr_msg(h, "opened fd=%d file=%s", fd, ccn_charbuf_as_string(temp));
    }
    ccn_charbuf_destroy(&temp);
    return(fd);
}
Ejemplo n.º 19
0
static int
r_init_debug_getenv(struct ccnr_handle *h, const char *envname)
{
    const char *debugstr;
    int debugval;
    
    debugstr = getenv(envname);
    debugval = ccnr_msg_level_from_string(debugstr);
    /* Treat 1 and negative specially, for some backward compatibility. */
    if (debugval == 1)
        debugval = CCNL_WARNING;
    if (debugval < 0) {
        debugval = CCNL_FINEST;
        if (h != NULL)
            ccnr_msg(h, "%s='%s' is not valid, using FINEST", envname, debugstr);
    }
    return(debugval);
}
Ejemplo n.º 20
0
/**
 * Message helper for r_init_parse_config()
 */
static void
r_init_config_msg(struct ccnr_handle *h, int flags,
                  int line, int chindex, const char *msg)
{
    const char *problem = "Problem";
    int log_at = CCNL_WARNING;
    
    log_at = CCNL_WARNING;
    if ((flags & CCNR_CONFIG_ERR) != 0) {
        problem = "Error";
        log_at = CCNL_ERROR;
    }
    if ((flags & (CCNR_CONFIG_IGNORELINE|CCNR_CONFIG_PASSMASK)) == 1 &&
        CCNSHOULDLOG(h, mmm, log_at)) {
        ccnr_msg(h, "%s in config file %s/config - line %d column %d: %s",
                 problem, h->directory, line, chindex + 1, msg);
    }
}
Ejemplo n.º 21
0
/**
 *  Remove internal representation of a content object
 */
PUBLIC void
r_store_forget_content(struct ccnr_handle *h, struct content_entry **pentry)
{
    unsigned i;
    struct content_entry *entry = *pentry;
    
    if (entry == NULL)
        return;
    *pentry = NULL;
    if ((entry->flags & CCN_CONTENT_ENTRY_STALE) != 0)
        h->n_stale--;
    if (CCNSHOULDLOG(h, LM_4, CCNL_FINER))
        ccnr_debug_content(h, __LINE__, "remove", NULL, entry);
    /* Remove the cookie reference */
    i = entry->cookie & (h->cookie_limit - 1);
    if (h->content_by_cookie[i] == entry)
        h->content_by_cookie[i] = NULL;
    entry->cookie = 0;
    /* Remove the accession reference */
    if (entry->accession != CCNR_NULL_ACCESSION) {
        struct hashtb_enumerator ee;
        struct hashtb_enumerator *e = &ee;
        hashtb_start(h->content_by_accession_tab, e);
        if (hashtb_seek(e, &entry->accession, sizeof(entry->accession), 0) ==
            HT_NEW_ENTRY) {
            ccnr_msg(h, "orphaned content %llu",
                     (unsigned long long)(entry->accession));
            hashtb_delete(e);
            hashtb_end(e);
            return;
        }
        hashtb_delete(e);
        hashtb_end(e);
        entry->accession = CCNR_NULL_ACCESSION;
    }
    /* Clean up allocated subfields */
    ccn_charbuf_destroy(&entry->flatname);
    if (entry->cob != NULL) {
        h->cob_count--;
        ccn_charbuf_destroy(&entry->cob);
    }
    free(entry);
}
Ejemplo n.º 22
0
PUBLIC struct content_entry *
r_store_content_from_accession(struct ccnr_handle *h, ccnr_accession accession)
{
    struct ccn_parsed_ContentObject obj = {0};
    struct content_entry *content = NULL;
    struct content_by_accession_entry *entry;
    const unsigned char *content_base = NULL;
    int res;
    ccnr_accession acc;
    
    if (accession == CCNR_NULL_ACCESSION)
        return(NULL);
    entry = hashtb_lookup(h->content_by_accession_tab,
                          &accession, sizeof(accession));
    if (entry != NULL) {
        h->content_from_accession_hits++;
        return(entry->content);
    }
    h->content_from_accession_misses++;
    content = calloc(1, sizeof(*content));
    CHKPTR(content);
    content->cookie = 0;
    content->accession = accession;
    content->cob = NULL;
    content->size = 0;
    content_base = r_store_content_base(h, content);
    if (content_base == NULL || content->size == 0)
        goto Bail;
    res = r_store_set_flatname(h, content, &obj);
    if (res < 0) goto Bail;
    r_store_enroll_content(h, content);
    res = r_store_content_btree_insert(h, content, &obj, &acc);
    if (res < 0) goto Bail;
    if (res == 1 || CCNSHOULDLOG(h, sdf, CCNL_FINEST))
        ccnr_debug_content(h, __LINE__, "content/accession", NULL, content);
    return(content);
Bail:
    ccnr_msg(h, "r_store_content_from_accession.%d failed 0x%jx",
             __LINE__, ccnr_accession_encode(h, accession));
    r_store_forget_content(h, &content);
    return(content);
}
Ejemplo n.º 23
0
/**
 *  Produce a ccnr debug trace entry.
 *  Output is produced by calling ccnr_msg.
 *  @param      h  the ccnr handle
 *  @param      lineno  caller's source line number (usually __LINE__)
 *  @param      msg  a short text tag to identify the entry
 *  @param      fdholder    handle of associated fdholder; may be NULL
 *  @param      ccnb    points to ccnb-encoded Interest or ContentObject
 *  @param      ccnb_size   is in bytes
 */
void
ccnr_debug_ccnb(struct ccnr_handle *h,
                int lineno,
                const char *msg,
                struct fdholder *fdholder,
                const unsigned char *ccnb,
                size_t ccnb_size)
{
    struct ccn_charbuf *c;
    struct ccn_parsed_interest pi;
    const unsigned char *nonce = NULL;
    size_t nonce_size = 0;
    size_t i;
    
    
    if (h != NULL && h->debug == 0)
        return;
    c = ccn_charbuf_create();
    ccn_charbuf_putf(c, "debug.%d %s ", lineno, msg);
    if (fdholder != NULL)
        ccn_charbuf_putf(c, "%u ", fdholder->filedesc);
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    ccn_charbuf_putf(c, " (%u bytes)", (unsigned)ccnb_size);
    if (ccn_parse_interest(ccnb, ccnb_size, &pi, NULL) >= 0) {
        const char *p = "";
        ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                  pi.offset[CCN_PI_B_Nonce],
                  pi.offset[CCN_PI_E_Nonce],
                  &nonce,
                  &nonce_size);
        if (nonce_size > 0) {
            ccn_charbuf_putf(c, " ");
            if (nonce_size == 12)
                p = "CCC-P-F-T-NN";
            for (i = 0; i < nonce_size; i++)
                ccn_charbuf_putf(c, "%s%02X", (*p) && (*p++)=='-' ? "-" : "", nonce[i]);
        }
    }
    ccnr_msg(h, "%s", ccn_charbuf_as_string(c));
    ccn_charbuf_destroy(&c);
}
Ejemplo n.º 24
0
/**
 * Handle errors after send() or sendto().
 * @returns -1 if error has been dealt with, or 0 to defer sending.
 */
static int
handle_send_error(struct ccnr_handle *h, int errnum, struct fdholder *fdholder,
                  const void *data, size_t size)
{
    int res = -1;
    if (errnum == EAGAIN) {
        res = 0;
    }
    else if (errnum == EPIPE) {
        fdholder->flags |= CCNR_FACE_NOSEND;
        fdholder->outbufindex = 0;
        ccn_charbuf_destroy(&fdholder->outbuf);
    }
    else {
        ccnr_msg(h, "send/write to fd %u failed: %s (errno = %d)",
                 fdholder->filedesc, strerror(errnum), errnum);
        if (errnum == EISCONN || errnum == EFBIG || errnum == ENOSPC)
            res = 0;
    }
    return(res);
}
Ejemplo n.º 25
0
PUBLIC void
ccnr_debug_content(struct ccnr_handle *h,
                   int lineno,
                   const char *msg,
                   struct fdholder *fdholder,
                   struct content_entry *content)
{
    struct ccn_charbuf *c = ccn_charbuf_create();
    struct ccn_charbuf *flat = content->flatname;
    
    if (c == NULL)
        return;
    ccn_charbuf_putf(c, "debug.%d %s ", lineno, msg);
    if (fdholder != NULL)
        ccn_charbuf_putf(c, "%u ", fdholder->filedesc);
    if (flat != NULL)
        ccn_uri_append_flatname(c, flat->buf, flat->length, 1);
    ccn_charbuf_putf(c, " (%d bytes)", content->size);
    ccnr_msg(h, "%s", ccn_charbuf_as_string(c));
    ccn_charbuf_destroy(&c);
}
Ejemplo n.º 26
0
/**
 * Log a bit if we are taking a while to re-index.
 */
static int
r_store_reindexing(struct ccn_schedule *sched,
                   void *clienth,
                   struct ccn_scheduled_event *ev,
                   int flags)
{
    struct ccnr_handle *h = clienth;
    struct fdholder *in = NULL;
    unsigned pct;
    
    if ((flags & CCN_SCHEDULE_CANCEL) != 0)
        return(0);
    in = r_io_fdholder_from_fd(h, h->active_in_fd);
    if (in == NULL)
        return(0);
    pct = ccnr_meter_total(in->meter[FM_BYTI]) / ((h->startupbytes / 100) + 1);
    if (pct >= 100)
        return(0);
    ccnr_msg(h, "indexing %u%% complete", pct);
    return(2000000);
}
Ejemplo n.º 27
0
static int
ccnr_direct_client_refresh(struct ccn_schedule *sched,
               void *clienth,
               struct ccn_scheduled_event *ev,
               int flags)
{
    struct ccnr_handle *ccnr = clienth;
    int microsec = 0;
    if ((flags & CCN_SCHEDULE_CANCEL) == 0 &&
          ccnr->direct_client != NULL &&
          ccnr->direct_client_refresh == ev) {
        microsec = ccn_process_scheduled_operations(ccnr->direct_client);
        // XXX - This is not really right, since an incoming request can cause us to need to reschedule this event.
        if CCNSHOULDLOG(ccnr, refresh, CCNL_FINEST)
            ccnr_msg(ccnr, "direct_client_refresh %d in %d usec",
                     ccn_get_connection_fd(ccnr->direct_client), microsec);
        if (microsec > ev->evint)
            microsec = ev->evint;
        if (microsec == 0)
            microsec = CCN_INTEREST_LIFETIME_MICROSEC;
    }
Ejemplo n.º 28
0
static int
establish_min_send_bufsize(struct ccnr_handle *h, int fd, int minsize)
{
    int res;
    int bufsize;
    int obufsize;
    socklen_t bufsize_sz;

    bufsize_sz = sizeof(bufsize);
    res = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsize, &bufsize_sz);
    if (res == -1)
        return (res);
    obufsize = bufsize;
    if (bufsize < minsize) {
        bufsize = minsize;
        res = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
        if (res == -1)
            return(res);
    }
    if (CCNSHOULDLOG(h, sdfdsf, CCNL_INFO))
        ccnr_msg(h, "SO_SNDBUF for fd %d is %d (was %d)", fd, bufsize, obufsize);
    return(bufsize);
}
Ejemplo n.º 29
0
/**
 * Set up the array of fd descriptors for the poll(2) call.
 *
 */
PUBLIC void
r_io_prepare_poll_fds(struct ccnr_handle *h)
{
    int i, j, nfds;
    
    for (i = 1, nfds = 0; i < h->face_limit; i++)
        if (r_io_fdholder_from_fd(h, i) != NULL)
            nfds++;
    
    if (nfds != h->nfds) {
        h->nfds = nfds;
        h->fds = realloc(h->fds, h->nfds * sizeof(h->fds[0]));
        memset(h->fds, 0, h->nfds * sizeof(h->fds[0]));
    }
    for (i = 1, j = 0; i < h->face_limit; i++) {
        struct fdholder *fdholder = r_io_fdholder_from_fd(h, i);
        if (fdholder != NULL) {
            h->fds[j].fd = fdholder->filedesc;
            h->fds[j].events = 0;
            if ((fdholder->flags & (CCNR_FACE_NORECV|CCNR_FACE_REPODATA)) == 0)
                h->fds[j].events |= POLLIN;
            if (fdholder->filedesc == h->active_in_fd)
                h->fds[j].events |= POLLIN;
            if (((fdholder->flags & CCNR_FACE_REPODATA) == 0) &&
                ((fdholder->outbuf != NULL || (fdholder->flags & CCNR_FACE_CLOSING) != 0)))
                h->fds[j].events |= POLLOUT;
             if ((fdholder->flags & CCNR_FACE_CCND) != 0) {
                 if (ccn_output_is_pending(h->direct_client)) {
                     if (CCNSHOULDLOG(h, xxx, CCNL_FINEST))
                        ccnr_msg(h, "including direct client in poll set");
                     h->fds[j].events |= POLLOUT;
                }
             }
            j++;
        }
    }
}
Ejemplo n.º 30
0
/**
 * Send data to the fdholder.
 *
 * No direct error result is provided; the fdholder state is updated as needed.
 */
PUBLIC void
r_io_send(struct ccnr_handle *h,
          struct fdholder *fdholder,
          const void *data, size_t size,
          off_t *offsetp)
{
    ssize_t res;
    off_t offset = -1;
    
    if (offsetp != NULL)
        *offsetp = (off_t)-1;
    if ((fdholder->flags & CCNR_FACE_NOSEND) != 0)
        return;
    if (fdholder->outbuf != NULL) {
        ccn_charbuf_append(fdholder->outbuf, data, size);
        return;
    }
    if (fdholder == h->face0) {
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], size);
        ccn_dispatch_message(h->internal_client, (void *)data, size);
        r_dispatch_process_internal_client_buffer(h);
        return;
    }
    if ((fdholder->flags & CCNR_FACE_CCND) != 0) {
        /* Writes here need to go via the direct client's handle. */
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], size);
        res = ccn_put(h->direct_client, data, size);
        if (res < 0 && CCNSHOULDLOG(h, r_io_send, CCNL_WARNING))
            ccnr_msg(h, "ccn_put failed");
        if (res == 1 && CCNSHOULDLOG(h, r_io_send, CCNL_FINEST))
            ccnr_msg(h, "ccn_put deferred output for later send");
        return;
    }
    if ((fdholder->flags & CCNR_FACE_REPODATA) != 0) {
        offset = lseek(fdholder->filedesc, 0, SEEK_END);
        if (offset == (off_t)-1) {
            ccnr_msg(h, "lseek(%d): %s", fdholder->filedesc, strerror(errno));
            return;
        }
        if (offsetp != NULL)
            *offsetp = offset;
        if (fdholder->filedesc == h->active_out_fd) {
            if (offset != h->stable && h->stable != 0)
                ccnr_msg(h, "expected file size %ju, found %ju",
                    (uintmax_t)h->stable,
                    (uintmax_t)offset);
            h->stable = offset + size;
        }
    }
    if ((fdholder->flags & CCNR_FACE_DGRAM) == 0)
        res = write(fdholder->filedesc, data, size);
    else
        res = sendto(sending_fd(h, fdholder), data, size, 0,
                     (struct sockaddr *)fdholder->name->buf,
                     fdholder->name->length);
    if (res > 0)
        ccnr_meter_bump(h, fdholder->meter[FM_BYTO], res);
    if (res == size)
        return;
    if (res == -1) {
        res = handle_send_error(h, errno, fdholder, data, size);
        if (res == -1)
            return;
    }
    if ((fdholder->flags & CCNR_FACE_DGRAM) != 0) {
        ccnr_msg(h, "sendto short");
        return;
    }
    if ((fdholder->flags & CCNR_FACE_REPODATA) != 0) {
        // need to truncate back to last known good object then exit.
        ccnr_msg(h, "Unrecoverable write error writing to repository. Content NOT stored.");
        ftruncate(fdholder->filedesc, offset);
        h->running = 0;
        return;
    }
    fdholder->outbufindex = 0;
    fdholder->outbuf = ccn_charbuf_create();
    if (fdholder->outbuf == NULL) {
        ccnr_msg(h, "do_write: %s", strerror(errno));
        return;
    }
    ccn_charbuf_append(fdholder->outbuf,
                       ((const unsigned char *)data) + res, size - res);
}