From c99b8d5951fe6429844c8cb5ff94213bb625ad95 Mon Sep 17 00:00:00 2001 From: pk910 Date: Wed, 22 Aug 2012 01:30:14 +0200 Subject: [PATCH] modified code to use IOHandler functions instead of own ones --- Makefile.am | 1 - src/ClientSocket.c | 461 ++++---------------- src/ClientSocket.h | 17 +- src/IRCParser.c | 19 +- src/IRCParser.h | 2 +- src/IRCQueue.c | 146 ++++--- src/IRCQueue.h | 2 - src/QServer.c | 200 ++++----- src/QServer.h | 1 - src/main.c | 77 +--- src/modules.c | 14 +- src/modules.h | 2 - src/modules/DummyServ.mod/bot_DummyServ.c | 4 - src/modules/DummyServ.mod/bot_DummyServ.h | 1 - src/modules/DummyServ.mod/module.c | 6 +- src/modules/NeonBackup.mod/bot_NeonBackup.c | 4 - src/modules/NeonBackup.mod/bot_NeonBackup.h | 1 - src/modules/NeonBackup.mod/module.c | 6 +- src/modules/NeonFun.mod/bot_NeonFun.c | 4 - src/modules/NeonFun.mod/bot_NeonFun.h | 1 - src/modules/NeonFun.mod/module.c | 6 +- src/modules/NeonHelp.mod/bot_NeonHelp.c | 4 - src/modules/NeonHelp.mod/bot_NeonHelp.h | 1 - src/modules/NeonHelp.mod/module.c | 6 +- src/modules/NeonServ.mod/bot_NeonServ.c | 4 - src/modules/NeonServ.mod/bot_NeonServ.h | 1 - src/modules/NeonServ.mod/module.c | 6 +- src/modules/NeonSpam.mod/bot_NeonSpam.c | 4 - src/modules/NeonSpam.mod/bot_NeonSpam.h | 1 - src/modules/NeonSpam.mod/module.c | 6 +- src/modules/funcmd.mod/module.c | 6 +- src/modules/global.mod/module.c | 6 +- src/modules/module.h | 9 +- src/modules/stats.mod/module.c | 6 +- src/overall.h | 2 +- src/ssl.c | 71 --- src/ssl.h | 45 -- src/timeq.c | 134 +++--- src/timeq.h | 8 +- 39 files changed, 340 insertions(+), 955 deletions(-) delete mode 100644 src/ssl.c delete mode 100644 src/ssl.h diff --git a/Makefile.am b/Makefile.am index 8a5caf6..14de200 100644 --- a/Makefile.am +++ b/Makefile.am @@ -185,7 +185,6 @@ neonserv_SOURCES = src/version.c \ src/ChanNode.c \ src/IRCParser.c \ src/ClientSocket.c \ - src/ssl.c \ src/UserNode.c \ src/ChanUser.c \ src/ModeNode.c \ diff --git a/src/ClientSocket.c b/src/ClientSocket.c index cdf76f4..5632de6 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -21,9 +21,9 @@ #include "IRCQueue.h" #include "WHOHandler.h" #include "HandleInfoHandler.h" -#include "ssl.h" #include "ConfigParser.h" #include "version.h" +#include "IOHandler.h" struct socket_list { struct ClientSocket *data; @@ -45,6 +45,8 @@ struct ParseOrder *parse_order = NULL; static struct socket_list *sockets = NULL; static char buffer[BUF_SIZ]; +static IOHANDLER_CALLBACK(socket_callback); + void init_sockets() { THREAD_MUTEX_INIT(synchronized); THREAD_MUTEX_INIT(synchronized_recv); @@ -61,11 +63,10 @@ void init_sockets() { struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname) { struct ClientSocket *client = malloc(sizeof(*client)); - if (!client) - { - perror("malloc() failed"); + if (!client) { return NULL; } + client->iofd = NULL; client->host = strdup(host); client->port = port; client->bind = (bindto ? strdup(bindto) : NULL); @@ -94,282 +95,72 @@ struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pas return client; } -static int _connect_socket(struct ClientSocket *client); - -int connect_socket(struct ClientSocket *client) { - SYNCHRONIZE(synchronized); - int ret = _connect_socket(client); - DESYNCHRONIZE(synchronized); - return ret; -} - -#ifndef WIN32 -static int _connect_socket(struct ClientSocket *client) { - if((client->flags & SOCKET_FLAG_CONNECTED)) return 1; - client->connection_time = time(0); - int sock; - - struct addrinfo hints, *res; - struct sockaddr_in *ip4 = NULL; - struct sockaddr_in6 *ip6 = NULL; - memset (&hints, 0, sizeof (hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags |= AI_CANONNAME; - if (getaddrinfo (client->host, NULL, &hints, &res)) { - return 0; - } - while (res) { - switch (res->ai_family) { - case AF_INET: - ip4 = (struct sockaddr_in *) res->ai_addr; - break; - case AF_INET6: - ip6 = (struct sockaddr_in6 *) res->ai_addr; - break; - } - res = res->ai_next; - } - - if(ip6) { - sock = socket(AF_INET6, SOCK_STREAM, 0); - if(sock == -1) { - perror("socket() failed"); - return 0; - } - - ip6->sin6_family = AF_INET6; - ip6->sin6_port = htons(client->port); - - struct sockaddr_in6 *ip6vhost = NULL; - if (client->bind && !getaddrinfo(client->bind, NULL, &hints, &res)) { - while (res) { - switch (res->ai_family) { - case AF_INET6: - ip6vhost = (struct sockaddr_in6 *) res->ai_addr; - break; - } - res = res->ai_next; - } - } - if(ip6vhost) { - ip6vhost->sin6_family = AF_INET6; - ip6vhost->sin6_port = htons(0); - bind(sock, (struct sockaddr*)ip6vhost, sizeof(*ip6vhost)); - } - - if (connect(sock, (struct sockaddr*)ip6, sizeof(*ip6)) == -1) { - perror("connect() failed"); - return 0; - } - - } else if(ip4) { - sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock == -1) { - perror("socket() failed"); - return 0; - } - - ip4->sin_family = AF_INET; - ip4->sin_port = htons(client->port); - - struct sockaddr_in *ip4vhost = NULL; - if (client->bind && !getaddrinfo(client->bind, NULL, &hints, &res)) { - while (res) { - switch (res->ai_family) { - case AF_INET: - ip4vhost = (struct sockaddr_in *) res->ai_addr; - break; - } - res = res->ai_next; - } - } - if(ip4vhost) { - ip4vhost->sin_family = AF_INET; - ip4vhost->sin_port = htons(0); - bind(sock, (struct sockaddr*)ip4vhost, sizeof(*ip4vhost)); - } - - if (connect(sock, (struct sockaddr*)ip4, sizeof(*ip4)) == -1) { - perror("connect() failed"); - return 0; - } - - } else - return 0; - - if(get_int_field("Sockets.NoDelay")) { - int flag = 1; - if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) == -1) { - perror("setsockopt() failed"); - return 0; - } - } - - client->sock = sock; - client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT; - - if(client->flags & SOCKET_FLAG_SSL) { - ssl_connect(client); - client->flags |= SOCKET_FLAG_HAVE_SSL; - } else - client->flags &= ~SOCKET_FLAG_HAVE_SSL; - - //send the IRC Headers - char sendBuf[512]; - int len; - - if(client->pass && strcmp(client->pass, "")) { - len = sprintf(sendBuf, "PASS :%s\n", client->pass); - write_socket(client, sendBuf, len); - } - len = sprintf(sendBuf, "USER %s 0 0 :%s\n", client->ident, client->realname); - write_socket(client, sendBuf, len); - len = sprintf(sendBuf, "NICK %s\n", client->nick); - write_socket(client, sendBuf, len); - - return 1; -} -#else -static int _connect_socket(struct ClientSocket *client) { - if((client->flags & SOCKET_FLAG_CONNECTED)) return 1; - client->connection_time = time(0); - struct hostent *host; - struct sockaddr_in addr; - int sock; - addr.sin_addr.s_addr = inet_addr(client->host); - if (addr.sin_addr.s_addr == INADDR_NONE) { - host = gethostbyname(client->host); - if(!host) { - return SOCKET_ERROR; - } - memcpy(&(addr.sin_addr), host->h_addr_list[0], 4); - } - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock == -1) - { - perror("socket() failed"); - return 0; - } - - addr.sin_port = htons(client->port); - addr.sin_family = AF_INET; - - if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) - { - perror("connect() failed"); - return 0; - } - - client->sock = sock; - client->flags |= SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT; - - - if(client->flags & SOCKET_FLAG_SSL) { - ssl_connect(client); - client->flags |= SOCKET_FLAG_HAVE_SSL; - } else - client->flags &= ~SOCKET_FLAG_HAVE_SSL; - - //send the IRC Headers - char sendBuf[512]; - int len; - - if(client->pass && strcmp(client->pass, "")) { - len = sprintf(sendBuf, "PASS :%s\n", client->pass); - write_socket(client, sendBuf, len); - } - len = sprintf(sendBuf, "USER %s 0 0 :%s\n", client->ident, client->realname); - write_socket(client, sendBuf, len); - len = sprintf(sendBuf, "NICK %s\n", client->nick); - write_socket(client, sendBuf, len); - - return 1; +void connect_socket(struct ClientSocket *client) { + client->iofd = iohandler_connect(client->host, client->port, ((client->flags & SOCKET_FLAG_SSL) ? 1 : 0), client->bind, socket_callback); + client->iofd->data = client; } -#endif int close_socket(struct ClientSocket *client) { if(client == NULL) return 0; if((client->flags & SOCKET_FLAG_CONNECTED)) { char quitbuf[MAXLEN]; int quitlen = sprintf(quitbuf, "QUIT :[NeonServ %s.%d] disconnect requested.\n", NEONSERV_VERSION, patchlevel); - write_socket_force(client, quitbuf, quitlen); - } - client->flags &= ~(SOCKET_FLAG_READY | SOCKET_FLAG_RECONNECT); - client->flags |= SOCKET_FLAG_QUITTED | SOCKET_FLAG_DEAD; - return 1; -} - -int disconnect_socket(struct ClientSocket *client) { - if(client == NULL) return 0; - if((client->flags & SOCKET_FLAG_CONNECTED)) { - char quitbuf[MAXLEN]; - int quitlen = sprintf(quitbuf, "QUIT :[NeonServ %s.%d] disconnect requested.\n", NEONSERV_VERSION, patchlevel); - write_socket_force(client, quitbuf, quitlen); - } - client->flags &= ~(SOCKET_FLAG_READY | SOCKET_FLAG_RECONNECT); - client->flags |= SOCKET_FLAG_QUITTED; - return 1; -} - -static void destroy_socket(struct ClientSocket *client, int free_socket) { - SYNCHRONIZE(synchronized); - if((client->flags & SOCKET_FLAG_CONNECTED)) { - close(client->sock); + iohandler_send(client, quitbuf, quitlen); + bot_disconnect(client); + + iohandler_close(client->iofd); + client->iofd = NULL; } - if(client->flags & SOCKET_FLAG_HAVE_SSL) - ssl_disconnect(client); + client->flags &= ~(SOCKET_FLAG_READY | SOCKET_FLAG_CONNECTED); if(client->queue) queue_destroy(client); if(client->whoqueue_first) clear_whoqueue(client); if(client->handleinfo_first) clear_handleinfoqueue(client); - client->flags &= ~(SOCKET_FLAG_CONNECTED | SOCKET_FLAG_READY | SOCKET_FLAG_HAVE_SSL); - if(free_socket) { - struct ClientSocket *sock, *last_sock = NULL; - for (sock = sockets->data; sock; sock = sock->next) { - if(sock == client) { - if(last_sock) - last_sock->next = sock->next; - else - sockets->data = sock->next; - sockets->count--; - break; - } else - last_sock = sock; - } - free(client->host); - if(client->bind) - free(client->bind); - if(client->pass) - free(client->pass); - if(client->network_name) - free(client->network_name); - free(client); - } else if(client->flags & SOCKET_FLAG_FAST_JUMP) { - client->flags &= ~SOCKET_FLAG_FAST_JUMP; - connect_socket(client); + return 1; +} + +int destroy_socket(struct ClientSocket *client) { + if(client == NULL) return 0; + close_socket(client); + SYNCHRONIZE(synchronized); + struct ClientSocket *sock, *last_sock = NULL; + for (sock = sockets->data; sock; sock = sock->next) { + if(sock == client) { + if(last_sock) + last_sock->next = sock->next; + else + sockets->data = sock->next; + sockets->count--; + break; + } else + last_sock = sock; } + free(client->host); + if(client->bind) + free(client->bind); + if(client->pass) + free(client->pass); + if(client->network_name) + free(client->network_name); + if(client->iofd) //reconnect timer? + iohandler_close(client->iofd); + free(client); DESYNCHRONIZE(synchronized); + return 1; } -int write_socket_force(struct ClientSocket *client, char* msg, int len) { +static int write_socket_force(struct ClientSocket *client, char* msg, int len) { + if(!(client && (client->flags & SOCKET_FLAG_CONNECTED))) return 0; SYNCHRONIZE(synchronized); #ifdef HAVE_THREADS putlog(LOGLEVEL_RAW, "[%d send %d] %s", getCurrentThreadID(), len, msg); #else putlog(LOGLEVEL_RAW, "[send %d] %s", len, msg); #endif - int ret = 1; - if(!(client->flags & SOCKET_FLAG_HAVE_SSL) || ssl_write(client, msg, len) == -2) { - #ifdef WIN32 - ret = send(client->sock, msg, len, 0); - #else - ret = write(client->sock, msg, len); - #endif - } + iohandler_send(client->iofd, msg, len) client->traffic_out += len; DESYNCHRONIZE(synchronized); return ret; @@ -426,120 +217,45 @@ int clientsocket_parseorder_top(unsigned int tid) { } #endif -int socket_loop(int timeout_seconds) { - if(sockets == NULL) return 0; - int is_synchronized = 1; - SYNCHRONIZE(synchronized_recv); - fd_set fds; - struct timeval timeout; - struct ClientSocket *sock, *next; - int ret = 0, bytes, i; - - FD_ZERO(&fds); - for (sock = sockets->data; sock; sock = sock->next) { - if(!(sock->flags & SOCKET_FLAG_CONNECTED)) continue; //skip disconnected sockets - FD_SET(sock->sock, &fds); - if(sock->sock > ret) - ret = sock->sock; - } - timeout.tv_sec = timeout_seconds; - timeout.tv_usec = 0; - ret = select(ret + 1, &fds, NULL, NULL, &timeout); - for (sock = sockets->data; sock; sock = next) { - next = sock->next; - if((sock->flags & (SOCKET_FLAG_CONNECTED | SOCKET_FLAG_QUITTED)) == SOCKET_FLAG_CONNECTED && FD_ISSET(sock->sock, &fds)) { - if(sock->bufferpos != 0) { - if(!(sock->flags & SOCKET_FLAG_HAVE_SSL) || (bytes = ssl_read(sock, buffer, sizeof(buffer))) == -2) { - #ifdef WIN32 - bytes = recv(sock->sock, buffer, sizeof(buffer), 0); - #else - bytes = read(sock->sock, buffer, sizeof(buffer)); - #endif - } - if(bytes > 0) { - for(i = 0; i < bytes; i++) { - if(sock->bufferpos + i == BUF_SIZ*2) break; //buffer overflow - sock->buffer[sock->bufferpos + i] = buffer[i]; - } - sock->bufferpos += i; - } - } else { - if(!(sock->flags & SOCKET_FLAG_HAVE_SSL) || (bytes = ssl_read(sock, sock->buffer, sizeof(sock->buffer))) == -2) { - #ifdef WIN32 - bytes = recv(sock->sock, sock->buffer, sizeof(sock->buffer), 0); - #else - bytes = read(sock->sock, sock->buffer, sizeof(sock->buffer)); - #endif - } - if(bytes > 0) - sock->bufferpos = bytes; - } - if(bytes <= 0) { - //error - sock->flags |= SOCKET_FLAG_QUITTED; - } else { - sock->traffic_in += bytes; - #ifdef HAVE_THREADS - char linesbuf[BUF_SIZ*2]; - strcpy(linesbuf, sock->buffer); - int used = 0; - for(i = 0; i < sock->bufferpos; i++) { - if(sock->buffer[i] == '\n') { - used = i+1; - } - } - if(used == sock->bufferpos + 1) { - //used all bytes so just reset the bufferpos - sock->bufferpos = 0; - } else { - for(i = 0; i < sock->bufferpos - used; i++) { - sock->buffer[i] = sock->buffer[i+used]; - } - sock->bufferpos -= used; - } - is_synchronized = 0; - unsigned int tid = (unsigned int) pthread_self_tid(); - clientsocket_start_of_recv(tid); - DESYNCHRONIZE(synchronized_recv); - parse_lines(sock, linesbuf, used); - clientsocket_end_of_recv(tid); - #else - int used = parse_lines(sock, sock->buffer, sock->bufferpos); - if(used == sock->bufferpos + 1) { - //used all bytes so just reset the bufferpos - sock->bufferpos = 0; - } else { - for(i = 0; i < sock->bufferpos - used; i++) { - sock->buffer[i] = sock->buffer[i+used]; - } - sock->bufferpos -= used; - } - is_synchronized = 0; - DESYNCHRONIZE(synchronized_recv); - #endif - #ifdef HAVE_THREADS - FD_ZERO(&fds); //zero out all other pending sockets here (we have other threads receiving from them) - #endif - } - } else if((sock->flags & (SOCKET_FLAG_CONNECTED | SOCKET_FLAG_RECONNECT)) == SOCKET_FLAG_RECONNECT) { - if(time(0) - sock->connection_time >= SOCKET_RECONNECT_TIME) { - connect_socket(sock); - } +static IOHANDLER_CALLBACK(socket_callback) { + struct ClientSocket *client = event->iofd->data; + switch(event->type) { + case IOEVENT_CONNECTED: + client->flags |= SOCKET_FLAG_CONNECTED; + if(client->pass && strcmp(client->pass, "")) + iohandler_printf(event->iofd, "PASS :%s", client->pass); + iohandler_printf(event->iofd, "USER %s 0 0 :%s", client->ident, client->realname); + iohandler_printf(event->iofd, "NICK %s", client->nick); + break; + case IOEVENT_NOTCONNECTED: + case IOEVENT_CLOSED: + close_socket(client); + if(client->flags & SOCKET_FLAG_RECONNECT) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + timeout.tv_sec += SOCKET_RECONNECT_TIME; + client->iofd = iohandler_timer(timeout, socket_callback); + client->iofd->data = client; } - if((sock->flags & SOCKET_FLAG_QUITTED)) { - sock->flags &= ~SOCKET_FLAG_QUITTED; - destroy_socket(sock, (sock->flags & SOCKET_FLAG_DEAD)); - } - } - if(is_synchronized) { - DESYNCHRONIZE(synchronized_recv); + break; + case IOEVENT_TIMEOUT: //reconnect timer + connect_socket(client); + break; + case IOEVENT_RECV: + #ifdef HAVE_THREADS + clientsocket_start_of_recv(tid); + #endif + parse_line(client, event->data.recv_str); + #ifdef HAVE_THREADS + clientsocket_end_of_recv(tid); + #endif + break; + default: + break; } - return 1; } -void -putsock(struct ClientSocket *client, const char *text, ...) -{ +void putsock(struct ClientSocket *client, const char *text, ...) { va_list arg_list; char sendBuf[MAXLEN]; int pos; @@ -569,20 +285,7 @@ void free_sockets() { struct ClientSocket *client, *next; for (client = sockets->data; client; client = next) { next = client->next; - if((client->flags & SOCKET_FLAG_CONNECTED)) - close(client->sock); - if(client->flags & SOCKET_FLAG_HAVE_SSL) - ssl_disconnect(client); - if(client->queue) - queue_destroy(client); - free(client->host); - if(client->bind) - free(client->bind); - if(client->pass) - free(client->pass); - if(client->network_name) - free(client->network_name); - free(client); + destroy_socket(client); } free(sockets); sockets = NULL; diff --git a/src/ClientSocket.h b/src/ClientSocket.h index b4e7d44..38768b1 100644 --- a/src/ClientSocket.h +++ b/src/ClientSocket.h @@ -19,15 +19,13 @@ #include "main.h" -#define SOCKET_FLAG_DEAD 0x01 #define SOCKET_FLAG_CONNECTED 0x02 #define SOCKET_FLAG_READY 0x04 #define SOCKET_FLAG_PREFERRED 0x08 /* prefered bot to send datas to the IRC World (NOTICE's WHO's etc pp) */ #define SOCKET_FLAG_USE_QUEUE 0x10 #define SOCKET_FLAG_RECONNECT 0x20 #define SOCKET_FLAG_SSL 0x40 -#define SOCKET_FLAG_HAVE_SSL 0x80 -#define SOCKET_FLAG_QUITTED 0x100 + #define SOCKET_FLAG_FAST_JUMP 0x200 #define SOCKET_FLAG_SILENT 0x400 #define SOCKET_FLAG_CHANGENICK 0x800 @@ -42,13 +40,11 @@ struct UserNode; struct trigger_cache; -struct SSLConnection; +struct IODescriptor; struct ClientSocket { - int sock; + struct IODescriptor *iofd; unsigned int flags; - char buffer[BUF_SIZ*2]; //we need to store up to 2 full commands at once - unsigned int bufferpos; char *host; int port; char *bind; @@ -61,7 +57,6 @@ struct ClientSocket { unsigned long traffic_in; unsigned long traffic_out; time_t connection_time; - struct SSLConnection *sslconn; struct BotQueue *queue; @@ -85,15 +80,13 @@ struct ClientSocket { #ifndef DND_FUNCTIONS /* MODULAR ACCESSIBLE */ struct ClientSocket* create_socket(char *host, int port, char *bindto, char *pass, char *nick, char *ident, char *realname); -/* MODULAR ACCESSIBLE */ int connect_socket(struct ClientSocket *client); +/* MODULAR ACCESSIBLE */ void connect_socket(struct ClientSocket *client); /* MODULAR ACCESSIBLE */ int close_socket(struct ClientSocket *client); -/* MODULAR ACCESSIBLE */ int disconnect_socket(struct ClientSocket *client); -int write_socket_force(struct ClientSocket *client, char* msg, int len); +/* MODULAR ACCESSIBLE */ int destroy_socket(struct ClientSocket *client); /* MODULAR ACCESSIBLE */ int write_socket(struct ClientSocket *client, char* msg, int len); #ifdef HAVE_THREADS int clientsocket_parseorder_top(unsigned int tid); #endif -int socket_loop(int timeout_seconds); /* MODULAR ACCESSIBLE */ void putsock(struct ClientSocket *client, const char *text, ...) PRINTF_LIKE(2, 3); /* MODULAR ACCESSIBLE */ struct ClientSocket* getBots(int flags, struct ClientSocket* last_bot); void init_sockets(); diff --git a/src/IRCParser.c b/src/IRCParser.c index efbdbfd..156afb3 100644 --- a/src/IRCParser.c +++ b/src/IRCParser.c @@ -35,27 +35,10 @@ int statistics_privmsg = 0; int statistics_network_users = 0; int statistics_network_channels = 0; -static void parse_line(struct ClientSocket *client, char *line); static void register_irc_function(char *command, irc_cmd_t *func); static void parse_raw(struct ClientSocket *client, char *from, char *cmd, char **argv, int argc); -int parse_lines(struct ClientSocket *client, char *lines, int len) { - int i, used = 0; - char *line = lines; - for(i = 0; i < len; i++) { - if(lines[i] == '\r') //just zero it out :D - lines[i] = 0; - if(lines[i] == '\n') { - lines[i] = 0; - parse_line(client, line); - line = lines+(i+1); - used = i+1; - } - } - return used; -} - -static void parse_line(struct ClientSocket *client, char *line) { +void parse_line(struct ClientSocket *client, char *line) { int argc = 0; char *argv[MAXNUMPARAMS]; #ifdef HAVE_THREADS diff --git a/src/IRCParser.h b/src/IRCParser.h index 7893bc6..e23a1ec 100644 --- a/src/IRCParser.h +++ b/src/IRCParser.h @@ -36,7 +36,7 @@ extern int statistics_privmsg; extern int statistics_network_users; extern int statistics_network_channels; -int parse_lines(struct ClientSocket *client, char *lines, int len); +void parse_line(struct ClientSocket *client, char *line); void bot_disconnect(struct ClientSocket *client); void init_parser(); void free_parser(); diff --git a/src/IRCQueue.c b/src/IRCQueue.c index be472b3..4fa520b 100644 --- a/src/IRCQueue.c +++ b/src/IRCQueue.c @@ -16,6 +16,7 @@ */ #include "IRCQueue.h" #include "ClientSocket.h" +#include "IOHandler.h" #define MAXPENALTY 8 /* 4 messages */ @@ -26,12 +27,16 @@ struct QueueEntry { struct BotQueue { struct ClientSocket *client; - int penalty; + struct IODescriptor *iofd; + int penalty : 8; + int rem_penalty : 8; struct QueueEntry *fastqueue_first, *fastqueue_last; struct QueueEntry *normalqueue_first, *normalqueue_last; struct QueueEntry *textqueue_first, *textqueue_last; }; +static IOHANDLER_CALLBACK(queue_callback); + static struct BotQueue *initialize_queue(struct ClientSocket *client) { struct BotQueue *queue = malloc(sizeof(*queue)); if (!queue) { @@ -56,6 +61,7 @@ int queue_add(struct ClientSocket *client, char* msg, int len) { struct BotQueue *queue = client->queue; char *args = strstr(msg, " "); int type; + int add_queue = 0; if(args) { *args = '\0'; if(!stricmp(msg, "MODE")) @@ -75,36 +81,73 @@ int queue_add(struct ClientSocket *client, char* msg, int len) { *args = ' '; } else type = 2; - struct QueueEntry *entry = malloc(sizeof(*entry)); - if (!entry) { - perror("malloc() failed"); - return 0; + + //check if we need to queue + switch(type) { + case 1: + if(queue->textqueue_first) { + add_queue = 1; + break; + } + case 2: + if(queue->normalqueue_first) { + add_queue = 1; + break; + } + case 3: + if(queue->fastqueue_first) { + add_queue = 1; + break; + } + default: + if(queue->penalty >= MAXPENALTY) + add_queue = 1; + break; } - entry->msg = strdup(msg); - entry->next = NULL; - if(type == 1) { //low priority - if(queue->textqueue_last) { - queue->textqueue_last->next = entry; - queue->textqueue_last = entry; - } else { - queue->textqueue_last = entry; - queue->textqueue_first = entry; + + if(!add_queue) { + int penalty = calculate_penalty(msg); + write_socket_force(client, msg, len); + queue->penalty += penalty; + if(!queue->iofd) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + queue->rem_penalty = (MAXPENALTY - queue->penalty) + 1; + timeout.tv_sec += queue->rem_penalty; + queue->iofd = iohandler_timer(timeout, queue_callback); } - } else if(type == 2) { //normal priority - if(queue->normalqueue_last) { - queue->normalqueue_last->next = entry; - queue->normalqueue_last = entry; - } else { - queue->normalqueue_last = entry; - queue->normalqueue_first = entry; + } else { + struct QueueEntry *entry = malloc(sizeof(*entry)); + if (!entry) { + perror("malloc() failed"); + return 0; } - } else if(type == 3) { //high priority - if(queue->fastqueue_last) { - queue->fastqueue_last->next = entry; - queue->fastqueue_last = entry; - } else { - queue->fastqueue_last = entry; - queue->fastqueue_first = entry; + entry->msg = strdup(msg); + entry->next = NULL; + if(type == 1) { //low priority + if(queue->textqueue_last) { + queue->textqueue_last->next = entry; + queue->textqueue_last = entry; + } else { + queue->textqueue_last = entry; + queue->textqueue_first = entry; + } + } else if(type == 2) { //normal priority + if(queue->normalqueue_last) { + queue->normalqueue_last->next = entry; + queue->normalqueue_last = entry; + } else { + queue->normalqueue_last = entry; + queue->normalqueue_first = entry; + } + } else if(type == 3) { //high priority + if(queue->fastqueue_last) { + queue->fastqueue_last->next = entry; + queue->fastqueue_last = entry; + } else { + queue->fastqueue_last = entry; + queue->fastqueue_first = entry; + } } } return 1; @@ -183,37 +226,30 @@ void queue_destroy(struct ClientSocket *client) { free(entry->msg); free(entry); } + if(client->queue->iofd) + iohandler_close(client->queue->iofd); free(client->queue); client->queue = NULL; } -static struct timeval lastloop; -void queue_init() { - gettimeofday(&lastloop, NULL); -} - - -void queue_loop() { - struct ClientSocket *bot; - struct timeval now; - gettimeofday(&now, NULL); - long mtime, seconds, useconds; - seconds = now.tv_sec - lastloop.tv_sec; - useconds = now.tv_usec - lastloop.tv_usec; - mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5; - int fullseconds = mtime/1000; - if(fullseconds) { - lastloop.tv_sec += fullseconds; - for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) { - if(bot->queue && bot->queue->penalty) { - bot->queue->penalty -= fullseconds; - if(bot->queue->penalty < 0) - bot->queue->penalty = 0; - } +static IOHANDLER_CALLBACK(queue_callback) { + struct BotQueue *queue = event->iofd->data; + switch(event->type) { + case IOEVENT_TIMEOUT: + queue->penalty -= queue->rem_penalty; + dequeue_bot(queue->client); + if(queue->penalty > 0) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + queue->rem_penalty = (MAXPENALTY - queue->penalty) + 1; + timeout.tv_sec += queue->rem_penalty; + queue->iofd = iohandler_timer(timeout, queue_callback); + } else { + queue->iofd = NULL; + queue->penalty = 0; } - } - for(bot = getBots(0, NULL); bot; bot = getBots(0, bot)) { - if(bot->queue) - dequeue_bot(bot); + break; + default: + break; } } diff --git a/src/IRCQueue.h b/src/IRCQueue.h index 9059631..3f8ae81 100644 --- a/src/IRCQueue.h +++ b/src/IRCQueue.h @@ -23,7 +23,5 @@ struct ClientSocket; int queue_add(struct ClientSocket *client, char* msg, int len); void queue_destroy(struct ClientSocket *client); -void queue_init(); -void queue_loop(); #endif \ No newline at end of file diff --git a/src/QServer.c b/src/QServer.c index 2d77a6b..1e11233 100644 --- a/src/QServer.c +++ b/src/QServer.c @@ -24,6 +24,7 @@ #include "WHOHandler.h" #include "ConfigParser.h" #include "bots.h" +#include "IOHandler.h" #ifdef WIN32 typedef uint32_t socklen_t; @@ -32,54 +33,54 @@ typedef uint32_t socklen_t; #define QSERVER_TIMEOUT 30 #define QSERVER_MAXCLIENTS 100 -#define QSERVER_FLAG_DISCONNECT 0x01 -#define QSERVER_FLAG_AUTHED 0x02 -#define QSERVER_FLAG_IN_USE 0x04 +#define QSERVER_FLAG_AUTHED 0x01 +#define QSERVER_FLAG_IN_USE 0x02 struct QServerClient { - int sock; + struct IODescriptor *iofd; unsigned int flags; - time_t lastmsg; - char buffer[MAXLEN]; - int bufferpos; int references; struct QServerClient *next; }; -static int server_sockfd = 0; +static struct IODescriptor *server_iofd = NULL; struct QServerClient *qserver_clients = NULL; static int qserver_clientcount = 0; +static IOHANDLER_CALLBACK(qserver_callback); + void qserver_init() { if(get_int_field("QServer.enabled")) { - server_sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (server_sockfd < 0) - return; - struct sockaddr_in serv_addr; - memset(&serv_addr, 0, sizeof(serv_addr)); + char *host = get_string_field("QServer.host"); + if(!host) + host = "0.0.0.0"; int portno = get_int_field("QServer.port"); if(!portno) portno = 7499; - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(portno); - if (bind(server_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - return; - listen(server_sockfd,5); + server_iofd = iohandler_listen(host, port, qserver_callback); } } +void qserver_free() { + struct QServerClient *client, *next; + for (client = qserver_clients; client; client = next) { + next = client->next; + if(client->iofd) + iohandler_close(client->iofd); + free(client); + } + qserver_clients = NULL; + qserver_clientcount = 0; + iohandler_close(server_iofd); + server_iofd = NULL; +} + static int qserver_write(struct QServerClient *client, char* msg, int len) { - if (!(client && !(client->flags & QSERVER_FLAG_DISCONNECT))) return 0; + if (!client || !client->iofd) return 0; if(!len) len = strlen(msg); - int ret = 1; - #ifdef WIN32 - ret = send(client->sock, msg, len, 0); - #else - ret = write(client->sock, msg, len); - #endif - return ret; + iohandler_send(client->iofd, msg, len); + return 1; } static void qserver_put(struct QServerClient *client, const char *text, ...) { @@ -97,6 +98,13 @@ static void qserver_put(struct QServerClient *client, const char *text, ...) { qserver_write(client, sendBuf, pos+1); } +static void qserver_update_lastmsg(struct QServerClient *client) { + struct timeval timeout; + gettimeofday(&timeout, NULL); + timeout.tv_sec += QSERVER_TIMEOUT; + iohandler_set_timeout(client->iofd, &timeout); +} + static void qserver_parse_A(struct QServerClient *client, char **argv, int argc) { if(client->flags & QSERVER_FLAG_AUTHED) { qserver_put(client, "E :Already Authed"); @@ -111,7 +119,7 @@ static void qserver_parse_A(struct QServerClient *client, char **argv, int argc) return; } client->flags |= QSERVER_FLAG_AUTHED; - client->lastmsg = time(0); + qserver_update_lastmsg(client); qserver_put(client, "A :Logged in"); } @@ -120,7 +128,7 @@ static void qserver_parse_A(struct QServerClient *client, char **argv, int argc) qserver_put(client, "E :Not Authed");\ return;\ }\ - client->lastmsg = time(0);\ + qserver_update_lastmsg(client);\ } static void qserver_parse_U(struct QServerClient *client, char **argv, int argc); @@ -129,7 +137,7 @@ static void qserver_parse_AC(struct QServerClient *client, char **argv, int argc static void qserver_parse_ACU(struct QServerClient *client, char **argv, int argc); static void qserver_parse_R(struct QServerClient *client, char **argv, int argc); -static void qserver_parse(struct QServerClient *client, char *line, int len) { +static void qserver_parse(struct QServerClient *client, char *line) { int argc = 0; char *argv[MAXNUMPARAMS]; while(*line) { @@ -163,115 +171,59 @@ static void qserver_parse(struct QServerClient *client, char *line, int len) { qserver_put(client, "E :Unknown Command"); } -void qserver_loop() { - if(!get_int_field("QServer.enabled")) +static void qserver_accept(int sockfd) { + struct IODescriptor *client_iofd = iohandler_add(sockfd, IOTYPE_CLIENT, NULL, qserver_callback); + client_iofd->state = IO_CONNECTED; + iohandler_update(client_iofd); + if(qserver_clientcount >= QSERVER_MAXCLIENTS) { + iohandler_printf(client_iofd, "E :Maximum QServer Connections reached"); + iohandler_close(client_iofd); return; - struct timeval tv; + } + struct QServerClient *client = malloc(sizeof(*client)); + client->iofd = client_iofd; + client->references = 0; + client->next = qserver_clients; + qserver_clients = client; + qserver_clientcount++; +} + +static void qserver_cleanup() { struct QServerClient *client, *next, *prev = NULL; - int ret; - time_t now = time(0); - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - ret = server_sockfd; - FD_SET(server_sockfd, &fds); for (client = qserver_clients; client; client = next) { next = client->next; - if((client->flags & (QSERVER_FLAG_DISCONNECT | QSERVER_FLAG_IN_USE)) == QSERVER_FLAG_DISCONNECT) { - close(client->sock); + if(client->iofd == NULL && !(client->flags & QSERVER_FLAG_IN_USE)) { if(prev) prev->next = client->next; else qserver_clients = client->next; qserver_clientcount--; free(client); - continue; - } - prev = client; - if(client->flags & QSERVER_FLAG_DISCONNECT) continue; - if(now - client->lastmsg > QSERVER_TIMEOUT) { - qserver_put(client, "E :Timeout"); - client->flags |= QSERVER_FLAG_DISCONNECT; - continue; - } - FD_SET(client->sock, &fds); - if(client->sock > ret) - ret = client->sock; - } - ret = select(ret + 1, &fds, NULL, NULL, &tv); - if(ret == 0) { - return; - } - if(FD_ISSET(server_sockfd, &fds)) { - //new connection - struct sockaddr_in cli_addr; - #ifdef WIN32 - int clilen; - #else - socklen_t clilen; - #endif - client = malloc(sizeof(*client)); - clilen = sizeof(cli_addr); - client->sock = accept(server_sockfd, (struct sockaddr *) &cli_addr, &clilen); - client->flags = 0; - if(qserver_clientcount >= QSERVER_MAXCLIENTS) { - qserver_put(client, "E :Maximum QServer Connections reached"); - close(client->sock); - free(client); - } else { - client->lastmsg = now; - client->bufferpos = 0; - client->references = 0; - client->next = qserver_clients; - qserver_clients = client; - qserver_clientcount++; - } - } - int bytes, i; - char buffer[MAXLEN]; - for (client = qserver_clients; client; client = next) { - next = client->next; - if(FD_ISSET(client->sock, &fds)) { - #ifdef WIN32 - bytes = recv(client->sock, buffer, sizeof(buffer), 0); - #else - bytes = read(client->sock, buffer, sizeof(buffer)); - #endif - if(bytes <= 0) { - client->flags |= QSERVER_FLAG_DISCONNECT; - continue; - } - for(i = 0; i < bytes; i++) { - if(client->bufferpos == MAXLEN-1) { - //buffer overflow - qserver_put(client, "E :Buffer Overflow"); - client->flags |= QSERVER_FLAG_DISCONNECT; - break; - } - if(buffer[i] == '\r') continue; - else if(buffer[i] == '\n') { - client->buffer[client->bufferpos] = '\0'; - qserver_parse(client, client->buffer, client->bufferpos); - client->bufferpos = 0; - } else { - client->buffer[client->bufferpos++] = buffer[i]; - } - } } } } -void qserver_free() { - struct QServerClient *client, *next; - for (client = qserver_clients; client; client = next) { - next = client->next; - close(client->sock); - free(client); +static IOHANDLER_CALLBACK(qserver_callback) { + struct QServerClient *client = event->iofd->data; + switch(event->type) { + case IOEVENT_TIMEOUT: + qserver_put(client, "E :Timeout"); + client->iofd = NULL; + break; + case IOEVENT_RECV: + qserver_parse(client, event->data.recv_str); + break; + case IOEVENT_CLOSED: + iohandler_close(client->iofd); + client->iofd = NULL; + break; + case IOEVENT_ACCEPT: + + break; + default: + break; } - qserver_clients = NULL; - qserver_clientcount = 0; - close(server_sockfd); + qserver_cleanup(); } /* diff --git a/src/QServer.h b/src/QServer.h index 4bda03e..59bbb5d 100644 --- a/src/QServer.h +++ b/src/QServer.h @@ -20,7 +20,6 @@ #include "main.h" void qserver_init(); -void qserver_loop(); void qserver_free(); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 2e0e5f3..22ced25 100644 --- a/src/main.c +++ b/src/main.c @@ -108,30 +108,24 @@ static int load_mysql_config() { return 1; } -#ifdef HAVE_THREADS -pthread_t *current_threads = NULL; +static TIMEQ_CALLBACK(clear_cache) { + timeq_add(CLEAR_CACHE_INTERVAL, 0, clear_cache, NULL); + clearTempUsers(); + destroyEvents(); + mysql_free(); +} -void * thread_main(void *arg) { +void *thread_main(void *arg) { time_t socket_wait; while(running) { - socket_wait = time(0) + SOCKET_SELECT_TIME; - do { - if(!socket_loop(SOCKET_SELECT_TIME)) { - if(!running) break; - putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.\n"); - cleanup(); - exit(0); - } - } while(time(0) < socket_wait); - if(!running) break; - clearTempUsers(); - destroyEvents(); - mysql_free(); + iohandler_poll(); } - running_threads--; return NULL; } +#ifdef HAVE_THREADS +pthread_t *current_threads = NULL; + int getCurrentThreadID() { if(!current_threads) return 0; int i; @@ -262,18 +256,6 @@ main: start_time = time(0); - #ifdef WIN32 - int res; - WSADATA wsadata; - // Start Windows Sockets. - res = WSAStartup(MAKEWORD(2, 0), &wsadata); - if (res) - { - perror("Unable to start Windows Sockets"); - return 0; - } - #endif - statistics_enabled = get_int_field("statistics.enable"); #ifdef HAVE_THREADS @@ -282,11 +264,7 @@ main: THREAD_MUTEX_INIT(whohandler_mass_sync); #endif - queue_init(); - init_sockets(); - init_timeq(); init_lang(); - ssl_init(); init_parser(); init_UserNode(); init_ChanNode(); @@ -309,6 +287,8 @@ main: timeq_add(90, 0, main_checkauths, NULL); + timeq_add(CLEAR_CACHE_INTERVAL, 0, clear_cache, NULL); + int worker_threads = get_int_field("General.worker_threads"); if(!worker_threads) worker_threads = 1; running = 1; @@ -319,38 +299,13 @@ main: running_threads++; pthread_create(¤t_threads[tid_id], NULL, thread_main, NULL); } - int usleep_delay = 1000000 / TICKS_PER_SECOND; - while(running) { - timeq_tick(); - loop_modules(); - qserver_loop(); - queue_loop(); - mysql_free(); - usleep(usleep_delay); - } + #endif + thread_main(); + #ifdef HAVE_THREADS for(tid_id = 0; tid_id < worker_threads; tid_id++) { pthread_join(current_threads[tid_id], NULL); } running_threads = 0; - #else - time_t socket_wait; - while(running) { - socket_wait = time(0) + SOCKET_SELECT_TIME; - do { - if(!socket_loop(SOCKET_SELECT_TIME)) { - putlog(LOGLEVEL_ERROR, "No more active Bots... shutting down.\n"); - cleanup(); - exit(0); - } - } while(time(0) < socket_wait); - timeq_tick(); - loop_modules(); - clearTempUsers(); - destroyEvents(); - qserver_loop(); - queue_loop(); - mysql_free(); - } #endif cleanup(); if(hard_restart) { diff --git a/src/modules.c b/src/modules.c index ba3562a..eda8f46 100644 --- a/src/modules.c +++ b/src/modules.c @@ -89,7 +89,7 @@ void *global_functions[] = { /* 030 */ (Function) create_socket, /* 031 */ (Function) connect_socket, /* 032 */ (Function) close_socket, -/* 033 */ (Function) disconnect_socket, +/* 033 */ (Function) destroy_socket, /* 034 */ (Function) write_socket, /* 035 */ (Function) putsock, /* 036 */ (Function) getBots, @@ -308,7 +308,6 @@ struct ModuleInfo *loadModule(char *name) { } void* initfunc = dlsym(module, "init_module"); void* startfunc = dlsym(module, "start_module"); - void* loopfunc = dlsym(module, "loop_module"); void* stopfunc = dlsym(module, "stop_module"); void* modversion = dlsym(module, "modversion"); #else @@ -320,11 +319,10 @@ struct ModuleInfo *loadModule(char *name) { } FARPROC initfunc = GetProcAddress(module, "init_module"); FARPROC startfunc = GetProcAddress(module, "start_module"); - FARPROC loopfunc = GetProcAddress(module, "loop_module"); FARPROC stopfunc = GetProcAddress(module, "stop_module"); FARPROC modversion = GetProcAddress(module, "modversion"); #endif - if(!startfunc || !loopfunc || !stopfunc || !modversion) { + if(!startfunc || !stopfunc || !modversion) { putlog(LOGLEVEL_ERROR, "Error loading module '%s': required symbols not found.\n", name); return NULL; } @@ -349,7 +347,6 @@ struct ModuleInfo *loadModule(char *name) { modinfo->module_id = module_id; modinfo->module = module; modinfo->startfunc = startfunc; - modinfo->loopfunc = loopfunc; modinfo->stopfunc = stopfunc; modinfo->state = 0; modinfo->next = modules; @@ -451,13 +448,6 @@ void start_modules() { } } -void loop_modules() { - struct ModuleInfo *modinfo; - for(modinfo = modules; modinfo; modinfo = modinfo->next) { - ((void (*)(void)) modinfo->loopfunc)(); - } -} - void stop_modules() { struct ModuleInfo *modinfo, *next; for(modinfo = modules; modinfo; modinfo = next) { diff --git a/src/modules.h b/src/modules.h index 5468297..da2c6e0 100644 --- a/src/modules.h +++ b/src/modules.h @@ -31,7 +31,6 @@ struct ModuleInfo { #endif int state; void *startfunc; - void *loopfunc; void *stopfunc; struct ModuleInfo *next; }; @@ -40,7 +39,6 @@ struct ModuleInfo { void loadModules(); struct ModuleInfo *loadModule(char *name); void start_modules(); -void loop_modules(); void stop_modules(); int module_loaded(int module_id); diff --git a/src/modules/DummyServ.mod/bot_DummyServ.c b/src/modules/DummyServ.mod/bot_DummyServ.c index c250510..259e640 100644 --- a/src/modules/DummyServ.mod/bot_DummyServ.c +++ b/src/modules/DummyServ.mod/bot_DummyServ.c @@ -150,10 +150,6 @@ void init_DummyServ(int type) { set_trigger_callback(BOTID, module_id, dummyserv_trigger_callback); } -void loop_DummyServ() { - -} - void free_DummyServ(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/DummyServ.mod/bot_DummyServ.h b/src/modules/DummyServ.mod/bot_DummyServ.h index e20bc01..dc5860f 100644 --- a/src/modules/DummyServ.mod/bot_DummyServ.h +++ b/src/modules/DummyServ.mod/bot_DummyServ.h @@ -20,7 +20,6 @@ #include "../../main.h" void init_DummyServ(int type); -void loop_DummyServ(); void free_DummyServ(int type); #endif \ No newline at end of file diff --git a/src/modules/DummyServ.mod/module.c b/src/modules/DummyServ.mod/module.c index b826999..61d9773 100644 --- a/src/modules/DummyServ.mod/module.c +++ b/src/modules/DummyServ.mod/module.c @@ -25,12 +25,8 @@ static void module_start(int type) { init_DummyServ(type); } -static void module_loop() { - loop_DummyServ(); -} - static void module_stop(int type) { free_DummyServ(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/NeonBackup.mod/bot_NeonBackup.c b/src/modules/NeonBackup.mod/bot_NeonBackup.c index 62e3918..b16c387 100644 --- a/src/modules/NeonBackup.mod/bot_NeonBackup.c +++ b/src/modules/NeonBackup.mod/bot_NeonBackup.c @@ -201,10 +201,6 @@ void init_NeonBackup(int type) { register_default_language_table(msgtab); } -void loop_NeonBackup() { - -} - void free_NeonBackup(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/NeonBackup.mod/bot_NeonBackup.h b/src/modules/NeonBackup.mod/bot_NeonBackup.h index b693d10..8284bed 100644 --- a/src/modules/NeonBackup.mod/bot_NeonBackup.h +++ b/src/modules/NeonBackup.mod/bot_NeonBackup.h @@ -20,7 +20,6 @@ #include "../../main.h" void init_NeonBackup(int type); -void loop_NeonBackup(); void free_NeonBackup(int type); #endif \ No newline at end of file diff --git a/src/modules/NeonBackup.mod/module.c b/src/modules/NeonBackup.mod/module.c index 4b13729..cb5f9a6 100644 --- a/src/modules/NeonBackup.mod/module.c +++ b/src/modules/NeonBackup.mod/module.c @@ -27,12 +27,8 @@ static void module_start(int type) { init_NeonBackup(type); } -static void module_loop() { - loop_NeonBackup(); -} - static void module_stop(int type) { free_NeonBackup(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/NeonFun.mod/bot_NeonFun.c b/src/modules/NeonFun.mod/bot_NeonFun.c index d2352c9..b0c2cae 100644 --- a/src/modules/NeonFun.mod/bot_NeonFun.c +++ b/src/modules/NeonFun.mod/bot_NeonFun.c @@ -184,10 +184,6 @@ void init_NeonFun(int type) { set_trigger_callback(BOTID, module_id, neonfun_trigger_callback); } -void loop_NeonFun() { - -} - void free_NeonFun(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/NeonFun.mod/bot_NeonFun.h b/src/modules/NeonFun.mod/bot_NeonFun.h index 9b8bdb1..0065182 100644 --- a/src/modules/NeonFun.mod/bot_NeonFun.h +++ b/src/modules/NeonFun.mod/bot_NeonFun.h @@ -20,7 +20,6 @@ #include "../../main.h" void init_NeonFun(int type); -void loop_NeonFun(); void free_NeonFun(int type); struct uno_game; diff --git a/src/modules/NeonFun.mod/module.c b/src/modules/NeonFun.mod/module.c index 9377166..2581834 100644 --- a/src/modules/NeonFun.mod/module.c +++ b/src/modules/NeonFun.mod/module.c @@ -28,12 +28,8 @@ static void module_start(int type) { srand(time(NULL)); } -static void module_loop() { - loop_NeonFun(); -} - static void module_stop(int type) { free_NeonFun(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/NeonHelp.mod/bot_NeonHelp.c b/src/modules/NeonHelp.mod/bot_NeonHelp.c index 5aa2316..7170dbd 100644 --- a/src/modules/NeonHelp.mod/bot_NeonHelp.c +++ b/src/modules/NeonHelp.mod/bot_NeonHelp.c @@ -567,10 +567,6 @@ void init_NeonHelp(int type) { register_default_language_table(msgtab); } -void loop_NeonHelp() { - -} - void free_NeonHelp(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/NeonHelp.mod/bot_NeonHelp.h b/src/modules/NeonHelp.mod/bot_NeonHelp.h index 51ca4e2..bc231ec 100644 --- a/src/modules/NeonHelp.mod/bot_NeonHelp.h +++ b/src/modules/NeonHelp.mod/bot_NeonHelp.h @@ -40,7 +40,6 @@ struct NeonHelpNode { }; void init_NeonHelp(int type); -void loop_NeonHelp(); void free_NeonHelp(int type); void neonhelp_destroy_support_request(struct ClientSocket *client, struct NeonHelpNode *helpnode, int do_reply); diff --git a/src/modules/NeonHelp.mod/module.c b/src/modules/NeonHelp.mod/module.c index 400c647..7ae1add 100644 --- a/src/modules/NeonHelp.mod/module.c +++ b/src/modules/NeonHelp.mod/module.c @@ -27,12 +27,8 @@ static void module_start(int type) { init_NeonHelp(type); } -static void module_loop() { - loop_NeonHelp(); -} - static void module_stop(int type) { free_NeonHelp(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/NeonServ.mod/bot_NeonServ.c b/src/modules/NeonServ.mod/bot_NeonServ.c index 8433db8..050e71c 100644 --- a/src/modules/NeonServ.mod/bot_NeonServ.c +++ b/src/modules/NeonServ.mod/bot_NeonServ.c @@ -522,10 +522,6 @@ void init_NeonServ(int type) { register_default_language_table(msgtab); } -void loop_NeonServ() { - -} - void free_NeonServ(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/NeonServ.mod/bot_NeonServ.h b/src/modules/NeonServ.mod/bot_NeonServ.h index fcd7d18..7d9f714 100644 --- a/src/modules/NeonServ.mod/bot_NeonServ.h +++ b/src/modules/NeonServ.mod/bot_NeonServ.h @@ -22,7 +22,6 @@ struct ChanNode; void init_NeonServ(int type); -void loop_NeonServ(); void free_NeonServ(int type); struct ClientSocket *getBotForChannel(struct ChanNode *chan); diff --git a/src/modules/NeonServ.mod/module.c b/src/modules/NeonServ.mod/module.c index d736384..c169e75 100644 --- a/src/modules/NeonServ.mod/module.c +++ b/src/modules/NeonServ.mod/module.c @@ -27,12 +27,8 @@ static void module_start(int type) { init_NeonServ(type); } -static void module_loop() { - loop_NeonServ(); -} - static void module_stop(int type) { free_NeonServ(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/NeonSpam.mod/bot_NeonSpam.c b/src/modules/NeonSpam.mod/bot_NeonSpam.c index 3e714ac..eace7b7 100644 --- a/src/modules/NeonSpam.mod/bot_NeonSpam.c +++ b/src/modules/NeonSpam.mod/bot_NeonSpam.c @@ -401,10 +401,6 @@ void init_NeonSpam(int type) { register_default_language_table(msgtab); } -void loop_NeonSpam() { - -} - void free_NeonSpam(int type) { unbind_allcmd(BOTID); if(type == MODSTATE_STARTSTOP) { diff --git a/src/modules/NeonSpam.mod/bot_NeonSpam.h b/src/modules/NeonSpam.mod/bot_NeonSpam.h index 072fccc..718b5ff 100644 --- a/src/modules/NeonSpam.mod/bot_NeonSpam.h +++ b/src/modules/NeonSpam.mod/bot_NeonSpam.h @@ -161,7 +161,6 @@ struct NeonSpamJoinNode { }; void init_NeonSpam(int type); -void loop_NeonSpam(); void free_NeonSpam(int type); void freeNeonSpamSettings(struct NeonSpamSettings *settings); diff --git a/src/modules/NeonSpam.mod/module.c b/src/modules/NeonSpam.mod/module.c index 2758e89..20f99ac 100644 --- a/src/modules/NeonSpam.mod/module.c +++ b/src/modules/NeonSpam.mod/module.c @@ -27,12 +27,8 @@ static void module_start(int type) { init_NeonSpam(type); } -static void module_loop() { - loop_NeonSpam(); -} - static void module_stop(int type) { free_NeonSpam(type); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/funcmd.mod/module.c b/src/modules/funcmd.mod/module.c index 667b6d1..df308a5 100644 --- a/src/modules/funcmd.mod/module.c +++ b/src/modules/funcmd.mod/module.c @@ -27,12 +27,8 @@ static void module_start(int type) { } -static void module_loop() { - -} - static void module_stop(int type) { } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/global.mod/module.c b/src/modules/global.mod/module.c index b4dc94f..a2c5bee 100644 --- a/src/modules/global.mod/module.c +++ b/src/modules/global.mod/module.c @@ -26,12 +26,8 @@ static void module_start(int type) { } -static void module_loop() { - -} - static void module_stop(int type) { } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/modules/module.h b/src/modules/module.h index 50207b5..5e203a7 100644 --- a/src/modules/module.h +++ b/src/modules/module.h @@ -58,9 +58,9 @@ extern int module_id; /* 028 */ #define getChannelUsers ((struct ChanUser* (*)(struct ChanNode *, struct ChanUser *))global[28]) /* 029 */ #define getUserChannels ((struct ChanUser* (*)(struct UserNode *, struct ChanUser *))global[29]) /* 030 */ #define create_socket ((struct ClientSocket* (*)(char *, int, char *, char *, char *, char *, char *))global[30]) -/* 031 */ #define connect_socket ((int (*)(struct ClientSocket *))global[31]) +/* 031 */ #define connect_socket ((void (*)(struct ClientSocket *))global[31]) /* 032 */ #define close_socket ((int (*)(struct ClientSocket *))global[32]) -/* 033 */ #define disconnect_socket ((int (*)(struct ClientSocket *))global[33]) +/* 033 */ #define destroy_socket ((int (*)(struct ClientSocket *))global[33]) /* 034 */ #define write_socket ((int (*)(struct ClientSocket *, char*, int))global[34]) /* 035 */ #define putsock ((void (*)(struct ClientSocket *, const char *, ...))global[35]) /* 036 */ #define getBots ((struct ClientSocket* (*)(int, struct ClientSocket *))global[36]) @@ -225,7 +225,7 @@ extern int module_id; /* 193 */ #define module_neonbackup_recover_chan ((void (*)(struct ChanNode *))global[193]) /* 194 */ #define requestInvite ((void (*)(struct UserNode *, struct ChanNode *))global[194]) -#define MODULE_HEADER(initfunc,startfunc,loopfunc,stopfunc) \ +#define MODULE_HEADER(initfunc,startfunc,stopfunc) \ void **global = NULL; \ int module_id = 0; \ int init_module(void **functions, int modid) { \ @@ -236,9 +236,6 @@ extern int module_id; void start_module(int type) { \ startfunc(type); \ } \ - void loop_module() { \ - loopfunc(); \ - } \ void stop_module(int type) { \ stopfunc(type); \ } \ diff --git a/src/modules/stats.mod/module.c b/src/modules/stats.mod/module.c index f276a0a..fa7d201 100644 --- a/src/modules/stats.mod/module.c +++ b/src/modules/stats.mod/module.c @@ -39,10 +39,6 @@ static void module_start(int type) { timeq_add_name("stats", 60, module_id, stats_timer_callback, NULL); } -static void module_loop() { - -} - static void module_stop(int type) { timeq_del_name("stats"); } @@ -164,4 +160,4 @@ static TIMEQ_CALLBACK(stats_timer_callback) { close(sock); } -MODULE_HEADER(module_initialize, module_start, module_loop, module_stop); +MODULE_HEADER(module_initialize, module_start, module_stop); diff --git a/src/overall.h b/src/overall.h index c5da71b..d84c1d2 100644 --- a/src/overall.h +++ b/src/overall.h @@ -137,7 +137,7 @@ #define BOTWAR_DETECTION_TIME 7 #define BOTWAR_DETECTION_EVENTS 6 #define REWHO_TIMEOUT 10 /* wait 10 seconds before WHO an unauthed user again */ -#define TICKS_PER_SECOND 10 +#define CLEAR_CACHE_INTERVAL 10 //valid nick chars #define VALID_NICK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890{|}~[\\]^-_`" diff --git a/src/ssl.c b/src/ssl.c deleted file mode 100644 index f65533c..0000000 --- a/src/ssl.c +++ /dev/null @@ -1,71 +0,0 @@ -/* ssl.c - NeonServ v5.5 - * Copyright (C) 2011-2012 Philipp Kreil (pk910) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "ssl.h" -#include "ClientSocket.h" - -void ssl_init() { -#ifdef HAVE_SSL - SSL_library_init(); - SSL_load_error_strings(); -#endif -} - -void ssl_connect(struct ClientSocket *client) { -#ifdef HAVE_SSL - client->sslconn = NULL; - if(!(client->flags & SOCKET_FLAG_CONNECTED)) return; - struct SSLConnection *sslconn = malloc(sizeof(*sslconn)); - sslconn->sslContext = SSL_CTX_new(SSLv23_client_method()); - if(!sslconn->sslContext) goto ssl_connect_err; - sslconn->sslHandle = SSL_new(sslconn->sslContext); - if(!sslconn->sslHandle) goto ssl_connect_err; - if(!SSL_set_fd(sslconn->sslHandle, client->sock)) goto ssl_connect_err; - if(SSL_connect(sslconn->sslHandle) != 1) goto ssl_connect_err; - client->sslconn = sslconn; - return; -ssl_connect_err: - free(sslconn); -#endif -} - -void ssl_disconnect(struct ClientSocket *client) { -#ifdef HAVE_SSL - if(!client->sslconn) return; - SSL_shutdown(client->sslconn->sslHandle); - SSL_free(client->sslconn->sslHandle); - SSL_CTX_free(client->sslconn->sslContext); - free(client->sslconn); - client->sslconn = NULL; -#endif -} - -int ssl_read(struct ClientSocket *client, char *buffer, int len) { -#ifdef HAVE_SSL - if(!client->sslconn) return -2; - return SSL_read(client->sslconn->sslHandle, buffer, len); -#endif - return -2; -} - -int ssl_write(struct ClientSocket *client, char *buffer, int len) { -#ifdef HAVE_SSL - if(!client->sslconn) return -2; - return SSL_write(client->sslconn->sslHandle, buffer, len); -#endif - return -2; -} \ No newline at end of file diff --git a/src/ssl.h b/src/ssl.h deleted file mode 100644 index 0af8ad0..0000000 --- a/src/ssl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ssl.h - NeonServ v5.5 - * Copyright (C) 2011-2012 Philipp Kreil (pk910) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef _ssl_h -#define _ssl_h - -#include "main.h" - -struct ClientSocket; - -#ifdef HAVE_SSL -#include -#include -#include - -struct SSLConnection { - SSL *sslHandle; - SSL_CTX *sslContext; -}; -#else -struct SSLConnection { - //just unused -}; -#endif - -void ssl_init(); -void ssl_connect(struct ClientSocket *client); -void ssl_disconnect(struct ClientSocket *client); -int ssl_read(struct ClientSocket *client, char *buffer, int len); -int ssl_write(struct ClientSocket *client, char *buffer, int len); - -#endif \ No newline at end of file diff --git a/src/timeq.c b/src/timeq.c index be82f8f..b53b58d 100644 --- a/src/timeq.c +++ b/src/timeq.c @@ -16,34 +16,24 @@ */ #include "timeq.h" +#include "IOHandler.h" static struct timeq_entry *timeq_events; #ifdef HAVE_THREADS +static int pthread_mutex_initialized = 0; static pthread_mutex_t synchronized; #endif -void init_timeq() { - THREAD_MUTEX_INIT(synchronized); -} - -void timeq_tick() { - SYNCHRONIZE(synchronized); - struct timeq_entry *entry, *next; - struct timeval now; - gettimeofday(&now, NULL); - for(entry = timeq_events; entry; entry = next) { - if(!timeval_is_bigger(entry->execute, now)) { - next = entry->next; - if(timeq_events == entry) - timeq_events = next; - entry->callback(entry->data); - if(entry->name) - free(entry->name); - free(entry); - } else - break; +static IOHANDLER_CALLBACK(timeq_callback) { + struct timeq_entry *entry = event->iofd->data; + switch(event->type) { + case IOEVENT_TIMEOUT: + entry->callback(entry->data); + timeq_del(entry); + break; + default: + break; } - DESYNCHRONIZE(synchronized); } struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *callback, void *data) { @@ -51,36 +41,31 @@ struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *call } struct timeq_entry* timeq_uadd(int useconds, int module_id, timeq_callback_t *callback, void *data) { - struct timeval now; - gettimeofday(&now, NULL); + struct timeval timeout; struct timeq_entry *entry = malloc(sizeof(*entry)); if (!entry) { perror("malloc() failed"); return NULL; } + if(!pthread_mutex_initialized) { + THREAD_MUTEX_INIT(synchronized); + pthread_mutex_initialized = 1; + } + gettimeofday(&timeout, NULL); SYNCHRONIZE(synchronized); - now.tv_usec += (useconds % 1000); - now.tv_sec += (useconds / 1000); - entry->execute = now; + timeout.tv_usec += (useconds % 1000); + timeout.tv_sec += (useconds / 1000); + entry->iofd = iohandler_timer(timeout, timeq_callback); + entry->iofd->data = entry; entry->module_id = module_id; entry->callback = callback; entry->data = data; entry->name = NULL; - struct timeq_entry *next, *prev = NULL; - for(next = timeq_events; next; next = next->next) { - if(timeval_is_bigger(next->execute, now)) - break; - else - prev = next; - } - if(prev == NULL) { - entry->next = timeq_events; - timeq_events = entry; - } else { - entry->next = next; - prev->next = entry; - } + entry->next = timeq_events; + entry->prev = NULL; + timeq_events->prev = entry; + timeq_events = entry; DESYNCHRONIZE(synchronized); return entry; } @@ -90,54 +75,40 @@ struct timeq_entry* timeq_add_name(char *name, int seconds, int module_id, timeq } struct timeq_entry* timeq_uadd_name(char *name, int useconds, int module_id, timeq_callback_t *callback, void *data) { - SYNCHRONIZE(synchronized); struct timeq_entry *entry = timeq_uadd(useconds, module_id, callback, data); entry->name = strdup(name); - DESYNCHRONIZE(synchronized); return entry; } int timeq_del(struct timeq_entry* entry) { + if(!pthread_mutex_initialized) return 0; SYNCHRONIZE(synchronized); - struct timeq_entry *centry, *last = NULL; - for(centry = timeq_events; centry; centry = centry->next) { - if(centry == entry) { - if(last) - last->next = centry->next; - else - timeq_events = centry->next; - if(centry->name) - free(centry->name); - free(centry); - DESYNCHRONIZE(synchronized); - return 1; - } else { - last = centry; - } - } + if(entry->next) + entry->next->prev = entry->prev; + if(entry->prev) + entry->prev->next = entry->next; + else + timeq_events = entry->next; + if(entry->name) + free(entry->name); + iohandler_close(entry->iofd); + free(entry); DESYNCHRONIZE(synchronized); - return 0; + return 1; } int timeq_del_name(char *name) { SYNCHRONIZE(synchronized); - struct timeq_entry *centry, *last = NULL; - for(centry = timeq_events; centry; centry = centry->next) { - if(centry->name && !stricmp(centry->name, name)) { - if(last) - last->next = centry->next; - else - timeq_events = centry->next; - free(centry->name); - free(centry); - DESYNCHRONIZE(synchronized); - return 1; - } else { - last = centry; + struct timeq_entry *entry; + int removed = 0; + for(entry = timeq_events; entry; entry = entry->next) { + if(entry->name && !stricmp(entry->name, name)) { + removed = timeq_del(entry); + break; } } DESYNCHRONIZE(synchronized); - return 0; + return removed; } int timeq_name_exists(char *name) { @@ -155,18 +126,11 @@ int timeq_name_exists(char *name) { void unregister_module_timers(int module_id) { SYNCHRONIZE(synchronized); - struct timeq_entry *centry, *next, *last = NULL; - for(centry = timeq_events; centry; centry = next) { - next = centry->next; - if(centry->module_id == module_id) { - if(last) - last->next = centry->next; - else - timeq_events = centry->next; - free(centry->name); - free(centry); - } else - last = centry; + struct timeq_entry *entry, *next_entry; + for(entry = timeq_events; entry; entry = next_entry) { + next_entry = entry->next; + if(entry->module_id == module_id) + timeq_del(entry); } DESYNCHRONIZE(synchronized); } diff --git a/src/timeq.h b/src/timeq.h index 989021b..969a294 100644 --- a/src/timeq.h +++ b/src/timeq.h @@ -22,19 +22,19 @@ #define TIMEQ_CALLBACK(NAME) void NAME(UNUSED_ARG(void *data)) typedef TIMEQ_CALLBACK(timeq_callback_t); +struct IODescriptor; + struct timeq_entry { + struct IODescriptor *iofd; char *name; int module_id; - struct timeval execute; timeq_callback_t *callback; void *data; - struct timeq_entry *next; + struct timeq_entry *prev, *next; }; #ifndef DND_FUNCTIONS -void init_timeq(); -void timeq_tick(); /* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_add(int seconds, int module_id, timeq_callback_t *callback, void *data); /* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_uadd(int useconds, int module_id, timeq_callback_t *callback, void *data); /* MODULAR ACCESSIBLE */ struct timeq_entry* timeq_add_name(char *name, int seconds, int module_id, timeq_callback_t *callback, void *data); -- 2.20.1