#include "server.h" #include #include #include #include #include #include #include #include /* * Macros */ #define LISTEN_BACKLOG (2048) /* * Data */ static int _fd = -1; /* * Private API */ bool _accept() { close(accept(_fd, 0, 0)); return true; } /* * Public API */ int server_open(const char* host, int port) { struct hostent *he = gethostbyname(host); if (!he) { fprintf(stderr, "[!] gethostbyname failed: %d (h_errno)\n", 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(uint32_t events) { if (events & EPOLLIN) { return _accept(); } // we assume any event other than EPOLLIN is error return false; }