1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-03-04 00:18:10 +00:00

Fix cb_connserver() to handle aborted outgoing connections

A configured server could have been removed while a connection apptempt
is still in progress. So the cb_connserver() callback has to test if the
server configuration record is still valid.
This commit is contained in:
Alexander Barton 2009-09-12 00:17:42 +02:00
parent 4daf780f01
commit 536538968c

View File

@ -143,21 +143,33 @@ cb_listen_ssl(int sock, short irrelevant)
static void static void
cb_connserver(int sock, UNUSED short what) cb_connserver(int sock, UNUSED short what)
{ {
int res, err; int res, err, server;
socklen_t sock_len; socklen_t sock_len;
CONN_ID idx = Socket2Index( sock ); CONN_ID idx = Socket2Index( sock );
if (idx <= NONE) { if (idx <= NONE) {
LogDebug("cb_connserver wants to write on unknown socket?!"); LogDebug("cb_connserver wants to write on unknown socket?!");
io_close(sock); io_close(sock);
return; return;
} }
assert( what & IO_WANTWRITE); assert(what & IO_WANTWRITE);
/* Make sure that the server is still configured; it could have been
* removed in the meantime! */
server = Conf_GetServer(idx);
if (server < 0) {
Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
sock, My_Connections[idx].host);
Conn_Close(idx, "Connection aborted!", NULL, false);
return;
}
/* connect() finished, get result. */ /* connect() finished, get result. */
sock_len = (socklen_t)sizeof(err); sock_len = (socklen_t)sizeof(err);
res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len ); res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
assert( sock_len == sizeof( err )); &err, &sock_len );
assert(sock_len == sizeof(err));
/* Error while connecting? */ /* Error while connecting? */
if ((res != 0) || (err != 0)) { if ((res != 0) || (err != 0)) {
@ -167,32 +179,28 @@ cb_connserver(int sock, UNUSED short what)
else else
Log(LOG_CRIT, Log(LOG_CRIT,
"Can't connect socket to \"%s:%d\" (connection %d): %s!", "Can't connect socket to \"%s:%d\" (connection %d): %s!",
My_Connections[idx].host, My_Connections[idx].host, Conf_Server[server].port,
Conf_Server[Conf_GetServer(idx)].port,
idx, strerror(err)); idx, strerror(err));
res = Conf_GetServer(idx);
assert(res >= 0);
Conn_Close(idx, "Can't connect!", NULL, false); Conn_Close(idx, "Can't connect!", NULL, false);
if (res < 0) if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
return;
if (ng_ipaddr_af(&Conf_Server[res].dst_addr[0])) {
/* more addresses to try... */ /* more addresses to try... */
New_Server(res, &Conf_Server[res].dst_addr[0]); New_Server(res, &Conf_Server[server].dst_addr[0]);
/* connection to dst_addr[0] in progress, remove this address... */ /* connection to dst_addr[0] is now in progress, so
Conf_Server[res].dst_addr[0] = Conf_Server[res].dst_addr[1]; * remove this address... */
Conf_Server[server].dst_addr[0] =
memset(&Conf_Server[res].dst_addr[1], 0, sizeof(Conf_Server[res].dst_addr[1])); Conf_Server[server].dst_addr[1];
memset(&Conf_Server[server].dst_addr[1], 0,
sizeof(Conf_Server[server].dst_addr[1]));
} }
return; return;
} }
res = Conf_GetServer(idx); /* connect() succeeded, remove all additional addresses */
assert(res >= 0); memset(&Conf_Server[server].dst_addr, 0,
if (res >= 0) /* connect succeeded, remove all additional addresses */ sizeof(Conf_Server[server].dst_addr));
memset(&Conf_Server[res].dst_addr, 0, sizeof(Conf_Server[res].dst_addr));
Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING ); Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
#ifdef SSL_SUPPORT #ifdef SSL_SUPPORT
if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) { if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {