commit ecce6b940e918db6d82a54b2d907a58fe026ae28
parent f2346770fa90085f1cf6b3e2409f05cd6d649a75
Author: Yersa Nordman <yersa@finwo.nl>
Date: Thu, 27 Jul 2023 20:23:57 +0200
Track all connections from listen in doubly-linked-list ; update callbacks to have event structs
Diffstat:
3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/src/fnet.c b/src/fnet.c
@@ -21,6 +21,8 @@ extern "C" {
struct fnet_internal_t {
struct fnet_t ext; // KEEP AT TOP, allows casting between fnet_internal_t* and fnet_t*
+ void *prev;
+ void *next;
FNET_SOCKET *fds;
int nfds;
FNET_FLAG flags;
@@ -29,6 +31,8 @@ struct fnet_internal_t {
FNET_CALLBACK(onClose);
};
+struct fnet_internal_t *connections = NULL;
+
int settcpnodelay(int fd) {
return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &(int){1}, sizeof(int));
}
@@ -79,6 +83,11 @@ struct fnet_t * fnet_listen(const char *address, uint16_t port, const struct fne
conn->nfds = 0;
conn->fds = NULL;
+ // Aanndd add to the connection tracking list
+ conn->next = connections;
+ if (connections) connections->prev = conn;
+ connections = conn;
+
/* struct sockaddr_in servaddr; */
struct addrinfo hints = {}, *addrs;
char port_str[6] = {};
@@ -109,6 +118,7 @@ struct fnet_t * fnet_listen(const char *address, uint16_t port, const struct fne
if (!conn->fds) {
fprintf(stderr, "%s\n", strerror(ENOMEM));
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
@@ -119,30 +129,35 @@ struct fnet_t * fnet_listen(const char *address, uint16_t port, const struct fne
if (fd < 0) {
fprintf(stderr, "socket\n");
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0) {
fprintf(stderr, "setsockopt(SO_REUSEADDR)\n");
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
if (setnonblock(fd) < 0) {
fprintf(stderr, "setnonblock\n");
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
if (bind(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) < 0) {
fprintf(stderr, "bind\n");
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
if (listen(fd, SOMAXCONN) < 0) {
fprintf(stderr, "bind\n");
fnet_free((struct fnet_t *)conn);
+ freeaddrinfo(addrs);
return NULL;
}
@@ -151,7 +166,6 @@ struct fnet_t * fnet_listen(const char *address, uint16_t port, const struct fne
}
freeaddrinfo(addrs);
-
return conn;
}
@@ -236,6 +250,11 @@ FNET_RETURNCODE fnet_free(struct fnet_t *connection) {
return FNET_RETURNCODE_MISSING_ARGUMENT;
}
+ // Remove ourselves from the linked list
+ if (conn->next) conn->next->prev = conn->prev;
+ if (conn->prev) conn->prev->next = conn->next;
+ if (conn == connections) connections = conn->next;
+
// TODO: check if the connections are closed?
if (conn->fds) free(conn->fds);
diff --git a/src/fnet.h b/src/fnet.h
@@ -26,8 +26,12 @@ extern "C" {
#define FNET_STATUS_ERROR 4
#define FNET_STATUS_CLOSED 8
-#define FNET_CALLBACK(NAME) void (*(NAME))(struct fnet_t *connection, void *udata)
-#define FNET_CALLBACK_VA(NAME, ...) void (*(NAME))(struct fnet_t *connection, __VA_ARGS__, void *udata)
+#define FNET_EVENT int
+#define FNET_EVENT_CONNECT 1
+#define FNET_EVENT_DATA 2
+#define FNET_EVENT_CLOSE 3
+
+#define FNET_CALLBACK(NAME) void (*(NAME))(struct fnet_ev *event)
struct fnet_t {
FNET_PROTOCOL proto;
@@ -35,11 +39,18 @@ struct fnet_t {
void *udata;
};
+struct fnet_ev {
+ struct fnet_t *connection;
+ FNET_EVENT type;
+ struct buf *buffer;
+ void *udata;
+};
+
struct fnet_options_t {
FNET_PROTOCOL proto;
FNET_FLAG flags;
FNET_CALLBACK(onConnect);
- FNET_CALLBACK_VA(onData, struct buf *data);
+ FNET_CALLBACK(onData);
FNET_CALLBACK(onClose);
void *udata;
};
diff --git a/test.c b/test.c
@@ -5,9 +5,6 @@
#include "fnet.h"
int main() {
- uint16_t us = 1337;
- /* uint32_t ui = 1337; */
-
const struct fnet_options_t opts = {
.proto = FNET_PROTO_TCP,
.flags = 0,
@@ -19,10 +16,10 @@ int main() {
struct fnet_t *conn = fnet_listen("::", 1337, &opts);
+ printf("p: %p\n", conn);
+
sleep(3600);
- printf("d: %d\n", us);
- printf("h: %i\n", us);
return 42;
}