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;
|
|
|
|
}
|