/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
+ * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
* Please read the file COPYING, README and AUTHORS for more information.
*/
+#undef DEBUG_BUFFER
+
#define CONN_MODULE
#include "portab.h"
#include "ngircd.h"
#include "array.h"
#include "client.h"
+#include "class.h"
#include "conf.h"
#include "conn-ssl.h"
#include "conn-zip.h"
/**
- * Initialite connecion module.
+ * Initialize connecion module.
*/
GLOBAL void
Conn_Init( void )
* they don't hold connections open that the main process wants to close.
*/
GLOBAL void
-Conn_CloseAllSockets(void)
+Conn_CloseAllSockets(int ExceptOf)
{
CONN_ID idx;
for(idx = 0; idx < Pool_Size; idx++) {
- if(My_Connections[idx].sock > NONE)
+ if(My_Connections[idx].sock > NONE &&
+ My_Connections[idx].sock != ExceptOf)
close(My_Connections[idx].sock);
}
}
Check_Servers();
Check_Connections();
+ /* Expire outdated class/list items */
+ Class_Expire();
+
/* Look for non-empty read buffers ... */
for (i = 0; i < Pool_Size; i++) {
if ((My_Connections[i].sock > NONE)
assert( Data != NULL );
assert( Len > 0 );
- c = Conn_GetClient(Idx);
- assert( c != NULL);
-
- /* Servers do get special write buffer limits, so they can generate
- * all the messages that are required while peering. */
- if (Client_Type(c) == CLIENT_SERVER)
- writebuf_limit = WRITEBUFFER_SLINK_LEN;
-
/* Is the socket still open? A previous call to Conn_Write()
* may have closed the connection due to a fatal error.
* In this case it is sufficient to return an error, as well. */
- if( My_Connections[Idx].sock <= NONE ) {
+ if (My_Connections[Idx].sock <= NONE) {
LogDebug("Skipped write on closed socket (connection %d).", Idx);
return false;
}
+ /* Make sure that there still exists a CLIENT structure associated
+ * with this connection and check if this is a server or not: */
+ c = Conn_GetClient(Idx);
+ if (c) {
+ /* Servers do get special write buffer limits, so they can
+ * generate all the messages that are required while peering. */
+ if (Client_Type(c) == CLIENT_SERVER)
+ writebuf_limit = WRITEBUFFER_SLINK_LEN;
+ } else
+ LogDebug("Write on socket without client (connection %d)!?", Idx);
+
#ifdef ZLIB
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
/* Compressed link:
GLOBAL void
Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient )
{
- /* Close connection. Open pipes of asyncronous resolver
+ /* Close connection. Open pipes of asynchronous resolver
* sub-processes are closed down. */
CLIENT *c;
return true;
}
+#ifdef DEBUG_BUFFER
LogDebug
("Handle_Write() called for connection %d, %ld bytes pending ...",
Idx, wdatalen);
+#endif
#ifdef SSL_SUPPORT
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
assert(Sock > NONE);
+ LogDebug("Accepting new connection on socket %d ...", Sock);
+
new_sock_len = (int)sizeof(new_addr);
new_sock = accept(Sock, (struct sockaddr *)&new_addr,
(socklen_t *)&new_sock_len);
if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
(size_t) len)) {
Log(LOG_ERR,
- "Could not append recieved data to zip input buffer (connn %d): %d bytes!",
+ "Could not append recieved data to zip input buffer (connection %d): %d bytes!",
Idx, len);
Conn_Close(Idx, "Receive buffer space exhausted", NULL,
false);
#endif
{
if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
- Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len );
+ Log(LOG_ERR,
+ "Could not append recieved data to input buffer (connection %d): %d bytes!",
+ Idx, len);
Conn_Close(Idx, "Receive buffer space exhausted", NULL, false );
}
}
return 0; /* error -> connection has been closed */
array_moveleft(&My_Connections[Idx].rbuf, 1, len);
+#ifdef DEBUG_BUFFER
LogDebug("Connection %d: %d bytes left in read buffer.",
Idx, array_bytes(&My_Connections[Idx].rbuf));
+#endif
#ifdef ZLIB
if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
(array_bytes(&My_Connections[Idx].rbuf) > 0)) {
/* Set type of service (TOS) */
#if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
value = IPTOS_LOWDELAY;
- LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
(socklen_t) sizeof(value))) {
LogDebug("Can't set socket option IP_TOS: %s!",
strerror(errno));
/* ignore this error */
- }
+ } else
+ LogDebug("IP_TOS on socket %d has been set to IPTOS_LOWDELAY.",
+ Sock);
#endif
return true;
/* Read result from pipe */
len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
+ Proc_Close(&Conf_Server[i].res_stat);
if (len == 0) {
/* Error resolving hostname: reset server structure */
Conf_Server[i].conn_id = NONE;
/* Read result from pipe */
len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
+ Proc_Close(&My_Connections[i].proc_stat);
if (len == 0)
return;