示例#1
0
文件: mlog.c 项目: reqshark/millsocks
static void mlog_close(int s) {
    struct mlogsock *obj = hdata(s, msock_type);
    dsock_assert(obj && obj->vfptrs.type == mlog_type);
    int rc = hclose(obj->s);
    dsock_assert(rc == 0);
    free(obj);
}
示例#2
0
static void bthrottler_close(int s) {
    struct bthrottlersock *obj = hdata(s, bsock_type);
    dsock_assert(obj && obj->vfptrs.type == bthrottler_type);
    int rc = hclose(obj->s);
    dsock_assert(rc == 0);
    free(obj);
}
示例#3
0
文件: lz4.c 项目: raedwulf/dillsocks
static int lz4_msendv(struct msock_vfs *mvfs,
      const struct iovec *iov, size_t iovlen, int64_t deadline) {
    struct lz4_sock *obj = dsock_cont(mvfs, struct lz4_sock, mvfs);
    /* Adjust the buffer size as needed. */
    size_t len = iov_size(iov, iovlen);
    size_t maxlen = LZ4F_compressFrameBound(len, NULL);
    if(obj->outlen < maxlen) {
        uint8_t *newbuf = realloc(obj->outbuf, maxlen);
        if(dsock_slow(!newbuf)) {errno = ENOMEM; return -1;}
        obj->outbuf = newbuf;
        obj->outlen = maxlen;
    }
    /* Compress the data. */
    /* TODO: Avoid the extra allocations and copies. */
    uint8_t *buf = malloc(len);
    if(dsock_slow(!buf)) {errno = ENOMEM; return -1;}
    iov_copyallfrom(buf, iov, iovlen);
    LZ4F_preferences_t prefs = {0};
    prefs.frameInfo.contentSize = len;
    size_t dstlen = LZ4F_compressFrame(obj->outbuf, obj->outlen,
        buf, len, &prefs);
    dsock_assert(!LZ4F_isError(dstlen));
    dsock_assert(dstlen <= obj->outlen);
    free(buf);
    /* Send the compressed frame. */
    return msend(obj->s, obj->outbuf, dstlen, deadline);
}
示例#4
0
文件: lz4.c 项目: raedwulf/dillsocks
static void lz4_hclose(struct hvfs *hvfs) {
    struct lz4_sock *obj = (struct lz4_sock*)hvfs;
    size_t ec = LZ4F_freeDecompressionContext(obj->dctx);
    dsock_assert(!LZ4F_isError(ec));
    free(obj->inbuf);
    free(obj->outbuf);
    int rc = hclose(obj->s);
    dsock_assert(rc == 0);
    free(obj);
}
示例#5
0
static void nagle_hclose(struct hvfs *hvfs) {
    struct nagle_sock *obj = (struct nagle_sock*)hvfs;
    int rc = hclose(obj->sender);
    dsock_assert(rc == 0);
    rc = hclose(obj->ackch);
    dsock_assert(rc == 0);
    rc = hclose(obj->sendch);
    dsock_assert(rc == 0);
    free(obj->buf);
    rc = hclose(obj->s);
    dsock_assert(rc == 0);
    free(obj);
}
示例#6
0
int nagle_stop(int s, int64_t deadline) {
    struct nagle_sock *obj = hquery(s, nagle_type);
    if(dsock_slow(!obj)) return -1;
    /* TODO: Flush the data from the buffer! */
    int rc = hclose(obj->sender);
    dsock_assert(rc == 0);
    rc = hclose(obj->ackch);
    dsock_assert(rc == 0);
    rc = hclose(obj->sendch);
    dsock_assert(rc == 0);
    free(obj->buf);
    int u = obj->s;
    free(obj);
    return u;
}
示例#7
0
static int bthrottler_brecv(int s, void *buf, size_t len,
      int64_t deadline) {
    struct bthrottlersock *obj = hdata(s, bsock_type);
    dsock_assert(obj->vfptrs.type == bthrottler_type);
    /* If recv-throttling is off forward the call. */
    if(obj->recv_full == 0) return brecv(obj->s, buf, len, deadline);
    /* Get rid of the corner case. */
    if(dsock_slow(len == 0)) return 0;
    while(1) {
        /* If there's capacity receive as much data as possible. */
        if(obj->recv_remaining) {
            size_t torecv = len < obj->recv_remaining ?
                len : obj->recv_remaining;
            int rc = brecv(obj->s, buf, torecv, deadline);
            if(dsock_slow(rc < 0)) return -1;
            obj->recv_remaining -= torecv;
            buf = (char*)buf + torecv;
            len -= torecv;
            if(len == 0) return 0;
        }
        /* Wait till capacity can be renewed. */
        int rc = msleep(obj->recv_last + obj->recv_interval);
        if(dsock_slow(rc < 0)) return -1;
        /* Renew the capacity. */
        obj->recv_remaining = obj->recv_full;
        obj->recv_last = now();
    }
} 
示例#8
0
文件: lz4.c 项目: raedwulf/dillsocks
int lz4_start(int s) {
    int err;
    /* Check whether underlying socket is message-based. */
    if(dsock_slow(!hquery(s, msock_type))) {err = errno; goto error1;}
    /* Create the object. */
    struct lz4_sock *obj = malloc(sizeof(struct lz4_sock));
    if(dsock_slow(!obj)) {errno = ENOMEM; goto error1;}
    obj->hvfs.query = lz4_hquery;
    obj->hvfs.close = lz4_hclose;
    obj->mvfs.msendv = lz4_msendv;
    obj->mvfs.mrecvv = lz4_mrecvv;
    obj->s = s;
    obj->outbuf = NULL;
    obj->outlen = 0;
    obj->inbuf = NULL;
    obj->inlen = 0;        
    size_t ec = LZ4F_createDecompressionContext(&obj->dctx, LZ4F_VERSION);
    if(dsock_slow(LZ4F_isError(ec))) {err = EFAULT; goto error2;}
    /* Create the handle. */
    int h = hcreate(&obj->hvfs);
    if(dsock_slow(h < 0)) {err = errno; goto error3;}
    return h;
error3:
    ec = LZ4F_freeDecompressionContext(obj->dctx);
    dsock_assert(!LZ4F_isError(ec));
error2:
    free(obj);
error1:
    errno = err;
    return -1;
}
示例#9
0
int nagle_start(int s, size_t batch, int64_t interval) {
    int rc;
    int err;
    /* Check whether underlying socket is a bytestream. */
    if(dsock_slow(!hquery(s, bsock_type))) {err = errno; goto error1;}
    /* Create the object. */
    struct nagle_sock *obj = malloc(sizeof(struct nagle_sock));
    if(dsock_slow(!obj)) {err = ENOMEM; goto error1;}
    obj->hvfs.query = nagle_hquery;
    obj->hvfs.close = nagle_hclose;
    obj->bvfs.bsendv = nagle_bsendv;
    obj->bvfs.brecvv = nagle_brecvv;
    obj->s = s;
    obj->buf = malloc(batch);
    if(dsock_slow(!obj->buf)) {errno = ENOMEM; goto error2;}
    obj->sendch = channel(sizeof(struct nagle_vec), 0);
    if(dsock_slow(obj->sendch < 0)) {err = errno; goto error3;}
    obj->ackch = channel(sizeof(int), 0);
    if(dsock_slow(obj->ackch < 0)) {err = errno; goto error4;}
    obj->sender = go(nagle_sender(s, batch, interval,
        obj->buf, obj->sendch, obj->ackch));
    if(dsock_slow(obj->sender < 0)) {err = errno; goto error5;}
    /* Create the handle. */
    int h = hcreate(&obj->hvfs);
    if(dsock_slow(h < 0)) {err = errno; goto error6;}
    return h;
error6:
    rc = hclose(obj->sender);
    dsock_assert(rc == 0);
error5:
    rc = hclose(obj->ackch);
    dsock_assert(rc == 0);
error4:
    rc = hclose(obj->sendch);
    dsock_assert(rc == 0);
error3:
    free(obj->buf);
error2:
    free(obj);
error1:
    errno = err;
    return -1;
}
示例#10
0
文件: mlog.c 项目: reqshark/millsocks
static int mlog_msend(int s, const void *buf, size_t len,
      int64_t deadline) {
    struct mlogsock *obj = hdata(s, msock_type);
    dsock_assert(obj->vfptrs.type == mlog_type);
    fprintf(stderr, "send %8zuB: 0x", len);
    size_t i;
    for(i = 0; i != len; ++i)
        fprintf(stderr, "%02x", (int)((uint8_t*)buf)[i]);
    fprintf(stderr, "\n");
    return msend(obj->s, buf, len, deadline);
}
示例#11
0
文件: lz4.c 项目: raedwulf/dillsocks
int lz4_stop(int s) {
    struct lz4_sock *obj = hquery(s, lz4_type);
    if(dsock_slow(!obj)) return -1;
    size_t ec = LZ4F_freeDecompressionContext(obj->dctx);
    dsock_assert(!LZ4F_isError(ec));
    free(obj->inbuf);
    free(obj->outbuf);
    int u = obj->s;
    free(obj);
    return u;
}
示例#12
0
文件: mlog.c 项目: reqshark/millsocks
static ssize_t mlog_mrecv(int s, void *buf, size_t len,
      int64_t deadline) {
    struct mlogsock *obj = hdata(s, msock_type);
    dsock_assert(obj->vfptrs.type == mlog_type);
    ssize_t sz = mrecv(obj->s, buf, len, deadline);
    if(dsock_slow(sz < 0)) return -1;
    fprintf(stderr, "recv %8zuB: 0x", len);
    size_t i;
    for(i = 0; i != sz && i != len; ++i)
        fprintf(stderr, "%02x", (int)((uint8_t*)buf)[i]);
    fprintf(stderr, "\n");
    return sz;
} 
示例#13
0
static ssize_t mthrottler_mrecv(int s, void *buf, size_t len,
      int64_t deadline) {
    struct mthrottlersock *obj = hdata(s, msock_type);
    dsock_assert(obj->vfptrs.type == mthrottler_type);
    /* If recv-throttling is off forward the call. */
    if(obj->recv_full == 0) return mrecv(obj->s, buf, len, deadline);
    /* If there's no quota wait till it is renewed. */
    if(!obj->recv_remaining) {
        int rc = msleep(obj->recv_last + obj->recv_interval);
        if(dsock_slow(rc < 0)) return -1;
        obj->recv_remaining = obj->recv_full;
        obj->recv_last = now();
    }
    /* Receive the message. */
    int rc = mrecv(obj->s, buf, len, deadline);
    if(dsock_slow(rc < 0)) return -1;
    --obj->recv_remaining;
    return 0;
} 
示例#14
0
文件: lz4.c 项目: raedwulf/dillsocks
static ssize_t lz4_mrecvv(struct msock_vfs *mvfs,
      const struct iovec *iov, size_t iovlen, int64_t deadline) {
    struct lz4_sock *obj = dsock_cont(mvfs, struct lz4_sock, mvfs);
    /* Adjust the buffer size as needed. */
    size_t len = iov_size(iov, iovlen);
    size_t maxlen = LZ4F_compressFrameBound(len, NULL);
    if(obj->inlen < maxlen) {
        uint8_t *newbuf = realloc(obj->inbuf, maxlen);
        if(dsock_slow(!newbuf)) {errno = ENOMEM; return -1;}
        obj->inbuf = newbuf;
        obj->inlen = maxlen;
    }
    /* Get the compressed message. */
    ssize_t sz = mrecv(obj->s, obj->inbuf, obj->inlen, deadline);
    if(dsock_slow(sz < 0)) return -1;
    /* Extract size of the uncompressed message from LZ4 frame header. */
    LZ4F_frameInfo_t info;
    size_t infolen = sz;
    size_t ec = LZ4F_getFrameInfo(obj->dctx, &info, obj->inbuf, &infolen);
    if(dsock_slow(LZ4F_isError(ec))) {errno = EPROTO; return -1;}
    /* Size is a required field. */
    if(dsock_slow(info.contentSize == 0)) {errno = EPROTO; return -1;}
    /* Decompressed message would exceed the buffer size. */
    if(dsock_slow(info.contentSize > len)) {errno = EMSGSIZE; return -1;}
    /* Decompress. */
    /* TODO: Avoid the extra allocations and copies. */
    uint8_t *buf = malloc(len);
    if(dsock_slow(!buf)) {errno = ENOMEM; return -1;}
    size_t dstlen = len;
    size_t srclen = sz - infolen;
    ec = LZ4F_decompress(obj->dctx, buf, &dstlen,
        obj->inbuf + infolen, &srclen, NULL);
    if(dsock_slow(LZ4F_isError(ec))) {errno = EPROTO; return -1;}
    if(dsock_slow(ec != 0)) {errno = EPROTO; return -1;}
    dsock_assert(srclen == sz - infolen);
    iov_copyallto(iov, iovlen, buf);
    free(buf);
    return dstlen;
}
示例#15
0
static void mthrottler_hclose(struct hvfs *hvfs) {
    struct mthrottler_sock *obj = (struct mthrottler_sock*)hvfs;
    int rc = hclose(obj->s);
    dsock_assert(rc == 0);
    free(obj);
}
示例#16
0
static coroutine void nagle_sender(int s, size_t batch, int64_t interval,
      uint8_t *buf, int sendch, int ackch) {
    /* Amount of data in the buffer. */
    size_t len = 0;
    /* Last time at least one byte was sent. */
    int64_t last = now();
    while(1) {
        /* Get data to send from the user coroutine. */
        struct nagle_vec vec;
        int rc = chrecv(sendch, &vec, sizeof(vec),
            interval >= 0 && len ? last + interval : -1);
        if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
        /* Timeout expired. Flush the data in the buffer. */
        if(dsock_slow(rc < 0 && errno == ETIMEDOUT)) {
            rc = bsend(s, buf, len, -1);
            if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
            dsock_assert(rc == 0);
            len = 0;
            last = now();
            continue;
        }
        dsock_assert(rc == 0);
        /* If data fit into the buffer, store them there. */
        size_t bytes = iov_size(vec.iov, vec.iovlen);
        if(len + bytes < batch) {
            iov_copyallfrom(buf + len, vec.iov, vec.iovlen);
            len += bytes;
            int err = 0;
            rc = chsend(ackch, &err, sizeof(err), -1);
            if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
            dsock_assert(rc == 0);
            continue;
        }
        if(len > 0) {
            /* Flush the buffer. */
            rc = bsend(s, buf, len, -1);
            if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
            /* Pass the error to the user. */
            if(dsock_slow(rc < 0)) {
                int err = errno;
                rc = chsend(ackch, &err, sizeof(err), -1);
                if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
                dsock_assert(rc == 0);
                return;
            }
            len = 0;
            last = now();
        }
        /* Once again: If data fit into buffer store them there. */
        if(bytes < batch) {
            iov_copyallfrom(buf, vec.iov, vec.iovlen);
            len = bytes;
            int err = 0;
            rc = chsend(ackch, &err, sizeof(err), -1);
            if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
            dsock_assert(rc == 0);
            continue;
        }
        /* This is a big chunk of data, no need to Nagle it.
           We'll send it straight away. */
        rc = bsendv(s, vec.iov, vec.iovlen, -1);
        if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
        dsock_assert(rc == 0);
        last = now();
        int err = 0;
        rc = chsend(ackch, &err, sizeof(err), -1);
        if(dsock_slow(rc < 0 && errno == ECANCELED)) return;
        dsock_assert(rc == 0);
    }
}