commit - 84e24afd2f6607a2345c4df2b2f9ad81e9dd4bbc
commit + 8ab097afb743061c6c9b865bdb401ba51285c347
blob - 09b43a68a8bb71ef5ba2fb3dd02f9cee1f04bf14
blob + 6d16f7cac50f8b177fb4d336201906733b0a3607
--- contrib/Makefile.am
+++ contrib/Makefile.am
#
# ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2013 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
ngIRCd-Logo.gif \
ngircd-redhat.init \
ngircd.service \
+ ngircd.socket \
ngircd.spec \
platformtest.sh \
systrace.policy
blob - f3730a4e969c69aed07bbfdfb737a7901b382fa8
blob + 2d639e664076d19c8b20a23e50a4d6426ddd6953
--- contrib/README
+++ contrib/README
ngircd.service
- systemd(8) service unit configuration file.
+ngircd.socket
+ - systemd(8) socket unit configuration file for "socket activation".
+
ngircd.spec
- RPM "spec" file.
blob - /dev/null
blob + 3838efcc1c278e315693d307013c4e8b2be41b09 (mode 644)
--- /dev/null
+++ contrib/ngircd.socket
+[Unit]
+Description=Next Generation IRC Daemon (Socket)
+
+[Socket]
+ListenStream=6667
+#ListenStream=6668
+IPTOS=low-delay
+
+[Install]
+WantedBy=sockets.target
blob - 14d337b9408265b1213a157cd36cf66a8efc057e
blob + 378509f96f09bc35eb9e3ebc2eb12140c24509fb
--- src/ngircd/conn.c
+++ src/ngircd/conn.c
#define MAX_COMMANDS_SERVER_MIN 10
#define MAX_COMMANDS_SERVICE 10
+#define SD_LISTEN_FDS_START 3
+
static bool Handle_Write PARAMS(( CONN_ID Idx ));
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
static int New_Connection PARAMS(( int Sock, bool IsSSL ));
static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
static void cb_clientserver PARAMS((int sock, short what));
+
+
+/**
+ * Get number of sockets available from systemd(8).
+ *
+ * ngIRCd needs to implement its own sd_listen_fds(3) function and can't
+ * use the one provided by systemd itself, becaus the sockets will be
+ * used in a forked child process with a new PID, and this would trigger
+ * an error in the standard implementation.
+ *
+ * @return Number of sockets available, -1 if sockets have already been
+ * initialized, or 0 when no sockets have been passed.
+ */
+static int
+my_sd_listen_fds(void)
+{
+ const char *e;
+ long count;
+
+ /* Check if LISTEN_PID exists; but we ignore the result, because
+ * normally ngircd forks a child before checking this, and therefore
+ * the PID set in the environment is always wrong ... */
+ e = getenv("LISTEN_PID");
+ if (!e || !*e)
+ return 0;
+
+ e = getenv("LISTEN_FDS");
+ if (!e || !*e)
+ return -1;
+ count = atol(e);
+ unsetenv("LISTEN_FDS");
+
+ return count;
+}
/**
/* Initialize ports on which the server should accept connections */
unsigned int created = 0;
char *copy, *listen_addr;
+ int count, fd, i;
assert(Conf_ListenAddress);
+
+ count = my_sd_listen_fds();
+ if (count < 0) {
+ Log(LOG_INFO,
+ "Not re-initializing listening sockets of systemd(8) ...");
+ return 0;
+ }
+ if (count > 0) {
+ /* systemd(8) passed sockets to us, so don't try to initialize
+ * listening sockets on our own but use the passed ones */
+ LogDebug("Initializing %d systemd sockets ...", count);
+ for (i = 0; i < count; i++) {
+ fd = SD_LISTEN_FDS_START + i;
+ Init_Socket(fd);
+ if (!io_event_create(fd, IO_WANTREAD, cb_listen)) {
+ Log(LOG_ERR,
+ "io_event_create(): Can't add fd %d: %s!",
+ fd, strerror(errno));
+ continue;
+ }
+ Log(LOG_INFO,
+ "Initialized socket %d from systemd.", fd);
+ created++;
+ }
+ return created;
+ }
+ /* not using systemd socket activation, initialize listening sockets: */
+
/* can't use Conf_ListenAddress directly, see below */
copy = strdup(Conf_ListenAddress);
if (!copy) {
int *fd;
size_t arraylen;
+ /* Get number of listening sockets to shut down. There can be none
+ * if ngIRCd has been "socket activated" by systemd. */
arraylen = array_length(&My_Listeners, sizeof (int));
+ if (arraylen < 1)
+ return;
+
Log(LOG_INFO,
"Shutting down all listening sockets (%d total) ...", arraylen);
fd = array_start(&My_Listeners);