ssize_t udp_recv(int s, struct ipaddr *addr, void *buf, size_t len, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; struct iolist iol = {(void*)buf, len, NULL, 0}; return udp_recvl_(m, addr, &iol, &iol, deadline); }
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; }
int mthrottler_stop(int s) { struct mthrottler_sock *obj = hquery(s, mthrottler_type); if(dsock_slow(!obj)) return -1; int u = obj->s; free(obj); return u; }
int msendl(int s, struct iolist *first, struct iolist *last, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; if(dill_slow(!first || !last || last->iol_next)) { errno = EINVAL; return -1;} return m->msendl(m, first, last, deadline); }
ssize_t mrecvl(int s, struct iolist *first, struct iolist *last, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; if(dill_slow((last && last->iol_next) || (!first && last) || (first && !last))) { errno = EINVAL; return -1;} return m->mrecvl(m, first, last, deadline); }
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; }
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; }
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; }
int mthrottler_start(int s, uint64_t send_throughput, int64_t send_interval, uint64_t recv_throughput, int64_t recv_interval) { if(dsock_slow(send_throughput != 0 && send_interval <= 0 )) { errno = EINVAL; return -1;} if(dsock_slow(recv_throughput != 0 && recv_interval <= 0 )) { errno = EINVAL; return -1;} /* Check whether underlying socket is message-based. */ if(dsock_slow(!hquery(s, msock_type))) return -1; /* Create the object. */ struct mthrottler_sock *obj = malloc(sizeof(struct mthrottler_sock)); if(dsock_slow(!obj)) {errno = ENOMEM; return -1;} obj->hvfs.query = mthrottler_hquery; obj->hvfs.close = mthrottler_hclose; obj->mvfs.msendv = mthrottler_msendv; obj->mvfs.mrecvv = mthrottler_mrecvv; obj->s = s; obj->send_full = 0; if(send_throughput > 0) { obj->send_full = send_throughput * send_interval / 1000; obj->send_remaining = obj->send_full; obj->send_interval = send_interval; obj->send_last = now(); } obj->recv_full = 0; if(recv_throughput > 0) { obj->recv_full = recv_throughput * recv_interval / 1000; obj->recv_remaining = obj->recv_full; obj->recv_interval = recv_interval; obj->recv_last = now(); } /* Create the handle. */ int h = hcreate(&obj->hvfs); if(dsock_slow(h < 0)) { int err = errno; free(obj); errno = err; return -1; } return h; }
ssize_t udp_recvl(int s, struct ipaddr *addr, struct iolist *first, struct iolist *last, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; return udp_recvl_(m, addr, first, last, deadline); }
int udp_sendl(int s, const struct ipaddr *addr, struct iolist *first, struct iolist *last) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; return udp_sendl_(m, addr, first, last); }
int udp_send(int s, const struct ipaddr *addr, const void *buf, size_t len) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; struct iolist iol = {(void*)buf, len, NULL, 0}; return udp_sendl_(m, addr, &iol, &iol); }
ssize_t mrecv(int s, void *buf, size_t len, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; struct iolist iol = {buf, len, NULL, 0}; return m->mrecvl(m, &iol, &iol, deadline); }
int msend(int s, const void *buf, size_t len, int64_t deadline) { struct msock_vfs *m = hquery(s, msock_type); if(dill_slow(!m)) return -1; struct iolist iol = {(void*)buf, len, NULL, 0}; return m->msendl(m, &iol, &iol, deadline); }