cliParser->addSwitch("strict-ident", 0, "Use users' quasselcore username as ident reply. Ignores each user's configured ident setting.");
cliParser->addSwitch("ident-daemon", 0, "Enable internal ident daemon");
cliParser->addOption("ident-port", 0, "The port quasselcore will listen at for ident requests. Only meaningful with --ident-daemon", "port", "10113");
+ cliParser->addOption("ident-listen", 0, "The address(es) quasselcore will listen on for ident requests", "<address>[,<address>[,...]]", "::1,127.0.0.1");
#ifdef HAVE_SSL
cliParser->addSwitch("require-ssl", 0, "Require SSL for remote (non-loopback) client connections");
cliParser->addOption("ssl-cert", 0, "Specify the path to the SSL Certificate", "path", "configdir/quasselCert.pem");
bool IdentServer::startListening()
{
- uint16_t port = Quassel::optionValue("ident-port").toUShort();
-
bool success = false;
- if (_v6server.listen(QHostAddress("::"), port)) {
- quInfo() << qPrintable(
- tr("Listening for identd clients on IPv6 %1 port %2")
- .arg("::")
- .arg(_v6server.serverPort())
- );
-
- success = true;
- }
- if (_server.listen(QHostAddress("0.0.0.0"), port)) {
- quInfo() << qPrintable(
- tr("Listening for identd clients on IPv4 %1 port %2")
- .arg("0.0.0.0")
- .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)) {
+ quInfo() << qPrintable(
+ tr("Listening for identd requests on IPv6 %1 port %2")
+ .arg(addr.toString())
+ .arg(_v6server.serverPort())
+ );
+ success = true;
+ }
+ else
+ quWarning() << 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)) {
+ quInfo() << 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)
+ quWarning() << 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) {