libdiscord

libdiscord.git
git clone git://git.lenczewski.org/libdiscord.git
Log | Files | Refs | README | LICENSE

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:
Msrc/conn.c | 16+++++++++++-----
Msrc/gateway.c | 12++++++------
Msrc/internal.h | 124++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/ioreq.c | 39+++++++++++++++++++++++++++++++++------
Msrc/libdiscord.c | 4++--
Msrc/voice.c | 8++++----
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;