From: pk910 Date: Thu, 22 Dec 2011 19:14:53 +0000 (+0100) Subject: don't close socket directly after sending the QUIT to the server X-Git-Tag: v5.3~112 X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=commitdiff_plain;h=37a4c120f59e3a65d401d23e9469958e4181fcf4 don't close socket directly after sending the QUIT to the server --- diff --git a/src/ClientSocket.c b/src/ClientSocket.c index ec8432a..16ad26d 100644 --- a/src/ClientSocket.c +++ b/src/ClientSocket.c @@ -272,31 +272,8 @@ int close_socket(struct ClientSocket *client) { 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); + client->flags &= ~(SOCKET_FLAG_READY | SOCKET_FLAG_RECONNECT); + client->flags |= SOCKET_FLAG_QUITTED | SOCKET_FLAG_DEAD; return 1; } @@ -306,6 +283,14 @@ int disconnect_socket(struct ClientSocket *client) { 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); } @@ -317,8 +302,30 @@ int disconnect_socket(struct ClientSocket *client) { clear_whoqueue(client); if(client->handleinfo_first) clear_handleinfoqueue(client); - client->flags &= ~(SOCKET_FLAG_CONNECTED | SOCKET_FLAG_READY | SOCKET_FLAG_RECONNECT); - 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) { @@ -390,17 +397,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); - if(sock->whoqueue_first) - clear_whoqueue(sock); - if(sock->handleinfo_first) - clear_handleinfoqueue(sock); + sock->flags |= SOCKET_FLAG_QUITTED; } else { sock->traffic_in += bytes; int used = parse_lines(sock, sock->buffer, sock->bufferpos); @@ -419,6 +416,10 @@ void socket_loop(int timeout_seconds) { connect_socket(sock); } } + if((sock->flags & SOCKET_FLAG_QUITTED)) { + sock->flags &= ~SOCKET_FLAG_QUITTED; + destroy_socket(sock, (sock->flags & SOCKET_FLAG_DEAD)); + } } } diff --git a/src/ClientSocket.h b/src/ClientSocket.h index 9bcdaff..bafc003 100644 --- a/src/ClientSocket.h +++ b/src/ClientSocket.h @@ -27,6 +27,8 @@ #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 BUF_SIZ 512 @@ -36,7 +38,7 @@ struct SSLConnection; struct ClientSocket { int sock; - unsigned char flags; + unsigned int flags; char buffer[BUF_SIZ*2]; //we need to store up to 2 full commands at once unsigned int bufferpos; char *host; diff --git a/src/cmd_global_reconnect.c b/src/cmd_global_reconnect.c index b8b9dde..2dbfdb7 100644 --- a/src/cmd_global_reconnect.c +++ b/src/cmd_global_reconnect.c @@ -36,7 +36,7 @@ CMD_BIND(global_cmd_reconnect) { for(client = getBots(0, NULL); client; client = getBots(0, client)) { if(client->clientid == botid) { disconnect_socket(client); - connect_socket(client); + client->flags |= SOCKET_FLAG_FAST_JUMP; break; } }