Exemple #1
0
PUBLIC int
r_store_commit_content(struct ccnr_handle *h, struct content_entry *content)
{
    // XXX - here we need to check if this is something we *should* be storing, according to our policy
    if ((r_store_content_flags(content) & CCN_CONTENT_ENTRY_STABLE) == 0) {
        r_store_send_content(h, r_io_fdholder_from_fd(h, h->active_out_fd), content);
        r_store_content_change_flags(content, CCN_CONTENT_ENTRY_STABLE, 0);
    }
    return(0);
}
Exemple #2
0
/**
 * Shutdown all open fds.
 */
PUBLIC void
r_io_shutdown_all(struct ccnr_handle *h)
{
    int i;
    for (i = 1; i < h->face_limit; i++) {
        if (r_io_fdholder_from_fd(h, i) != NULL)
            r_io_shutdown_client_fd(h, i);
    }
    ccnr_internal_client_stop(h);
    r_io_shutdown_client_fd(h, 0);
}
Exemple #3
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++;
        }
    }
}
Exemple #4
0
PUBLIC void
r_match_consume_interest(struct ccnr_handle *h, struct propagating_entry *pe)
{
    struct fdholder *fdholder = NULL;
    ccn_indexbuf_destroy(&pe->outbound);
    if (pe->interest_msg != NULL) {
        free(pe->interest_msg);
        pe->interest_msg = NULL;
        fdholder = r_io_fdholder_from_fd(h, pe->filedesc);
        if (fdholder != NULL)
            fdholder->pending_interests -= 1;
    }
    if (pe->next != NULL) {
        pe->next->prev = pe->prev;
        pe->prev->next = pe->next;
        pe->next = pe->prev = NULL;
    }
    pe->usec = 0;
}
Exemple #5
0
PUBLIC void
r_store_send_content(struct ccnr_handle *h, struct fdholder *fdholder, struct content_entry *content)
{
    const unsigned char *content_msg = NULL;
    off_t offset;

    if (CCNSHOULDLOG(h, LM_4, CCNL_FINE))
        ccnr_debug_content(h, __LINE__, "content_to", fdholder, content);
    content_msg = r_store_content_base(h, content);
    r_link_stuff_and_send(h, fdholder, content_msg, content->size, NULL, 0, &offset);
    if (offset != (off_t)-1 && content->accession == CCNR_NULL_ACCESSION) {
        int res;
        res = r_store_set_accession_from_offset(h, content, fdholder, offset);
        if (res == 0)
            if (CCNSHOULDLOG(h, LM_4, CCNL_FINE))
                ccnr_debug_content(h, __LINE__, "content_stored",
                                   r_io_fdholder_from_fd(h, h->active_out_fd),
                                   content);
    }
}
Exemple #6
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);
}
Exemple #7
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);
}
Exemple #8
0
/**
 * Consume matching interests
 * given a nameprefix_entry and a piece of content.
 *
 * If fdholder is not NULL, pay attention only to interests from that fdholder.
 * It is allowed to pass NULL for pc, but if you have a (valid) one it
 * will avoid a re-parse.
 * @returns number of matches found.
 */
PUBLIC int
r_match_consume_matching_interests(struct ccnr_handle *h,
                           struct nameprefix_entry *npe,
                           struct content_entry *content,
                           struct ccn_parsed_ContentObject *pc,
                           struct fdholder *fdholder)
{
    int matches = 0;
    struct propagating_entry *head;
    struct propagating_entry *next;
    struct propagating_entry *p;
    const unsigned char *content_msg;
    size_t content_size;
    struct fdholder *f;
    
    head = &npe->pe_head;
    // XXX - i do not think this is called in practice
    content_msg = r_store_content_base(h, content);
    content_size = r_store_content_size(h, content);
    f = fdholder;
    for (p = head->next; p != head; p = next) {
        next = p->next;
        if (p->interest_msg != NULL &&
            ((fdholder == NULL && (f = r_io_fdholder_from_fd(h, p->filedesc)) != NULL) ||
             (fdholder != NULL && p->filedesc == fdholder->filedesc))) {
            if (ccn_content_matches_interest(content_msg, content_size, 1, pc,
                                             p->interest_msg, p->size, NULL)) {
                r_sendq_face_send_queue_insert(h, f, content);
                if (CCNSHOULDLOG(h, (32 | 8), CCNL_FINE))
                    ccnr_debug_ccnb(h, __LINE__, "consume", f,
                                    p->interest_msg, p->size);
                matches += 1;
                r_match_consume_interest(h, p);
            }
        }
    }
    return(matches);
}
Exemple #9
0
/**
 * Looks up a fdholder based on its filedesc.
 */
