213 lines
5.3 KiB
C
213 lines
5.3 KiB
C
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <pthread.h>
|
|
//#include <sys/event.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <sys/time.h>
|
|
#include <err.h>
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
#include <logger.h>
|
|
#include <clconfig.h>
|
|
#include <tconfig.h>
|
|
#include <massert.h>
|
|
|
|
|
|
|
|
/*
|
|
static char* strcopy(char* src) {
|
|
size_t srcsize = strlen(src) + 1;
|
|
char* dst = malloc(srcsize);
|
|
|
|
memset(dst, '\0', srcsize);
|
|
strcpy(dst, src);
|
|
return dst;
|
|
}
|
|
*/
|
|
|
|
typedef struct {
|
|
int argc;
|
|
char** argv;
|
|
char* logpath;
|
|
int port;
|
|
} server_t;
|
|
|
|
|
|
static server_t server;
|
|
|
|
int server_init(int argc, char** argv) {
|
|
logger_dprintf("server initialization");
|
|
server.argc = argc;
|
|
server.argv = argv;
|
|
return 0;
|
|
}
|
|
|
|
#define SERVER_CONFIG_ERROR -1
|
|
|
|
int server_config(void) {
|
|
logger_dprintf("server configuration");
|
|
|
|
tconfig_t tconfig;
|
|
|
|
tconfig_init(&tconfig);
|
|
|
|
server.logpath = "/var/log/helmetd.log";
|
|
server.port = 1025;
|
|
|
|
tconfig_bind(&tconfig, TCONF_STR, "logpath", &server.logpath);
|
|
tconfig_bind(&tconfig, TCONF_INT, "port", &server.port);
|
|
|
|
ssize_t rsize = tconfig_read(&tconfig, "helmet.conf");
|
|
|
|
if (rsize < 0) {
|
|
return SERVER_CONFIG_ERROR;
|
|
}
|
|
int res = tconfig_parse(&tconfig);
|
|
|
|
if (res < 0) {
|
|
char* errstr = tconfig_geterr(&tconfig);
|
|
|
|
logger_dprintf("tconfig parsing error: %s", errstr);
|
|
return SERVER_CONFIG_ERROR;
|
|
}
|
|
tconfig_destroy(&tconfig);
|
|
|
|
clconfig_t clconfig;
|
|
|
|
clconfig_init(&clconfig, server.argc, server.argv);
|
|
|
|
clconfig_bind(&clconfig, GCONF_INT, "port", &(server.port));
|
|
clconfig_bind(&clconfig, GCONF_STR, "log", &(server.logpath));
|
|
|
|
// TODO: memory leak on server.logpath
|
|
res = clconfig_parse(&clconfig);
|
|
if (res < 0) {
|
|
char* errstr = clconfig_geterr(&clconfig);
|
|
|
|
logger_dprintf("clconfig parsing error: %s", errstr);
|
|
return SERVER_CONFIG_ERROR;
|
|
}
|
|
|
|
logger_dprintf("logpath = %s", server.logpath);
|
|
logger_dprintf("port = %d", server.port);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int loop(void);
|
|
|
|
int server_run(void) {
|
|
logger_dprintf("start the server");
|
|
loop();
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int socket_create(int port, int backlog) {
|
|
int sock;
|
|
|
|
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
|
logger_dprintf("cannot create socket");
|
|
return -1;
|
|
}
|
|
int optval;
|
|
|
|
optval = 1;
|
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
|
|
logger_dprintf("cannot set socket option, exit\n");
|
|
return -1;
|
|
}
|
|
|
|
struct sockaddr addr;
|
|
struct sockaddr_in* paddr = (struct sockaddr_in *)&addr;
|
|
|
|
paddr->sin_family = AF_INET;
|
|
paddr->sin_addr.s_addr = INADDR_ANY;
|
|
paddr->sin_port = htons(port);
|
|
|
|
if (bind(sock, (struct sockaddr *)paddr, sizeof(struct sockaddr_in)) < 0) {
|
|
logger_dprintf("cannot bind socket");
|
|
return -1;
|
|
}
|
|
if (listen(sock, backlog) < 0) {
|
|
logger_dprintf("cannot listen socket");
|
|
return -1;
|
|
}
|
|
return sock;
|
|
}
|
|
|
|
|
|
int loop(void) {
|
|
|
|
int port = 1025;
|
|
int backlog = 4096;
|
|
int sock;
|
|
|
|
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
|
logger_eprintf("Cannot create socket");
|
|
return -1;
|
|
}
|
|
int optval;
|
|
|
|
optval = 1;
|
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
|
|
logger_eprintf("Cannot set socket option, exit\n");
|
|
return -1;
|
|
}
|
|
|
|
struct sockaddr addr;
|
|
struct sockaddr_in* paddr = (struct sockaddr_in *)&addr;
|
|
|
|
paddr->sin_family = AF_INET;
|
|
paddr->sin_addr.s_addr = INADDR_ANY;
|
|
paddr->sin_port = htons(port);
|
|
|
|
if (bind(sock, (struct sockaddr *)paddr, sizeof(struct sockaddr_in)) < 0) {
|
|
logger_eprintf("Cannot bind socket");
|
|
return -1;
|
|
}
|
|
if (listen(sock, backlog) < 0) {
|
|
logger_eprintf("Cannot listen socket");
|
|
return -1;
|
|
}
|
|
|
|
while (1) {
|
|
int newsock = 0;
|
|
if ((newsock = accept(sock, NULL, 0)) > 3) {
|
|
struct timeval tv = {
|
|
.tv_sec = 3,
|
|
.tv_usec = 0
|
|
};
|
|
tv.tv_sec = 3;
|
|
tv.tv_usec = 0;
|
|
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0) {
|
|
logger_eprintf("Cannot set socket option");
|
|
return -1;
|
|
}
|
|
logger_dprintf("hello");
|
|
char* message = "hello\n";
|
|
write(newsock, message, strlen(message));
|
|
close(newsock);
|
|
}
|
|
}
|
|
|
|
close(sock);
|
|
return 0;
|
|
}
|