diff options
| -rw-r--r-- | idle.c | 2 | ||||
| -rw-r--r-- | main.h | 1 | ||||
| -rw-r--r-- | proxy.c | 61 | ||||
| -rw-r--r-- | proxy.h | 1 | ||||
| -rw-r--r-- | rcon.c | 2 | ||||
| -rw-r--r-- | server.c | 2 | ||||
| -rw-r--r-- | utils.c | 94 | ||||
| -rw-r--r-- | utils.h | 101 | 
8 files changed, 167 insertions, 97 deletions
@@ -361,7 +361,7 @@ again:                  goto again;          } -	socket_set_gaming_options(cfg, sfd); +	socket_set_low_latency(cfg, sfd);          uring_task_set_fd(&idle->idlecheck, sfd);          uring_connect(cfg, &idle->idlecheck, &idle->remote, idle_check_remote_connected); @@ -44,6 +44,7 @@ struct uring_task {  	callback_t callback;  	rcallback_t complete_callback; /* to check if tbuf processing is done */  	callback_t final_callback; /* once tbuf processing is done */ +	void *priv;  };  struct cfg { @@ -179,70 +179,27 @@ proxy_server_data_in(struct cfg *cfg, struct uring_task *task, int res)  	uring_tbuf_write(cfg, task, proxy_server_data_out);  } -static void proxy_connect_next_remote(struct cfg *cfg, struct server_proxy *proxy); -  static void -proxy_server_connected(struct cfg *cfg, struct uring_task *task, int res) +proxy_connected_cb(struct cfg *cfg, struct connection *conn, int res)  { -	struct server_proxy *proxy = container_of(task, struct server_proxy, servertask); +	struct server_proxy *proxy = container_of(conn, struct server_proxy, server_conn); -	fprintf(stderr, "%s: connected %i\n", __func__, res);  	if (res < 0) { -		uring_task_close_fd(cfg, task); -		proxy_connect_next_remote(cfg, proxy); +		fprintf(stderr, "%s: proxy connection to remote server failed\n", +			proxy->scfg->name); +		proxy_delete(cfg, proxy);  		return;  	} +	proxy->sfd = proxy->servertask.fd;  	fprintf(stderr, "%s: proxy connection %s -> %s opened\n", -		proxy->scfg->name, proxy->clientstr, proxy->serverstr); +		proxy->scfg->name, proxy->clientstr, proxy->server_conn.remotestr);  	proxy->begin = time(NULL); +  	uring_tbuf_read(cfg, &proxy->clienttask, proxy_client_data_in);  	uring_tbuf_read(cfg, &proxy->servertask, proxy_server_data_in);  } -static void -proxy_connect_next_remote(struct cfg *cfg, struct server_proxy *proxy) -{ -	struct sockaddr_in46 *remote, *tmp; -	struct server *scfg = proxy->scfg; -	int sfd; -	unsigned i = 0; - -again: -	remote = NULL; -	list_for_each_entry(tmp, &scfg->remotes, list) { -		if (i == proxy->next_remote) { -			remote = tmp; -			break; -		} -		i++; -	} - -	if (!remote) { -		fprintf(stderr, "No more remote addresses to attempt\n"); -		proxy_delete(cfg, proxy); -		return; -	} - -	proxy->next_remote++; -	proxy->server = *remote; -	sockaddr_to_str(&proxy->server, proxy->serverstr, sizeof(proxy->serverstr)); -	fprintf(stderr, "%s: attempting proxy connection to %s (len %u)\n", -		scfg->name, proxy->serverstr, proxy->server.addrlen); - -	sfd = socket(proxy->server.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); -	if (sfd < 0) { -		perror("socket"); -		goto again; -	} - -	socket_set_gaming_options(cfg, sfd); - -	proxy->sfd = sfd; -	uring_task_set_fd(&proxy->servertask, sfd); -	uring_connect(cfg, &proxy->servertask, &proxy->server, proxy_server_connected); -} -  struct server_proxy *  proxy_new(struct cfg *cfg, struct server *scfg, struct sockaddr_in46 *client, int fd)  { @@ -269,7 +226,7 @@ proxy_new(struct cfg *cfg, struct server *scfg, struct sockaddr_in46 *client, in  	uring_task_set_buf(&proxy->servertask, &proxy->serverbuf);  	list_add(&proxy->list, &scfg->proxys); -	proxy_connect_next_remote(cfg, proxy); +	connect_any(cfg, &proxy->servertask, &scfg->remotes, &proxy->server_conn, proxy_connected_cb);  	return proxy;  } @@ -9,6 +9,7 @@ struct server_proxy {  	uint64_t client_bytes;  	int cfd; +	struct connection server_conn;  	struct sockaddr_in46 server;  	char serverstr[ADDRSTRLEN];  	struct uring_task_buf serverbuf; @@ -372,7 +372,7 @@ again:                  goto again;          } -	socket_set_gaming_options(cfg, sfd); +	socket_set_low_latency(cfg, sfd);          uring_task_set_fd(&rcon->task, sfd);          uring_connect(cfg, &rcon->task, &rcon->rcon, rcon_connected); @@ -251,7 +251,7 @@ server_local_open(struct cfg *cfg, struct server *scfg, struct server_local *loc  	if (setsockopt(sfd, IPPROTO_IP, IP_FREEBIND, &option, sizeof(option)) < 0)  		perror("setsockopt"); -	socket_set_gaming_options(cfg, sfd); +	socket_set_low_latency(cfg, sfd);  	r = bind(sfd, (struct sockaddr *)&local->addr.storage, local->addr.addrlen);  	if (r < 0) { @@ -164,7 +164,7 @@ debug_resource_usage()  }  void -socket_set_gaming_options(struct cfg *cfg, int sfd) +socket_set_low_latency(struct cfg *cfg, int sfd)  {  	int option; @@ -187,6 +187,98 @@ socket_set_gaming_options(struct cfg *cfg, int sfd)  		perror("setsockopt");  } +static void +connection_set_local_addr(struct cfg *cfg, struct connection *conn, int fd) +{ +	if (fd < 0 || getsockname(fd, (struct sockaddr *)&conn->local.storage, +				  &conn->local.addrlen) < 0) +		sprintf(conn->localstr, "<unknown>"); +	else +		sockaddr_to_str(&conn->local, conn->localstr, sizeof(conn->localstr)); +} + +static void connect_next(struct cfg *cfg, struct uring_task *task, struct connection *conn); + +static void +connect_cb(struct cfg *cfg, struct uring_task *task, int res) +{ +	struct connection *conn = task->priv; + +	if (res < 0) { +		fprintf(stderr, "%s: connection to %s failed\n", +			__func__, conn->remotestr); +		uring_task_close_fd(cfg, task); +		connect_next(cfg, task, conn); +		return; +	} + +	connection_set_local_addr(cfg, conn, task->fd); + +	fprintf(stderr, "%s: (%s) connection established %s -> %s\n", +		__func__, task->name, conn->localstr, conn->remotestr); + +	conn->callback(cfg, conn, true); +} + +static void +connect_next(struct cfg *cfg, struct uring_task *task, struct connection *conn) +{ +        struct sockaddr_in46 *remote, *tmp; +        int sfd; +        unsigned i; + +again: +	i = 0; +        remote = NULL; +        list_for_each_entry(tmp, conn->addrs, list) { +                if (i == conn->next_addr) { +                        remote = tmp; +                        break; +                } +                i++; +        } + +        if (!remote) { +                fprintf(stderr, "%s: no more remote addresses to attempt\n", __func__); +		conn->callback(cfg, conn, false); +                return; +        } + +	conn->next_addr++; +        conn->remote = *remote; +	sockaddr_to_str(&conn->remote, conn->remotestr, sizeof(conn->remotestr)); +        fprintf(stderr, "%s: attempting to connect to %s\n", +		task->name, conn->remotestr); + +        sfd = socket(conn->remote.storage.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); +        if (sfd < 0) { +                perror("socket"); +                goto again; +        } + +	socket_set_low_latency(cfg, sfd); + +	task->priv = conn; +        uring_task_set_fd(task, sfd); +        uring_connect(cfg, task, &conn->remote, connect_cb); +} + +void +connect_any(struct cfg *cfg, struct uring_task *task, +	    struct list_head *addrs, struct connection *conn, +	    void (*callback)(struct cfg *, struct connection *, int res)) +{ +	if (!cfg || !task || !addrs || !conn || !callback) { +		fprintf(stderr, "%s: invalid arguments\n", __func__); +		return; +	} + +	conn->next_addr = 0; +	conn->addrs = addrs; +	conn->callback = callback; +	connect_next(cfg, task, conn); +} +  uint16_t sockaddr_port(struct sockaddr_in46 *addr)  {  	switch (addr->storage.ss_family) { @@ -10,6 +10,66 @@ struct list_head {  	struct list_head *prev;  }; +#define zmalloc(s) __zmalloc(__func__, __LINE__, s) +void *__zmalloc(const char *fn, int line, size_t s); + +#define xstrdup(s) __xstrdup(__func__, __LINE__, s) +char *__xstrdup(const char *fn, int line, const char *s); + +#define xstrndup(s, n) __xstrndup(__func__, __LINE__, s, n) +char *__xstrndup(const char *fn, int line, const char *s, size_t n); + +#define xfree(s) __xfree(__func__, __LINE__, s) +void __xfree(const char *fn, int line, void *ptr); + +void debug_resource_usage(); + +#define ADDRSTRLEN (9 /*strlen("AF_INETX ")*/ + INET6_ADDRSTRLEN + 6 /*strlen(" 65535")*/ + 1) +struct sockaddr_in46 { +	union { +		struct sockaddr_storage storage; +		struct sockaddr_in in4; +		struct sockaddr_in6 in6; +	}; +	socklen_t addrlen; +	struct list_head list; +}; + +struct connection { +	struct sockaddr_in46 remote; +	char remotestr[ADDRSTRLEN]; + +	struct sockaddr_in46 local; +	char localstr[ADDRSTRLEN]; + +	struct list_head *addrs; +	unsigned next_addr; + +	void (*callback)(struct cfg *, struct connection *, int res); +}; + +struct uring_task; + +void socket_set_low_latency(struct cfg *cfg, int sfd); + +void connect_any(struct cfg *cfg, struct uring_task *task, +		 struct list_head *addrs, struct connection *conn, +		 void (*callback)(struct cfg *, struct connection *, int res)); + +uint16_t sockaddr_port(struct sockaddr_in46 *addr); + +char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen); + +int strtou16_strict(const char *str, uint16_t *result); + +static inline bool empty_str(const char *str) +{ +	if (!str || str[0] == '\0') +		return true; +	else +		return false; +} +  #define LIST_HEAD_INIT(name) { &(name), &(name) }  #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) @@ -79,47 +139,6 @@ static inline bool list_empty(struct list_head *list)  	     &pos->member != (head);					\  	     pos = n, n = list_entry(n->member.next, typeof(*n), member)) -#define zmalloc(s) __zmalloc(__func__, __LINE__, s) -void *__zmalloc(const char *fn, int line, size_t s); - -#define xstrdup(s) __xstrdup(__func__, __LINE__, s) -char *__xstrdup(const char *fn, int line, const char *s); - -#define xstrndup(s, n) __xstrndup(__func__, __LINE__, s, n) -char *__xstrndup(const char *fn, int line, const char *s, size_t n); - -#define xfree(s) __xfree(__func__, __LINE__, s) -void __xfree(const char *fn, int line, void *ptr); - -void debug_resource_usage(); - -#define ADDRSTRLEN (9 /*strlen("AF_INETX ")*/ + INET6_ADDRSTRLEN + 6 /*strlen(" 65535")*/ + 1) -struct sockaddr_in46 { -	union { -		struct sockaddr_storage storage; -		struct sockaddr_in in4; -		struct sockaddr_in6 in6; -	}; -	socklen_t addrlen; -	struct list_head list; -}; - -void socket_set_gaming_options(struct cfg *cfg, int sfd); - -uint16_t sockaddr_port(struct sockaddr_in46 *addr); - -char *sockaddr_to_str(struct sockaddr_in46 *addr, char *buf, size_t buflen); - -int strtou16_strict(const char *str, uint16_t *result); - -static inline bool empty_str(const char *str) -{ -	if (!str || str[0] == '\0') -		return true; -	else -		return false; -} -  /*  #define _cleanup_(x) __attribute__((cleanup(x)))  | 
