69 lines
1.6 KiB
C
69 lines
1.6 KiB
C
#include "server.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <stdlib.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
|
|
#ifdef BAD_ERROR_REPORTING_FOR_AUTOGRADER
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
struct _Server {
|
|
int socket;
|
|
};
|
|
|
|
Server *make_server(const char *text_addr, uint32_t port) {
|
|
struct sockaddr_in addr = {
|
|
.sin_family = AF_INET,
|
|
.sin_port = htons(port),
|
|
};
|
|
if (inet_pton(AF_INET, text_addr, &addr.sin_addr) != 1) {
|
|
log_error("bad IPv4 address: \"%s\"", text_addr);
|
|
return NULL;
|
|
}
|
|
Server *server = malloc_safe(sizeof(Server));
|
|
server->socket = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (server->socket < 0) {
|
|
log_errno("socket");
|
|
free(server);
|
|
return NULL;
|
|
}
|
|
int on = 1;
|
|
if (setsockopt(server->socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
|
|
log_errno("setsockopt SO_REUSEADDR");
|
|
close(server->socket);
|
|
free(server);
|
|
return NULL;
|
|
}
|
|
if (bind(server->socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
|
#ifdef BAD_ERROR_REPORTING_FOR_AUTOGRADER
|
|
fprintf(stderr, "Invalid Port\n");
|
|
#else
|
|
log_errno("bind");
|
|
#endif
|
|
close(server->socket);
|
|
free(server);
|
|
return NULL;
|
|
}
|
|
if (listen(server->socket, SERVER_BACKLOG) < 0) {
|
|
log_errno("listen");
|
|
close(server->socket);
|
|
free(server);
|
|
return NULL;
|
|
}
|
|
return server;
|
|
}
|
|
|
|
void destroy_server(Server *server) {
|
|
close(server->socket);
|
|
free(server);
|
|
}
|
|
|
|
int server_accept(Server *server) {
|
|
return accept(server->socket, NULL, NULL);
|
|
}
|