/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2018 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
CONN_ID idx = Socket2Index( sock );
if (idx <= NONE) {
- LogDebug("cb_connserver wants to write on unknown socket?!");
io_close(sock);
return;
}
{
CONN_ID idx = Socket2Index(sock);
- assert(idx >= 0);
-
- if (idx < 0) {
+ if (idx <= NONE) {
io_close(sock);
return;
}
+
#ifdef SSL_SUPPORT
if (what & IO_WANTREAD
|| (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
GLOBAL void
Conn_Init( void )
{
- CONN_ID i;
+ int size;
- Pool_Size = CONNECTION_POOL;
- if ((Conf_MaxConnections > 0) &&
- (Pool_Size > Conf_MaxConnections))
- Pool_Size = Conf_MaxConnections;
-
- if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
- Log(LOG_EMERG, "Can't allocate memory! [Conn_Init]");
+ /* Initialize the "connection pool".
+ * FIXME: My_Connetions/Pool_Size is needed by other parts of the
+ * code; remove them! */
+ Pool_Size = 0;
+ size = Conf_MaxConnections > 0 ? Conf_MaxConnections : CONNECTION_POOL;
+ if (Socket2Index(size) <= NONE) {
+ Log(LOG_EMERG, "Failed to initialize connection pool!");
exit(1);
}
- /* FIXME: My_Connetions/Pool_Size is needed by other parts of the
- * code; remove them! */
- My_Connections = (CONNECTION*) array_start(&My_ConnArray);
-
- LogDebug("Allocated connection pool for %d items (%ld bytes).",
- array_length(&My_ConnArray, sizeof(CONNECTION)),
- array_bytes(&My_ConnArray));
-
- assert(array_length(&My_ConnArray, sizeof(CONNECTION)) >= (size_t)Pool_Size);
-
+ /* Initialize "listener" array. */
array_free( &My_Listeners );
-
- for (i = 0; i < Pool_Size; i++)
- Init_Conn_Struct(i);
} /* Conn_Init */
/**
if (!ret) {
assert(listen_addrstr);
Log(LOG_CRIT,
- "Can't bind to [%s]:%u: can't convert ip address \"%s\"!",
- listen_addrstr, Port, listen_addrstr);
+ "Can't listen on [%s]:%u: Failed to parse IP address!",
+ listen_addrstr, Port);
}
return ret;
}
GLOBAL bool
Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
#else
-GLOBAL bool
+GLOBAL bool
Conn_WriteStr(Idx, Format, va_alist)
CONN_ID Idx;
const char *Format;
* IRC_WriteXXX() functions when the prefix of this server had
* to be added to an already "quite long" command line which
* has been received from a regular IRC client, for example.
- *
+ *
* We are not allowed to send such "oversized" messages to
* other servers and clients, see RFC 2812 2.3 and 2813 3.3
* ("these messages SHALL NOT exceed 512 characters in length,
/* Check global connection limit */
if ((Conf_MaxConnections > 0) &&
(NumConnections >= (size_t) Conf_MaxConnections)) {
- Log(LOG_ALERT, "Can't accept connection: limit (%d) reached!",
- Conf_MaxConnections);
+ Log(LOG_ALERT, "Can't accept new connection on socket %d: Limit (%d) reached!",
+ Sock, Conf_MaxConnections);
Simple_Message(new_sock, "ERROR :Connection limit reached");
close(new_sock);
return -1;
return -1;
}
- if (new_sock >= Pool_Size) {
- if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
- (size_t) new_sock)) {
- Log(LOG_EMERG,
- "Can't allocate memory! [New_Connection]");
- Simple_Message(new_sock, "ERROR: Internal error");
- close(new_sock);
- return -1;
- }
- LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)",
- new_sock, array_length(&My_ConnArray,
- sizeof(CONNECTION)), array_bytes(&My_ConnArray));
-
- /* Adjust pointer to new block */
- My_Connections = array_start(&My_ConnArray);
- while (Pool_Size <= new_sock)
- Init_Conn_Struct(Pool_Size++);
+ if (Socket2Index(new_sock) <= NONE) {
+ Simple_Message(new_sock, "ERROR: Internal error");
+ close(new_sock);
+ return -1;
}
/* register callback */
ident_sock = My_Connections[Idx].sock;
#endif
- if (Conf_NoticeAuth) {
- /* Send "NOTICE AUTH" messages to the client */
+ if (Conf_NoticeBeforeRegistration) {
+ /* Send "NOTICE *" messages to the client */
#ifdef IDENTAUTH
if (Conf_Ident)
(void)Conn_WriteStr(Idx,
- "NOTICE AUTH :*** Looking up your hostname and checking ident");
+ "NOTICE * :*** Looking up your hostname and checking ident");
else
#endif
(void)Conn_WriteStr(Idx,
- "NOTICE AUTH :*** Looking up your hostname");
+ "NOTICE * :*** Looking up your hostname");
/* Send buffered data to the client, but break on errors
* because Handle_Write() would have closed the connection
* again in this case! */
} /* Account_Connection */
/**
- * Translate socket handle into connection index.
+ * Translate socket handle into connection index (for historical reasons, it is
+ * a 1:1 mapping today) and enlarge the "connection pool" accordingly.
*
* @param Sock Socket handle.
- * @returns Connecion index or NONE, if no connection could be found.
+ * @returns Connecion index or NONE when the pool is too small.
*/
static CONN_ID
Socket2Index( int Sock )
{
- assert( Sock >= 0 );
+ assert(Sock > 0);
+ assert(Pool_Size >= 0);
+
+ if (Sock < Pool_Size)
+ return Sock;
- if( Sock >= Pool_Size || My_Connections[Sock].sock != Sock ) {
- /* the Connection was already closed again, likely due to
- * an error. */
- LogDebug("Socket2Index: can't get connection for socket %d!", Sock);
+ /* Try to allocate more memory ... */
+ if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Sock)) {
+ Log(LOG_EMERG,
+ "Can't allocate memory to enlarge connection pool!");
return NONE;
}
+ LogDebug("Enlarged connection pool for %ld sockets (%ld items, %ld bytes)",
+ Sock, array_length(&My_ConnArray, sizeof(CONNECTION)),
+ array_bytes(&My_ConnArray));
+
+ /* Adjust pointer to new block, update size and initialize new items. */
+ My_Connections = array_start(&My_ConnArray);
+ while (Pool_Size <= Sock)
+ Init_Conn_Struct(Pool_Size++);
+
return Sock;
-} /* Socket2Index */
+}
/**
* Read data from the network to the read buffer. If an error occurs,
if (len == 0) {
LogDebug("Client \"%s:%u\" is closing connection %d ...",
My_Connections[Idx].host,
- ng_ipaddr_tostr(&My_Connections[Idx].addr), Idx);
+ ng_ipaddr_getport(&My_Connections[Idx].addr), Idx);
Conn_Close(Idx, NULL, "Client closed connection", false);
return;
}
Conf_Server[i].lasttry = time_now;
Conf_Server[i].conn_id = SERVER_WAIT;
assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
- Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
- cb_Connect_to_Server);
+
+ /* Start resolver subprocess ... */
+ if (!Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
+ cb_Connect_to_Server))
+ Conf_Server[i].conn_id = NONE;
}
} /* Check_Servers */
return;
}
- if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) {
- Log(LOG_ALERT,
- "Cannot allocate memory for server connection (socket %d)",
- new_sock);
+ if (Socket2Index(new_sock) <= NONE) {
close( new_sock );
Conf_Server[Server].conn_id = NONE;
return;
return;
}
- My_Connections = array_start(&My_ConnArray);
-
assert(My_Connections[new_sock].sock <= 0);
Init_Conn_Struct(new_sock);
strlcpy(My_Connections[i].host, readbuf,
sizeof(My_Connections[i].host));
Client_SetHostname(c, readbuf);
- if (Conf_NoticeAuth)
+ if (Conf_NoticeBeforeRegistration)
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Found your hostname: %s",
+ "NOTICE * :*** Found your hostname: %s",
My_Connections[i].host);
#ifdef IDENTAUTH
++identptr;
i, identptr);
Client_SetUser(c, identptr, true);
}
- if (Conf_NoticeAuth) {
+ if (Conf_NoticeBeforeRegistration) {
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** Got %sident response%s%s",
+ "NOTICE * :*** Got %sident response%s%s",
*ptr ? "invalid " : "",
*ptr ? "" : ": ",
*ptr ? "" : identptr);
}
} else if(Conf_Ident) {
Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
- if (Conf_NoticeAuth)
+ if (Conf_NoticeBeforeRegistration)
(void)Conn_WriteStr(i,
- "NOTICE AUTH :*** No ident response");
+ "NOTICE * :*** No ident response");
}
#endif
- if (Conf_NoticeAuth) {
+ if (Conf_NoticeBeforeRegistration) {
/* Send buffered data to the client, but break on
* errors because Handle_Write() would have closed
* the connection again in this case! */
* @returns Pointer to CLIENT structure.
*/
GLOBAL CLIENT *
-Conn_GetClient( CONN_ID Idx )
+Conn_GetClient( CONN_ID Idx )
{
CONNECTION *c;
* @param Reason The reason, see THROTTLE_xxx constants.
* @param Idx The connection index.
* @param Client The client of this connection.
- * @param Seconds The time to delay this connection.
+ * @param Value The time to delay this connection.
*/
static void
Throttle_Connection(const CONN_ID Idx, CLIENT *Client, const int Reason,
{
CONN_ID idx = Socket2Index(sock);
- assert(idx >= 0);
-
- if (idx < 0) {
+ if (idx <= NONE) {
io_close(sock);
return;
}
{
CONN_ID idx = Socket2Index(sock);
- assert(idx >= 0);
- if (idx < 0) {
+ (void) unused;
+
+ if (idx <= NONE) {
io_close(sock);
return;
}
- (void) unused;
+
switch (ConnSSL_Connect( &My_Connections[idx])) {
case 1: break;
case 0: LogDebug("ConnSSL_Connect: not ready");