summaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c75
1 files changed, 13 insertions, 62 deletions
diff --git a/src/server.c b/src/server.c
index fa48b25..621acae 100644
--- a/src/server.c
+++ b/src/server.c
@@ -11,18 +11,12 @@
#include <endian.h>
#include <unistd.h>
#include <inttypes.h>
-#include <fcntl.h>
#include <errno.h>
#include <poll.h>
-#include <netdb.h>
#include <png.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include "array.h"
#include "content.h"
-#include "peer.h"
+#include "net.h"
#include "str.h"
#include "ser.h"
@@ -56,6 +50,7 @@ typedef struct {
} player;
typedef struct {
+ int accept_fd;
str motd;
str passphrase;
array(map) maps;
@@ -179,36 +174,6 @@ bool map_load(map *m)
#undef TRY
}
-int net_listen(const char *host, const char *port)
-{
- struct addrinfo *info = NULL, hints = {0};
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- int err;
- if ((err = getaddrinfo(host, port, &hints, &info))) {
- fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
- return -1;
- }
-
-#define TRY(op, val) if ((val) < 0) { perror(op); freeaddrinfo(info); return -1; }
-
- int fd;
- TRY("socket", fd = socket(info->ai_family, info->ai_socktype, info->ai_protocol))
-
- int flag = 1;
- TRY("setsockopt", setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &flag, sizeof flag))
-
- TRY("bind", bind(fd, info->ai_addr, info->ai_addrlen))
- TRY("listen", listen(fd, 3))
-
-#undef TRY
-
- freeaddrinfo(info);
- return fd;
-
-}
-
void ser_color(strbuf *w, color c)
{
ser_u8(w, c.r);
@@ -336,7 +301,7 @@ bool handle_hi(str pkt, player *p, game *g)
return true;
}
-bool process_pkt(str pkt, player *p, game *g)
+bool handle_pkt(str pkt, player *p, game *g)
{
pkt_type type;
if (!deser_pkt_type(&pkt, &type))
@@ -355,6 +320,7 @@ int main()
{
game g = {0};
+ g.accept_fd = -1;
g.entity_id = 1;
g.motd = str_clone(S("Welcome to test server"));
g.passphrase = str_clone(S(""));
@@ -376,8 +342,7 @@ int main()
if (!map_load(&g.maps.data[0]))
game_exit(&g, EXIT_FAILURE);
- int accept_fd = net_listen("0.0.0.0", "4560");
- if (accept_fd < 0)
+ if ((g.accept_fd = socket_create("0.0.0.0", "4560", true)) < 0)
game_exit(&g, EXIT_FAILURE);
for (;;) {
@@ -394,7 +359,7 @@ int main()
fds[i++] = peer_prepare(&p->conn);
}
- fds[g.players.len].fd = accept_fd;
+ fds[g.players.len].fd = g.accept_fd;
fds[g.players.len].events = POLLIN;
if (poll(fds, g.players.len + 1, -1) < 0) {
@@ -406,32 +371,18 @@ int main()
for (size_t i = 0; i < g.players.len; i++) {
player *p = &g.players.data[i];
- if (!peer_ready(&p->conn, fds[i]))
- continue;
- if (p->conn.disco)
+
+ str pkt = peer_recv(&p->conn, fds[i]);
+ if (p->conn.disco || pkt.len == 0)
continue;
- str pkt = { p->conn.in.len, (char *) p->conn.in.buffer };
- if (!process_pkt(pkt, p, &g)) {
- // TODO: maybe inform client about failure? not sure
- // FIXME: hexdumping a gazillon bytes to stderr might be an issue
- fprintf(stderr, "invalid pkt from %*s: ", PSTR(p->name));
- for (size_t i = 0; i < pkt.len; i++)
- fprintf(stderr, "%02x%c", (uint8_t) pkt.data[i], i+1 == pkt.len ? '\n' : ' ');
- }
+ if (!handle_pkt(pkt, p, &g))
+ invalid_pkt(p->name, pkt);
}
if (fds[g.players.len].revents) {
- int socket = accept(accept_fd, NULL, NULL); // TODO: save ip
- if (socket < 0) {
- perror("accept");
+ int socket = socket_accept(g.accept_fd);
+ if (socket < 0)
continue;
- }
-
- if (fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | O_NONBLOCK) < 0) {
- close(socket);
- perror("fcntl");
- continue;
- }
printf("new player\n");
player *p = ARR_APPEND(g.players);