#include "ng_ipaddr.h"
#include "parse.h"
#include "resolve.h"
+#include "sighandlers.h"
#define SERVER_WAIT (NONE - 1) /** "Wait for outgoing connection" flag */
int i;
size_t wdatalen;
struct timeval tv;
- time_t t;
+ time_t t, notify_t = 0;
bool command_available;
+ char status[200];
Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
+ Signal_NotifySvcMgr("READY=1\n");
while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
t = time(NULL);
exit(1);
}
- /* Should ngIRCd timeout when idle? */
+ t = time(NULL);
if (Conf_IdleTimeout > 0 && NumConnectionsAccepted > 0
- && idle_t > 0 && time(NULL) - idle_t >= Conf_IdleTimeout) {
+ && idle_t > 0 && t - idle_t >= Conf_IdleTimeout) {
+ /* Should ngIRCd timeout when idle? */
LogDebug("Server idle timeout reached: %d second%s. Initiating shutdown ...",
Conf_IdleTimeout,
Conf_IdleTimeout == 1 ? "" : "s");
NGIRCd_SignalQuit = true;
+ } else if (Signal_NotifySvcMgr_Possible() && t - notify_t > 3) {
+ /* Send the current status to the service manager. */
+ snprintf(status, sizeof(status),
+ "WATCHDOG=1\nSTATUS=%ld connection%s established (%ld user%s, %ld server%s), %ld maximum. %ld accepted in total.\n",
+ (long)NumConnections, NumConnections == 1 ? "" : "s",
+ Client_MyUserCount(), Client_MyUserCount() == 1 ? "" : "s",
+ Client_MyServerCount(), Client_MyServerCount() == 1 ? "" : "s",
+ (long)NumConnectionsMax, (long)NumConnectionsAccepted);
+ Signal_NotifySvcMgr(status);
+ notify_t = t;
}
}
- if (NGIRCd_SignalQuit)
+ if (NGIRCd_SignalQuit) {
Log(LOG_NOTICE | LOG_snotice, "Server going down NOW!");
- else if (NGIRCd_SignalRestart)
+ Signal_NotifySvcMgr("STOPPING=1\n");
+ } else if (NGIRCd_SignalRestart) {
Log(LOG_NOTICE | LOG_snotice, "Server restarting NOW!");
+ Signal_NotifySvcMgr("RELOADING=1\n");
+ }
} /* Conn_Handler */
/**
/**
* IO callback for new outgoing SSL-enabled server connections.
*
+ * IMPORTANT: The SSL session has been validated before, but all errors have
+ * been ignored so far! The reason for this is that the generic SSL code has no
+ * idea if the new session actually belongs to a server, as this only becomes
+ * clear when the remote peer sends its PASS command (and we have to handle
+ * invalid client certificates!). Therefore, it is important to check the
+ * status of the SSL session first before continuing the server handshake here!
+ *
* @param sock Socket descriptor.
* @param unused (ignored IO specification)
*/
cb_connserver_login_ssl(int sock, short unused)
{
CONN_ID idx = Socket2Index(sock);
+ int serveridx;
(void) unused;
return;
}
- Log( LOG_INFO, "SSL connection %d with \"%s:%d\" established.", idx,
- My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port );
+ serveridx = Conf_GetServer(idx);
+ assert(serveridx >= 0);
+ /* The SSL handshake is done, but validation results were ignored so
+ * far, so let's see where we are: */
+ LogDebug("SSL handshake on socket %d done.", idx);
+ if (!Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_PEERCERT_OK)) {
+ if (Conf_Server[serveridx].SSLVerify) {
+ Log(LOG_ERR,
+ "Peer certificate check failed for \"%s\" on connection %d!",
+ My_Connections[idx].host, idx);
+ Conn_Close(idx, "Valid certificate required",
+ NULL, false);
+ return;
+ }
+ Log(LOG_WARNING,
+ "Peer certificate check failed for \"%s\" on connection %d, but \"SSLVerify\" is disabled. Continuing ...",
+ My_Connections[idx].host, idx);
+ }
+ LogDebug("Server certificate accepted, continuing server login ...");
server_login(idx);
}