#include "server.h" #include #include #include #include #include #include #include #include #include "connection.h" #include "utils.h" /* * Macros */ #define LISTEN_BACKLOG (2048) /* * Data */ static int _fd = -1; /* * Private API */ bool _accept() { int fd = accept(_fd, 0, 0); if (fd == -1) { fprintf(stderr, "[!] accept failed: %d\n", errno); return false; } uint32_t id = connection_add(fd); if (!id) { close(fd); fprintf(stderr, "[!] connection_add failed\n"); // no returning false, because it would terminate the app } else { const char* data = "Test data lalalala"; connection_send(id, data, strlen(data)); } return true; } /* * Public API */ int server_open(const char* host, int port) { struct hostent *he = gethostbyname(host); if (!he) { fprintf(stderr, "[!] gethostbyname (%s) failed: %d (h_errno)\n", host, h_errno); return -1; } _fd = socket( AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP ); if (_fd == -1) { fprintf(stderr, "[!] socket failed: %d\n", errno); return -1; } const int opt = 1; if (setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { close(_fd); fprintf(stderr, "[!] setsockopt failed: %d\n", errno); return -1; } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htobe16(port); memcpy(&addr.sin_addr, he->h_addr, he->h_length); if (bind(_fd, (const void *)&addr, sizeof(addr)) == -1) { close(_fd); fprintf(stderr, "[!] bind failed: %d\n", errno); return -1; } if (listen(_fd, LISTEN_BACKLOG) == -1) { close(_fd); fprintf(stderr, "[!] listen failed: %d\n", errno); return -1; } return _fd; } void server_close() { shutdown(_fd, SHUT_RDWR); close(_fd); } bool server_event(int fd, uint32_t events) { if (events & EPOLLIN) { return _accept(); } // we assume any event other than EPOLLIN is error return false; }