commit 9369de7d8bbf430bbb8b6552e776c5898250bb69
parent b0b64cb48afab868eda1690d342815db559df460
Author: MikoĊaj Lenczewski <mblenczewski@gmail.com>
Date: Fri, 20 Jun 2025 22:40:21 +0100
Refactored conn_* method signatures
Diffstat:
6 files changed, 153 insertions(+), 50 deletions(-)
diff --git a/src/conn.c b/src/conn.c
@@ -1,27 +1,33 @@
#include "internal.h"
extern inline int
-conn_queue_connect(struct io_uring *uring, struct conn *conn);
+conn_queue_connect(struct conn *conn, struct io_uring *uring);
extern inline void
conn_finish_connect(struct conn *conn, int result);
extern inline int
-conn_queue_recv(struct io_uring *uring, struct conn *conn);
+conn_queue_recv(struct conn *conn, struct io_uring *uring);
extern inline void
conn_finish_recv(struct conn *conn, int result);
extern inline int
-conn_queue_send(struct io_uring *uring, struct conn *conn);
+conn_queue_send(struct conn *conn, struct io_uring *uring);
extern inline void
conn_finish_send(struct conn *conn, int result);
extern inline int
-conn_do_tls_handshake(struct io_uring *uring, struct conn *conn,
+conn_queue_close(struct conn *conn, struct io_uring *uring);
+
+extern inline void
+conn_finish_close(struct conn *conn, int result);
+
+extern inline int
+conn_do_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
extern inline int
-conn_handle_io(struct io_uring *uring, struct conn *conn, int result,
+conn_handle_io(struct conn *conn, struct io_uring *uring, int result,
struct discord_event *ev);
diff --git a/src/gateway.c b/src/gateway.c
@@ -1,7 +1,7 @@
#include "internal.h"
int
-gateway_connect(struct io_uring *uring, struct conn *conn,
+gateway_connect(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
if (conn->socket < 0 && !conn->ai_ptr->ai_next) {
@@ -11,7 +11,7 @@ gateway_connect(struct io_uring *uring, struct conn *conn,
if (conn->socket < 0 && conn->ai_ptr->ai_next) {
conn->ai_ptr = conn->ai_ptr->ai_next;
- return conn_queue_connect(uring, conn);
+ return conn_queue_connect(conn, uring);
}
char host[NI_MAXHOST], serv[NI_MAXSERV];
@@ -22,11 +22,11 @@ gateway_connect(struct io_uring *uring, struct conn *conn,
freeaddrinfo(conn->addrinfo);
- return conn_do_tls_handshake(uring, conn, ev);
+ return conn_do_tls_handshake(conn, uring, ev);
}
int
-gateway_tls_handshake(struct io_uring *uring, struct conn *conn,
+gateway_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
printf("discord: connected over tls\n");
@@ -35,14 +35,14 @@ gateway_tls_handshake(struct io_uring *uring, struct conn *conn,
}
int
-gateway_recv(struct io_uring *uring, struct conn *conn,
+gateway_recv(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;
}
int
-gateway_send(struct io_uring *uring, struct conn *conn,
+gateway_send(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;
diff --git a/src/internal.h b/src/internal.h
@@ -32,6 +32,15 @@ struct ioreq_recv {
int flags;
};
+struct ioreq_recvfrom {
+ int fd;
+ void *buf;
+ size_t len;
+ int flags;
+ struct sockaddr *addr;
+ socklen_t addrlen;
+};
+
struct ioreq_send {
int fd;
void *buf;
@@ -39,16 +48,41 @@ struct ioreq_send {
int flags;
};
+struct ioreq_sendto {
+ int fd;
+ void *buf;
+ size_t len;
+ int flags;
+ struct sockaddr *addr;
+ socklen_t addrlen;
+};
+
+struct ioreq_close {
+ int fd;
+};
+
union ioreq_tag {
struct ioreq_connect connect;
struct ioreq_recv recv;
+ struct ioreq_recvfrom recvfrom;
struct ioreq_send send;
+ struct ioreq_sendto sendto;
+ struct ioreq_close close;
};
struct conn;
+enum ioreq_type {
+ IOREQ_CONNECT,
+ IOREQ_RECV,
+ IOREQ_RECVFROM,
+ IOREQ_SEND,
+ IOREQ_SENDTO,
+ IOREQ_CLOSE,
+};
+
struct ioreq {
- enum { IOREQ_CONNECT, IOREQ_RECV, IOREQ_SEND, } type;
+ enum ioreq_type type;
union ioreq_tag tag;
};
@@ -56,16 +90,16 @@ int
queue_ioreqs(struct io_uring *uring, struct ioreq *reqs, size_t len);
struct conn_ops {
- int (*connect)(struct io_uring *uring, struct conn *conn,
+ int (*connect)(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
- int (*tls_handshake)(struct io_uring *uring, struct conn *conn,
+ int (*tls_handshake)(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
- int (*send)(struct io_uring *uring, struct conn *conn,
+ int (*recv)(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
- int (*recv)(struct io_uring *uring, struct conn *conn,
+ int (*send)(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
};
@@ -85,10 +119,10 @@ struct conn {
};
inline int
-conn_queue_connect(struct io_uring *uring, struct conn *conn)
+conn_queue_connect(struct conn *conn, struct io_uring *uring)
{
int sock = socket(conn->ai_ptr->ai_family,
- conn->ai_ptr->ai_socktype | SOCK_NONBLOCK,
+ conn->ai_ptr->ai_socktype,
conn->ai_ptr->ai_protocol);
if (sock < 0)
return -1;
@@ -119,12 +153,13 @@ conn_finish_connect(struct conn *conn, int result)
}
inline int
-conn_queue_recv(struct io_uring *uring, struct conn *conn)
+conn_queue_recv(struct conn *conn, struct io_uring *uring)
{
char *buf;
int len = BIO_nwrite0(conn->net_bio, &buf);
conn->ioreq.type = IOREQ_RECV;
+ conn->ioreq.tag.recv.fd = conn->socket;
conn->ioreq.tag.recv.buf = buf;
conn->ioreq.tag.recv.len = len;
conn->ioreq.tag.recv.flags = 0;
@@ -143,12 +178,13 @@ conn_finish_recv(struct conn *conn, int result)
}
inline int
-conn_queue_send(struct io_uring *uring, struct conn *conn)
+conn_queue_send(struct conn *conn, struct io_uring *uring)
{
char *buf;
int len = BIO_nread0(conn->net_bio, &buf);
conn->ioreq.type = IOREQ_SEND;
+ conn->ioreq.tag.send.fd = conn->socket;
conn->ioreq.tag.send.buf = buf;
conn->ioreq.tag.send.len = len;
conn->ioreq.tag.send.flags = 0;
@@ -167,12 +203,29 @@ conn_finish_send(struct conn *conn, int result)
}
inline int
-conn_do_tls_handshake(struct io_uring *uring, struct conn *conn,
+conn_queue_close(struct conn *conn, struct io_uring *uring)
+{
+ conn->ioreq.type = IOREQ_CLOSE;
+ conn->ioreq.tag.close.fd = conn->socket;
+
+ printf("discord: closing socket\n");
+
+ return queue_ioreqs(uring, &conn->ioreq, 1);
+}
+
+inline void
+conn_finish_close(struct conn *conn, int result)
+{
+ printf("discord: closed socket\n");
+}
+
+inline int
+conn_do_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
int ret = SSL_do_handshake(conn->ssl);
if (ret == 1) /* handshake completed */
- return conn->ops->tls_handshake(uring, conn, ev);
+ return conn->ops->tls_handshake(conn, uring, ev);
if (ret == 0) /* connection closed */
return -1;
@@ -183,11 +236,11 @@ conn_do_tls_handshake(struct io_uring *uring, struct conn *conn,
int pending = BIO_ctrl_pending(conn->net_bio);
if (pending) /* need to send bytes to advance handshake */
- return conn_queue_send(uring, conn);
+ return conn_queue_send(conn, uring);
int expecting = BIO_ctrl_get_read_request(conn->net_bio);
if (expecting) /* need to recv bytes to advance handshake */
- return conn_queue_recv(uring, conn);
+ return conn_queue_recv(conn, uring);
error:
fprintf(stderr, "discord: failed to complete tls handshake: %d\n", err);
@@ -196,32 +249,49 @@ error:
}
inline int
-conn_handle_io(struct io_uring *uring, struct conn *conn, int result,
+conn_handle_io(struct conn *conn, struct io_uring *uring, int result,
struct discord_event *ev)
{
switch (conn->ioreq.type) {
case IOREQ_CONNECT: {
conn_finish_connect(conn, result);
- return conn->ops->connect(uring, conn, ev);
+ return conn->ops->connect(conn, uring, ev);
} break;
case IOREQ_RECV: {
conn_finish_recv(conn, result);
if (!SSL_is_init_finished(conn->ssl))
- return conn_do_tls_handshake(uring, conn, ev);
+ return conn_do_tls_handshake(conn, uring, ev);
+
+ return conn->ops->recv(conn, uring, ev);
+ } break;
- return conn->ops->recv(uring, conn, ev);
+ case IOREQ_RECVFROM: {
+ // TODO: simply use connect() + recv() for UDP?
+ assert(0);
+ return 0;
} break;
case IOREQ_SEND: {
conn_finish_send(conn, result);
if (!SSL_is_init_finished(conn->ssl))
- return conn_do_tls_handshake(uring, conn, ev);
+ return conn_do_tls_handshake(conn, uring, ev);
+
+ return conn->ops->send(conn, uring, ev);
+ } break;
+
+ case IOREQ_SENDTO: {
+ // TODO: simply use connect() + send() for UDP?
+ assert(0);
+ return 0;
+ } break;
- return conn->ops->send(uring, conn, ev);
+ case IOREQ_CLOSE: {
+ conn_finish_close(conn, result);
+ return 0;
} break;
}
}
@@ -259,35 +329,35 @@ struct discord {
};
int
-gateway_connect(struct io_uring *uring, struct conn *conn,
+gateway_connect(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-gateway_tls_handshake(struct io_uring *uring, struct conn *conn,
+gateway_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-gateway_recv(struct io_uring *uring, struct conn *conn,
+gateway_recv(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-gateway_send(struct io_uring *uring, struct conn *conn,
+gateway_send(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-voice_connect(struct io_uring *uring, struct conn *conn,
+voice_connect(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-voice_tls_handshake(struct io_uring *uring, struct conn *conn,
+voice_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-voice_recv(struct io_uring *uring, struct conn *conn,
+voice_recv(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
int
-voice_send(struct io_uring *uring, struct conn *conn,
+voice_send(struct conn *conn, struct io_uring *uring,
struct discord_event *ev);
#endif /* INTERNAL_H */
diff --git a/src/ioreq.c b/src/ioreq.c
@@ -18,21 +18,48 @@ queue_ioreqs(struct io_uring *uring, struct ioreq *reqs, size_t len)
ioreq->tag.connect.addrlen);
break;
- case IOREQ_SEND:
- io_uring_prep_send(sqe,
- ioreq->tag.send.fd,
+ case IOREQ_RECV:
+ io_uring_prep_recv(sqe,
+ ioreq->tag.recv.fd,
ioreq->tag.recv.buf,
ioreq->tag.recv.len,
ioreq->tag.recv.flags);
break;
- case IOREQ_RECV:
- io_uring_prep_recv(sqe,
- ioreq->tag.recv.fd,
+ case IOREQ_RECVFROM:
+#if 0
+ io_uring_prep_recvfrom(sqe,
+ ioreq->tag.recvfrom.fd,
+ ioreq->tag.recvfrom.buf,
+ ioreq->tag.recvfrom.len,
+ ioreq->tag.recvfrom.flags,
+ ioreq->tag.recvfrom.addr,
+ ioreq->tag.recvfrom.addrlen);
+#endif
+ break;
+
+ case IOREQ_SEND:
+ io_uring_prep_send(sqe,
+ ioreq->tag.send.fd,
ioreq->tag.recv.buf,
ioreq->tag.recv.len,
ioreq->tag.recv.flags);
break;
+
+ case IOREQ_SENDTO:
+ io_uring_prep_sendto(sqe,
+ ioreq->tag.sendto.fd,
+ ioreq->tag.sendto.buf,
+ ioreq->tag.sendto.len,
+ ioreq->tag.sendto.flags,
+ ioreq->tag.sendto.addr,
+ ioreq->tag.sendto.addrlen);
+ break;
+
+ case IOREQ_CLOSE:
+ io_uring_prep_close(sqe,
+ ioreq->tag.close.fd);
+ break;
}
io_uring_sqe_set_data(sqe, ioreq);
diff --git a/src/libdiscord.c b/src/libdiscord.c
@@ -128,7 +128,7 @@ discord_connect_gateway(struct discord *ctx)
conn->ops = &gateway_ops;
- return conn_queue_connect(&ctx->io_uring, conn);
+ return conn_queue_connect(conn, &ctx->io_uring);
}
int
@@ -158,7 +158,7 @@ discord_poll_events(struct discord *ctx,
struct conn,
ioreq);
- ret = conn_handle_io(&ctx->io_uring, conn,
+ ret = conn_handle_io(conn, &ctx->io_uring,
cqe->res, evs);
seen++;
diff --git a/src/voice.c b/src/voice.c
@@ -1,28 +1,28 @@
#include "internal.h"
int
-voice_connect(struct io_uring *uring, struct conn *conn,
+voice_connect(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;
}
int
-voice_tls_handshake(struct io_uring *uring, struct conn *conn,
+voice_tls_handshake(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;
}
int
-voice_recv(struct io_uring *uring, struct conn *conn,
+voice_recv(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;
}
int
-voice_send(struct io_uring *uring, struct conn *conn,
+voice_send(struct conn *conn, struct io_uring *uring,
struct discord_event *ev)
{
return -1;