ppd/common/io.cc

195 lines
3.6 KiB
C++
Raw Normal View History

2023-01-17 20:22:43 +00:00
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <stdio.h>
#include <unistd.h>
2023-03-02 14:12:35 +00:00
#include <bsock/bsock.h>
2023-01-17 20:22:43 +00:00
#include "logger.h"
#include "msg.h"
2023-02-24 23:25:52 +00:00
#include "io.h"
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
#include <algorithm>
2023-01-17 20:22:43 +00:00
#include <cerrno>
2023-01-18 00:24:49 +00:00
static ssize_t
ppd_read_ssl(void * _ctx, void *buf, size_t len)
2023-01-17 20:22:43 +00:00
{
2023-01-18 00:24:49 +00:00
struct ppd_bsock_io_ssl_ctx * ctx = (struct ppd_bsock_io_ssl_ctx *)_ctx;
int status = SSL_read(ctx->ssl, buf, len);
if (status > 0) {
return status;
}
errno = SSL_get_error(ctx->ssl, status);
return -1;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
static ssize_t
ppd_write_ssl(void * _ctx, void *buf, size_t len)
2023-01-17 20:22:43 +00:00
{
2023-01-18 00:24:49 +00:00
struct ppd_bsock_io_ssl_ctx * ctx = (struct ppd_bsock_io_ssl_ctx *)_ctx;
int status = SSL_write(ctx->ssl, buf, len);
if (status > 0) {
return status;
}
errno = SSL_get_error(ctx->ssl, status);
return -1;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
static ssize_t
ppd_readv_ssl(void * _ctx, const struct iovec * vec, int nvec)
2023-01-17 20:22:43 +00:00
{
2023-01-18 00:24:49 +00:00
struct ppd_bsock_io_ssl_ctx * ctx = (struct ppd_bsock_io_ssl_ctx *)_ctx;
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
size_t total_sz = 0;
for(int i = 0; i < nvec; i++) {
total_sz += (vec + i)->iov_len;
}
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
if (total_sz > ctx->ssl_readbuf_len) {
total_sz = ctx->ssl_readbuf_len;
}
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
int read_size = SSL_read(ctx->ssl, ctx->ssl_readbuf, total_sz);
if (read_size <= 0) {
errno = SSL_get_error(ctx->ssl, read_size);
return -1;
}
int copied = 0;
for (int i = 0; i < nvec; i++) {
int cur_cpy = std::min((int)vec[i].iov_len, read_size - copied);
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
memcpy(vec[i].iov_base, ctx->ssl_readbuf + copied, cur_cpy);
copied += cur_cpy;
if (copied == read_size) {
break;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
}
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
return read_size;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
static ssize_t
ppd_writev_ssl(void * _ctx, const struct iovec * vec, int nvec)
2023-01-17 20:22:43 +00:00
{
2023-01-18 00:24:49 +00:00
struct ppd_bsock_io_ssl_ctx * ctx = (struct ppd_bsock_io_ssl_ctx *)_ctx;
int copied = 0;
for(int i = 0; i < nvec; i++) {
int len = (vec + i)->iov_len;
int cur_copy = std::min(len, (int)ctx->ssl_readbuf_len - copied);
memcpy(ctx->ssl_readbuf + copied, vec->iov_base, len);
copied += cur_copy;
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
if (copied == (int)ctx->ssl_readbuf_len) {
break;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
}
int write_size = SSL_write(ctx->ssl, ctx->ssl_readbuf, copied);
if (write_size <= 0) {
errno = SSL_get_error(ctx->ssl, write_size);
return -1;
}
return write_size;
}
2023-01-17 20:22:43 +00:00
2023-01-18 00:24:49 +00:00
struct bsock_ringbuf_io ppd_bsock_io_ssl()
{
struct bsock_ringbuf_io io;
io.read = &ppd_read_ssl;
io.readv = &ppd_readv_ssl;
io.write = &ppd_write_ssl;
io.writev = &ppd_writev_ssl;
return io;
2023-01-17 20:22:43 +00:00
}
int
2023-01-18 00:24:49 +00:00
ppd_readmsg(struct bsock * bsock, char *buf, size_t len)
2023-01-17 20:22:43 +00:00
{
int status;
struct ppd_msg *msg = (struct ppd_msg *)buf;
if (len < sizeof(struct ppd_msg)) {
2023-01-18 00:24:49 +00:00
errno = EOVERFLOW;
return -1;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
status = bsock_peek(bsock, buf, sizeof(struct ppd_msg));
2023-01-17 20:22:43 +00:00
if (status != 0) {
return status;
}
int sz = ntohl(msg->size);
if (sz > (int)len) {
2023-01-18 00:24:49 +00:00
errno = EOVERFLOW;
return -1;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
status = bsock_read(bsock, buf, sizeof(struct ppd_msg) + sz);
if (status != 0) {
return status;
2023-01-17 20:22:43 +00:00
}
2023-01-18 00:24:49 +00:00
msg->size = sz;
2023-01-17 20:22:43 +00:00
return status;
}
int
2023-01-18 00:24:49 +00:00
ppd_writemsg(struct bsock * bsock, struct ppd_msg *msg)
2023-01-17 20:22:43 +00:00
{
int status;
int sz = msg->size;
msg->size = htonl(msg->size);
2023-01-18 00:24:49 +00:00
return bsock_write(bsock, (char *)msg, sizeof(struct ppd_msg) + sz);
2023-01-17 20:22:43 +00:00
}
2023-03-02 14:12:35 +00:00
int
ppd_readbuf(int fd, void *buf, int len)
{
int status;
while (len > 0) {
if ((status = recv(fd, buf, len, 0)) > 0) {
buf = (char *)buf + status;
len -= status;
} else if (status == 0) {
errno = ECONNRESET;
return -1;
} else {
if (errno != EINTR) {
return -1;
}
}
};
return 0;
}
int
ppd_writebuf(int fd, void *buf, int len)
{
int status;
while (len > 0) {
if ((status = send(fd, buf, len, 0)) > 0) {
buf = (char *)buf + status;
len -= status;
} else if (status == 0) {
errno = ECONNRESET;
return -1;
} else {
return -1;
}
};
return 0;
}