summaryrefslogtreecommitdiff
path: root/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils.c')
-rw-r--r--utils.c430
1 files changed, 0 insertions, 430 deletions
diff --git a/utils.c b/utils.c
deleted file mode 100644
index eacc586..0000000
--- a/utils.c
+++ /dev/null
@@ -1,430 +0,0 @@
-#include <stdlib.h>
-#include <errno.h>
-#include <stdint.h>
-#include <limits.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <inttypes.h>
-
-#include "main.h"
-#include "utils.h"
-#include "uring.h"
-
-static unsigned total_malloc_count = 0;
-static int malloc_count = 0;
-
-LIST_HEAD(malloc_list);
-
-struct allocation {
- const char *allocfn;
- const char *callerfn;
- int line;
- void *ptr;
- size_t size;
- struct list_head list;
-};
-
-static void
-add_allocation(const char *allocfn, const char *callerfn, int line, void *ptr, size_t size)
-{
- struct allocation *a;
-
- assert_die(!empty_str(allocfn) && !empty_str(callerfn) && line > 0 && ptr && size > 0, "invalid arguments");
-
- a = malloc(sizeof(*a));
- if (!a)
- die("malloc: %m");
- a->allocfn = allocfn;
- a->callerfn = callerfn;
- a->line = line;
- a->ptr = ptr;
- a->size = size;
- list_add(&a->list, &malloc_list);
- total_malloc_count++;
- malloc_count++;
- debug(DBG_MALLOC, "called from %s:%i - %s(%zu) = %p (%p)",
- callerfn, line, allocfn, size, ptr, a);
-}
-
-void *
-__zmalloc(const char *fn, int line, size_t size)
-{
- void *ptr;
-
- assert_die(!empty_str(fn) && line > 0 && size > 0, "invalid arguments");
-
- ptr = calloc(1, size);
- if (ptr)
- add_allocation("zmalloc", fn, line, ptr, size);
- return ptr;
-}
-
-char *
-__xstrdup(const char *fn, int line, const char *s)
-{
- char *ptr;
-
- assert_die(!empty_str(fn) && line > 0 && !empty_str(s), "invalid arguments");
-
- ptr = strdup(s);
- if (ptr)
- add_allocation("xstrdup", fn, line, ptr, strlen(s) + 1);
- return ptr;
-}
-
-char *
-__xstrndup(const char *fn, int line, const char *s, size_t n)
-{
- char *ptr;
-
- assert_die(!empty_str(fn) && line > 0 && !empty_str(s) && n > 0, "invalid arguments");
-
- ptr = strndup(s, n);
- if (ptr)
- add_allocation("xstrndup", fn, line, ptr, n);
- return ptr;
-}
-
-void
-__xfree(const char *fn, int line, void *ptr)
-{
- struct allocation *a, *tmp;
- unsigned delete_count = 0;
-
- assert_die(!empty_str(fn) && line > 0, "invalid arguments");
-
- if (!ptr)
- return;
- free(ptr);
- malloc_count--;
-
- debug(DBG_MALLOC, "called from %s:%i - %p", fn, line, ptr);
-
- list_for_each_entry_safe(a, tmp, &malloc_list, list) {
- if (a->ptr == ptr) {
- list_del(&a->list);
- free(a);
- delete_count++;
- }
- }
-
- if (delete_count != 1) {
- error("Delete count is %u for ptr 0x%p", delete_count, ptr);
- exit(EXIT_FAILURE);
- }
-}
-
-void
-debug_resource_usage()
-{
- struct allocation *a;
- DIR *dir;
- struct dirent *dent;
- char buf[4096];
- ssize_t r;
- unsigned file_count = 0;
-
- debug(DBG_MALLOC, "Still malloced %i (total %u)",
- malloc_count, total_malloc_count);
-
- list_for_each_entry(a, &malloc_list, list) {
- debug(DBG_MALLOC, "* Lost allocation - %s:%i - ptr: %p, size: %zu",
- a->callerfn, a->line, a->ptr, a->size);
- }
-
- dir = opendir("/proc/self/fd");
- if (!dir) {
- error("failed to open fd dir");
- return;
- }
-
- debug(DBG_MALLOC, "Open files:");
- while ((dent = readdir(dir)) != NULL) {
- if (streq(dent->d_name, ".") || streq(dent->d_name, ".."))
- continue;
-
- r = readlinkat(dirfd(dir), dent->d_name, buf, sizeof(buf));
- if (r < 0) {
- debug(DBG_MALLOC, "Failed to readlink %s", dent->d_name);
- continue;
- }
- buf[r] = '\0';
- debug(DBG_MALLOC, " * %s -> %s", dent->d_name, buf);
- file_count++;
- }
- closedir(dir);
-
- if (file_count > 4)
- debug(DBG_MALLOC, "Lost file descriptor(s)");
-
- debug(DBG_MALLOC, "CQEs used: %" PRIu64 ", SQEs used: %" PRIu64,
- cqe_count, sqe_count);
-}
-
-void
-socket_set_low_latency(int sfd)
-{
- int option;
-
- assert_return(sfd >= 0);
-
- /* Probably not necessary, but can't hurt */
- if (cfg->socket_defer) {
- option = true;
- if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
- }
-
- /* Doubtful if it has much effect, but can't hurt */
- if (cfg->socket_iptos) {
- option = IPTOS_LOWDELAY;
- if (setsockopt(sfd, IPPROTO_IP, IP_TOS, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
- }
-
- /* Nagle's algorithm is a poor fit for gaming */
- if (cfg->socket_nodelay) {
- option = true;
- if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, &option, sizeof(option)) < 0)
- error("setsockopt: %m");
- }
-}
-
-void
-connection_set_local(struct connection *conn, int fd)
-{
- assert_return(conn && fd >= 0);
-
- conn->local.addrlen = sizeof(conn->local.storage);
- if (getsockname(fd, (struct sockaddr *)&conn->local.storage,
- &conn->local.addrlen) < 0)
- sprintf(conn->local.addrstr, "<unknown>");
- else
- saddr_set_addrstr(&conn->local);
-}
-
-void
-connection_set_remote(struct connection *conn, struct saddr *remote)
-{
- assert_return(conn && remote);
-
- conn->remote = *remote;
- saddr_set_addrstr(&conn->remote);
-}
-
-static void connect_next(struct uring_task *task, struct connection *conn);
-
-static void
-connect_cb(struct uring_task *task, int res)
-{
- struct connection *conn;
-
- assert_return(task && task->priv);
-
- conn = task->priv;
- if (res < 0) {
- debug(DBG_SRV, "%s: connection to %s failed",
- task->name, conn->remote.addrstr);
- uring_task_close_fd(task);
- connect_next(task, conn);
- return;
- }
-
- connection_set_local(conn, task->fd);
-
- debug(DBG_SRV, "%s: connection established %s -> %s",
- task->name, conn->local.addrstr, conn->remote.addrstr);
-
- conn->cb(conn, true);
-}
-
-static void
-connect_next(struct uring_task *task, struct connection *conn)
-{
- struct saddr *remote, *tmp;
- int sfd;
- unsigned i;
-
- assert_return(task && conn && conn->cb);
-again:
- assert_task_alive_or(DBG_UR, task, goto out);
-
- i = 0;
- remote = NULL;
- list_for_each_entry(tmp, conn->addrs, list) {
- if (i == conn->next_addr) {
- remote = tmp;
- break;
- }
- i++;
- }
-
- if (!remote) {
- debug(DBG_SRV, "%s: no more remote addresses to attempt",
- task->name);
- goto out;
- }
-
- conn->next_addr++;
- connection_set_remote(conn, remote);
- debug(DBG_SRV, "%s: attempting to connect to %s",
- task->name, conn->remote.addrstr);
-
- sfd = socket(conn->remote.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (sfd < 0) {
- error("socket: %m");
- goto again;
- }
-
- socket_set_low_latency(sfd);
-
- task->priv = conn;
- uring_task_set_fd(task, sfd);
- uring_connect(task, &conn->remote, connect_cb);
- return;
-
-out:
- conn->cb(conn, false);
-}
-
-void
-connect_any(struct uring_task *task,
- struct list_head *addrs, struct connection *conn,
- connection_cb_t cb)
-{
- assert_return(task && addrs && conn && cb);
-
- conn->next_addr = 0;
- conn->addrs = addrs;
- conn->cb = cb;
- connect_next(task, conn);
-}
-
-uint16_t
-saddr_port(struct saddr *saddr)
-{
- assert_return(saddr, 0);
-
- switch (saddr->storage.ss_family) {
- case AF_INET:
- return ntohs(saddr->in4.sin_port);
- case AF_INET6:
- return ntohs(saddr->in6.sin6_port);
- default:
- return 0;
- }
-}
-
-char *
-saddr_addr(struct saddr *saddr, char *buf, size_t len)
-{
- assert_return(saddr && buf && len > 0, NULL);
-
- switch (saddr->storage.ss_family) {
- case AF_INET:
- if (inet_ntop(saddr->in4.sin_family, &saddr->in4.sin_addr, buf, len))
- return buf;
- break;
- case AF_INET6:
- if (inet_ntop(saddr->in6.sin6_family, &saddr->in6.sin6_addr, buf, len))
- return buf;
- break;
- default:
- break;
- }
-
- snprintf(buf, len, "<unknown>");
- return buf;
-}
-
-void
-saddr_set_ipv4(struct saddr *saddr, in_addr_t ip, in_port_t port)
-{
- assert_return(saddr);
-
- memset(&saddr->in4, 0, sizeof(saddr->in4));
- saddr->in4.sin_family = AF_INET;
- saddr->in4.sin_port = port;
- saddr->in4.sin_addr.s_addr = ip;
- saddr->addrlen = sizeof(saddr->in4);
- saddr_set_addrstr(saddr);
-}
-
-void
-saddr_set_ipv6(struct saddr *saddr, const struct in6_addr *ip, in_port_t port)
-{
- assert_return(saddr && ip);
-
- memset(&saddr->in6, 0, sizeof(saddr->in6));
- saddr->in6.sin6_family = AF_INET6;
- saddr->in6.sin6_port = port;
- if (ip)
- saddr->in6.sin6_addr = *ip;
- saddr->addrlen = sizeof(saddr->in6);
- saddr_set_addrstr(saddr);
-}
-
-void
-saddr_set_addrstr(struct saddr *saddr)
-{
- assert_return(saddr);
-
- char abuf[ADDRSTRLEN];
-
- switch (saddr->storage.ss_family) {
- case AF_INET:
- snprintf(saddr->addrstr, sizeof(saddr->addrstr),
- "AF_INET4 %s %" PRIu16,
- saddr_addr(saddr, abuf, sizeof(abuf)),
- saddr_port(saddr));
- break;
- case AF_INET6:
- snprintf(saddr->addrstr, sizeof(saddr->addrstr),
- "AF_INET6 %s %" PRIu16,
- saddr_addr(saddr, abuf, sizeof(abuf)),
- saddr_port(saddr));
- break;
- default:
- snprintf(saddr->addrstr, sizeof(saddr->addrstr), "AF_UNKNOWN");
- break;
- }
-}
-
-int
-strtou16_strict(const char *str, uint16_t *result)
-{
- char *end;
- long val;
-
- assert_return(!empty_str(str) && result, -EINVAL);
-
- errno = 0;
- val = strtol(str, &end, 10);
-
- if (errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
- return -EINVAL;
-
- if (errno != 0 && val == 0)
- return -EINVAL;
-
- if (end == str)
- return -EINVAL;
-
- if (*end != '\0')
- return -EINVAL;
-
- if (val < 1 || val > UINT16_MAX)
- return -EINVAL;
-
- if (result)
- *result = val;
- return 0;
-}
-