Allow configuring listen address
authorJanne Koschinski <janne@kuschku.de>
Tue, 12 Feb 2019 21:42:26 +0000 (22:42 +0100)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 13 Feb 2019 19:26:24 +0000 (20:26 +0100)
src/common/quassel.cpp
src/core/identserver.cpp

index 440e989..afd7a84 100644 (file)
@@ -358,6 +358,7 @@ void Quassel::setupCliParser()
              tr("The port quasselcore will listen at for ident requests. Only meaningful with --ident-daemon."),
              tr("port"),
              "10113"},
+            {"ident-listen", tr("The address(es) quasselcore will listen on for ident requests."), tr("<address>[,<address>[,...]]"), "::1,127.0.0.1"},
             {"oidentd", tr("Enable oidentd integration. In most cases you should also enable --strict-ident.")},
             {"oidentd-conffile", tr("Set path to oidentd configuration file."), tr("file")},
 #ifdef HAVE_SSL
index c1cb5d0..62d68a9 100644 (file)
@@ -33,19 +33,65 @@ IdentServer::IdentServer(QObject* parent)
 
 bool IdentServer::startListening()
 {
-    uint16_t port = Quassel::optionValue("ident-port").toUShort();
-
     bool success = false;
-    if (_v6server.listen(QHostAddress("::"), port)) {
-        qInfo() << qPrintable(tr("Listening for identd clients on IPv6 %1 port %2").arg("::").arg(_v6server.serverPort()));
-
-        success = true;
-    }
 
-    if (_server.listen(QHostAddress("0.0.0.1"), port)) {
-        qInfo() << qPrintable(tr("Listening for identd clients on IPv4 %1 port %2").arg("0.0.0.1").arg(_server.serverPort()));
+    uint16_t port = Quassel::optionValue("ident-port").toUShort();
 
-        success = true;
+    const QString listen = Quassel::optionValue("ident-listen");
+    const QStringList listen_list = listen.split(",", QString::SkipEmptyParts);
+    for (const QString &listen_term : listen_list) { // TODO: handle multiple interfaces for same TCP version gracefully
+        QHostAddress addr;
+        if (!addr.setAddress(listen_term)) {
+            qCritical() << qPrintable(
+                    tr("Invalid listen address %1")
+                            .arg(listen_term)
+            );
+        }
+        else {
+            switch (addr.protocol()) {
+                case QAbstractSocket::IPv6Protocol:
+                    if (_v6server.listen(addr, port)) {
+                        qInfo() << qPrintable(
+                                tr("Listening for identd requests on IPv6 %1 port %2")
+                                        .arg(addr.toString())
+                                        .arg(_v6server.serverPort())
+                        );
+                        success = true;
+                    }
+                    else
+                        qWarning() << qPrintable(
+                                tr("Could not open IPv6 interface %1:%2: %3")
+                                        .arg(addr.toString())
+                                        .arg(port)
+                                        .arg(_v6server.errorString()));
+                    break;
+                case QAbstractSocket::IPv4Protocol:
+                    if (_server.listen(addr, port)) {
+                        qInfo() << qPrintable(
+                                tr("Listening for identd requests on IPv4 %1 port %2")
+                                        .arg(addr.toString())
+                                        .arg(_server.serverPort())
+                        );
+                        success = true;
+                    }
+                    else {
+                        // if v6 succeeded on Any, the port will be already in use - don't display the error then
+                        if (!success || _server.serverError() != QAbstractSocket::AddressInUseError)
+                            qWarning() << qPrintable(
+                                    tr("Could not open IPv4 interface %1:%2: %3")
+                                            .arg(addr.toString())
+                                            .arg(port)
+                                            .arg(_server.errorString()));
+                    }
+                    break;
+                default:
+                    qCritical() << qPrintable(
+                            tr("Invalid listen address %1, unknown network protocol")
+                                    .arg(listen_term)
+                    );
+                    break;
+            }
+        }
     }
 
     if (!success) {