X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2FClientSocket.c;h=2897d9d8ca722f6b5dceada83a71e792baf5082d;hb=bb5692b9cbff069abbf9573c81e86c3cd2061ceb;hp=2e2eb1c703fca717a79ab4c87e33f856d7539ef2;hpb=391260f64a1dfb35bf0a55e7044fe1b8d83f2561;p=NeonServV5.git diff --git a/src/ClientSocket.c b/src/ClientSocket.c index 2e2eb1c..2897d9d 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -1,5 +1,5 @@ -/* ClientSocket.c - NeonServ v5.2 - * Copyright (C) 2011 Philipp Kreil (pk910) +/* ClientSocket.c - NeonServ v5.3 + * 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 @@ -23,6 +23,7 @@ #include "HandleInfoHandler.h" #include "ssl.h" #include "ConfigParser.h" +#include "version.h" struct socket_list { struct ClientSocket *data; @@ -186,7 +187,8 @@ int connect_socket(struct ClientSocket *client) { 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]; @@ -241,8 +243,8 @@ int connect_socket(struct ClientSocket *client) { 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]; @@ -263,34 +265,65 @@ int connect_socket(struct ClientSocket *client) { int close_socket(struct ClientSocket *client) { if(client == NULL) return 0; - if((client->flags & SOCKET_FLAG_CONNECTED)) + 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) { + if((client->flags & SOCKET_FLAG_CONNECTED)) { close(client->sock); + bot_disconnect(client); + } if(client->flags & SOCKET_FLAG_HAVE_SSL) ssl_disconnect(client); - 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--; - } else - last_sock = sock; - } if(client->queue) queue_destroy(client); if(client->whoqueue_first) clear_whoqueue(client); if(client->handleinfo_first) clear_handleinfoqueue(client); - free(client->host); - if(client->bind) - free(client->bind); - if(client->pass) - free(client->pass); - free(client); - return 1; + 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); + free(client); + } else if(client->flags & SOCKET_FLAG_FAST_JUMP) { + client->flags &= ~SOCKET_FLAG_FAST_JUMP; + connect_socket(client); + } } int write_socket_force(struct ClientSocket *client, char* msg, int len) { @@ -318,7 +351,7 @@ void socket_loop(int timeout_seconds) { if(sockets == NULL) return; fd_set fds; struct timeval timeout; - struct ClientSocket *sock; + struct ClientSocket *sock, *next; int ret = 0, bytes, i; FD_ZERO(&fds); @@ -332,8 +365,9 @@ void socket_loop(int timeout_seconds) { timeout.tv_usec = 0; ret = select(ret + 1, &fds, NULL, NULL, &timeout); if(ret == 0) return; - for (sock = sockets->data; sock; sock = sock->next) { - if((sock->flags & SOCKET_FLAG_CONNECTED) && FD_ISSET(sock->sock, &fds)) { + 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 @@ -362,13 +396,7 @@ void socket_loop(int timeout_seconds) { } if(bytes <= 0) { //error - sock->flags &= ~(SOCKET_FLAG_CONNECTED | SOCKET_FLAG_READY); - bot_disconnect(sock); - if(sock->queue) - queue_destroy(sock); - close(sock->sock); - if(sock->flags & SOCKET_FLAG_HAVE_SSL) - ssl_disconnect(sock); + sock->flags |= SOCKET_FLAG_QUITTED; } else { sock->traffic_in += bytes; int used = parse_lines(sock, sock->buffer, sock->bufferpos); @@ -382,11 +410,15 @@ void socket_loop(int timeout_seconds) { sock->bufferpos -= used; } } - } else if(!(sock->flags & SOCKET_FLAG_CONNECTED) && (sock->flags & SOCKET_FLAG_RECONNECT)) { + } 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); } } + if((sock->flags & SOCKET_FLAG_QUITTED)) { + sock->flags &= ~SOCKET_FLAG_QUITTED; + destroy_socket(sock, (sock->flags & SOCKET_FLAG_DEAD)); + } } }