From 31e88525ae86ffb1539e2d5138576961e80e75be Mon Sep 17 00:00:00 2001 From: pantonshire Date: Sun, 19 Apr 2026 09:12:19 +0100 Subject: [PATCH] wip client --- include/client.h | 3 ++ src/client.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 85 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 170 insertions(+), 5 deletions(-) diff --git a/include/client.h b/include/client.h index afa6f49..ba42da1 100644 --- a/include/client.h +++ b/include/client.h @@ -2,7 +2,10 @@ #include +#include "str.h" + struct client_conf { + str_view_t addr; uint16_t port; }; diff --git a/src/client.c b/src/client.c index 2492172..72beed7 100644 --- a/src/client.c +++ b/src/client.c @@ -1,5 +1,92 @@ +#include +#include +#include +#include +#include + #include "client.h" +#include "io.h" +#include "str.h" +#include "util.h" + +struct client_ctx { + int fd; +}; + +static void addrinfo_cleanup(struct addrinfo **ai) { + if (*ai) + freeaddrinfo(*ai); + *ai = NULL; +} + +// static int + +static int client_init(const struct client_conf *conf, struct client_ctx *ctx) { + SB_SCOPED(addr_str); + struct addrinfo *ai_res __attribute__((cleanup(addrinfo_cleanup))) = NULL; + struct addrinfo *ai; + struct addrinfo hints; + in_port_t *port; + int addrinfo_res; + FD_SCOPED(sock_fd); + + if (sb_is_null(addr_str = sb_from_sv(conf->addr))) + FAIL("failed to alloc"); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + if ((addrinfo_res = getaddrinfo(addr_str.ptr, NULL, &hints, &ai_res))) + FAIL("failed to resolve name: %s", gai_strerror(addrinfo_res)); + + for (ai = ai_res; ai; ai = ai->ai_next) { + switch (ai->ai_family) { + case AF_INET: + port = &((struct sockaddr_in *)ai->ai_addr)->sin_port; + break; + case AF_INET6: + port = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_port; + break; + default: + port = NULL; + break; + } + + if (!port) + continue; + + *port = htons(conf->port); + + if ((sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { + LOG_ERR("failed to create socket: %s", strerror(errno)); + continue; + } + + if (setsockopt_int(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1)) { + LOG_ERR("failed to set SO_REUSEADDR: %s", strerror(errno)); + continue; + } + + // TODO: ping, connect + + printf("res family=%d\n", ai->ai_family); + } + + if (setsockopt_int(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1)) + FAIL("failed to set SO_TIMESTAMP: %s", strerror(errno)); + + ctx->fd = FD_RELEASE(&sock_fd); + + return 0; +} int client(const struct client_conf *conf) { + struct client_ctx ctx; + + if (client_init(conf, &ctx)) + FAIL("failed to create client socket"); + return 0; } diff --git a/src/main.c b/src/main.c index cae9dc1..bd325a9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,20 +1,90 @@ -#include #include -#include -#include + +#include +#include "eventloop.h" +#include "util.h" #include "server.h" #include "client.h" #include "defaults.h" +#include "str.h" + +#include +#include +#include + +#include +#include +#include + +static int ev_test(void) { + struct owd_event timer, pipe_ev; + struct owd_eventloop el; + EVENTLOOP_STACK_SCOPED(el_ptr); + owd_event_id_t id; + uint32_t flags; + + int pfds[2]; + if (pipe(pfds)) + FAIL("pipe: %s", strerror(errno)); + + pid_t pid = fork(); + if (pid < 0) + FAIL("fork: %s", strerror(errno)); + + if (!pid) { + char buf[] = "hello!"; + sleep(5); + write(pfds[1], buf, sizeof(buf)); + exit(0); + } -// #define DEFAULT_PORT 34802 + if (owd_eventloop_init(&el)) + FAIL("failed to init event loop"); + el_ptr = ⪙ + + if (owd_eventloop_add_timer(&el, &timer, 2000, false)) + FAIL("failed to add timer"); + + if (owd_eventloop_add_fd(&el, &pipe_ev, pfds[0], OWD_EVENT_READABLE)) + FAIL("failed to add fd"); + + for (;;) { + if (owd_eventloop_wait(&el, &id, &flags, NULL)) { + LOG_ERR("failed to wait"); + continue; + } + + if (owd_event_id_eq(id, timer.id)) { + owd_eventloop_clear(&el, &timer); + printf("timer tick flags=%u\n", flags); + // break; + } + else if (owd_event_id_eq(id, pipe_ev.id)) { + char buf[1024] = { 0 }; + read(pfds[0], buf, sizeof(buf) - 1); + printf("pipe event flags=%u buf=%s\n", flags, buf); + break; + } + else { + LOG_ERR("unknown id"); + } + } + + owd_eventloop_remove(&el, &timer); + owd_eventloop_remove(&el, &pipe_ev); + + return 0; +} int main(int argc, char **argv) { union { struct server_conf server; struct client_conf client; } conf; - + + return ev_test(); + if (argc < 2) return 1; @@ -23,6 +93,11 @@ int main(int argc, char **argv) { return !!server(&conf.server); } if (!strcmp(argv[1], "client")) { + // TODO: proper arg parsing + if (argc < 3) + return 1; + conf.client.addr = sv_from_cstr_unbounded(argv[2]); + conf.client.port = DEFAULT_PORT; return !!client(&conf.client); }