PUBLIC struct fdholder *
ccnr_r_io_fdholder_from_fd(struct ccnr_handle *h, unsigned filedesc)
{
    return(r_io_fdholder_from_fd(h, filedesc));
}
Exemple #10
0
static int
content_sender(struct ccn_schedule *sched,
    void *clienth,
    struct ccn_scheduled_event *ev,
    int flags)
{
    int i, j;
    int delay;
    int nsec;
    int burst_nsec;
    int burst_max;
    struct ccnr_handle *h = clienth;
    struct content_entry *content = NULL;
    unsigned filedesc = ev->evint;
    struct fdholder *fdholder = NULL;
    struct content_queue *q = ev->evdata;
    (void)sched;
    
    if ((flags & CCN_SCHEDULE_CANCEL) != 0)
        goto Bail;
    fdholder = r_io_fdholder_from_fd(h, filedesc);
    if (fdholder == NULL)
        goto Bail;
    if (q->send_queue == NULL)
        goto Bail;
    if ((fdholder->flags & CCNR_FACE_NOSEND) != 0)
        goto Bail;
    /* Send the content at the head of the queue */
    if (q->ready > q->send_queue->n ||
        (q->ready == 0 && q->nrun >= 12 && q->nrun < 120))
        q->ready = q->send_queue->n;
    nsec = 0;
    burst_nsec = q->burst_nsec;
    burst_max = 2;
    if (q->ready < burst_max)
        burst_max = q->ready;
    if (burst_max == 0)
        q->nrun = 0;
    for (i = 0; i < burst_max && nsec < 1000000; i++) {
        content = r_store_content_from_cookie(h, q->send_queue->buf[i]);
        if (content == NULL)
            q->nrun = 0;
        else {
            r_link_send_content(h, fdholder, content);
            /* fdholder may have vanished, bail out if it did */
            if (r_io_fdholder_from_fd(h, filedesc) == NULL)
                goto Bail;
            // nsec += burst_nsec * (unsigned)((content->size + 1023) / 1024);
            q->nrun++;
        }
    }
    if (q->ready < i) abort();
    q->ready -= i;
    /* Update queue */
    for (j = 0; i < q->send_queue->n; i++, j++)
        q->send_queue->buf[j] = q->send_queue->buf[i];
    q->send_queue->n = j;
    /* Do a poll before going on to allow others to preempt send. */
    delay = (nsec + 499) / 1000 + 1;
    if (q->ready > 0) {
        return(delay);
    }
    q->ready = j;
    if (q->nrun >= 12 && q->nrun < 120) {
        /* We seem to be a preferred provider, forgo the randomized delay */
        if (j == 0)
            delay += burst_nsec / 50;
        return(delay);
    }
    /* Determine when to run again */
    for (i = 0; i < q->send_queue->n; i++) {
        content = r_store_content_from_cookie(h, q->send_queue->buf[i]);
        if (content != NULL) {
            q->nrun = 0;
            delay = randomize_content_delay(h, q);
            if (CCNSHOULDLOG(h, LM_8, CCNL_FINER))
                ccnr_msg(h, "fdholder %u queued %u delay %i",
                         (unsigned)ev->evint, q->ready, delay);
            return(delay);
        }
    }
    q->send_queue->n = q->ready = 0;
Bail:
    q->sender = NULL;
    return(0);
}
Exemple #11
0
int
r_init_map_and_process_file(struct ndnr_handle *h, struct ndn_charbuf *filename, int add_content)
{
    int res = 0;
    int dres;
    struct stat statbuf;
    unsigned char *mapped_file = MAP_FAILED;
    unsigned char *msg;
    size_t size;
    int fd = -1;
    struct content_entry *content;
    struct ndn_skeleton_decoder *d;
    struct fdholder *fdholder;
    
    fd = r_io_open_repo_data_file(h, ndn_charbuf_as_string(filename), 0);
    if (fd == -1)   // Normal exit
        return(1);
    
    res = fstat(fd, &statbuf);
    if (res != 0) {
        ndnr_msg(h, "stat failed for %s (fd=%d), %s (errno=%d)",
                 ndn_charbuf_as_string(filename), fd, strerror(errno), errno);
        res = -errno;
        goto Bail;
    }
    if (statbuf.st_size == 0)
        goto Bail;
    
    mapped_file = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
    if (mapped_file == MAP_FAILED) {
        ndnr_msg(h, "mmap failed for %s (fd=%d), %s (errno=%d)",
                 ndn_charbuf_as_string(filename), fd, strerror(errno), errno);
        res = -errno;
        goto Bail;
    }
    fdholder = r_io_fdholder_from_fd(h, fd);
    d = &fdholder->decoder;
    msg = mapped_file;
    size = statbuf.st_size;
    while (d->index < size) {
        dres = ndn_skeleton_decode(d, msg + d->index, size - d->index);
        if (!NDN_FINAL_DSTATE(d->state))
            break;
        if (add_content) {
            content = process_incoming_content(h, fdholder, msg + d->index - dres, dres, NULL);
            if (content != NULL)
                r_store_commit_content(h, content);
        }
    }
    
    if (d->index != size || !NDN_FINAL_DSTATE(d->state)) {
        ndnr_msg(h, "protocol error on fdholder %u (state %d), discarding %d bytes",
                 fdholder->filedesc, d->state, (int)(size - d->index));
        res = -1;
        goto Bail;
    }
    
Bail:
    if (mapped_file != MAP_FAILED)
        munmap(mapped_file, statbuf.st_size);
    r_io_shutdown_client_fd(h, fd);
    return (res);
}