-/* 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
char quitbuf[MAXLEN];
int quitlen = sprintf(quitbuf, "QUIT :[NeonServ %s.%d] disconnect requested.\n", NEONSERV_VERSION, patchlevel);
write_socket_force(client, quitbuf, quitlen);
- 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;
}
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);
}
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) {
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);
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
}
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);
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));
+ }
}
}