Beispiel #1
0
PUBLIC struct content_entry *
process_incoming_content(struct ccnr_handle *h, struct fdholder *fdholder,
                         unsigned char *msg, size_t size)
{
    struct ccn_parsed_ContentObject obj = {0};
    int res;
    struct content_entry *content = NULL;
    ccnr_accession accession = CCNR_NULL_ACCESSION;
    
    content = calloc(1, sizeof(*content));
    if (content == NULL)
        goto Bail;    
    content->cob = ccn_charbuf_create();
    if (content->cob == NULL)
        goto Bail;    
    res = ccn_charbuf_append(content->cob, msg, size);
    if (res < 0) goto Bail;
    content->size = size;
    res = r_store_set_flatname(h, content, &obj);
    if (res < 0) goto Bail;
    ccnr_meter_bump(h, fdholder->meter[FM_DATI], 1);
    content->accession = CCNR_NULL_ACCESSION;
    r_store_enroll_content(h, content);
    if (CCNSHOULDLOG(h, LM_4, CCNL_FINE))
        ccnr_debug_content(h, __LINE__, "content_from", fdholder, content);
    res = r_store_content_btree_insert(h, content, &obj, &accession);
    if (res < 0) goto Bail;
    if (res == 0) {
        /* Content was there, with an accession */
        if (CCNSHOULDLOG(h, LM_4, CCNL_FINER))
            ccnr_debug_content(h, __LINE__, "content_duplicate",
                               fdholder, content);
        h->content_dups_recvd++;
        r_store_forget_content(h, &content);
        content = r_store_content_from_accession(h, accession);
        if (content == NULL)
            goto Bail;
    }
    r_store_set_content_timer(h, content, &obj);
    r_match_match_interests(h, content, &obj, NULL, fdholder);
    return(content);
Bail:
    r_store_forget_content(h, &content);
    return(content);
}
Beispiel #2
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);
}