Allow to set Local Socket listen(2) backlog

Unix sockets do not suffer from SYN flood, thus the hardcoded value to
50 is size of the only queue to hold connections to be accepted,
resulting in dropped connections when the limit is reached.

On Windows the hardcoded value is 8, this patch changes the default to
50 matching UNIX.

[ChangeLog][QtNetwork][QLocalServer] Added setListenBacklogSize() to
be able to have control over the listen backlog feature.

Change-Id: Iaee6349a46b75b0bd05e40e7ade5948f1cf9f407
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Daniel Nicoletti 2021-06-30 17:18:02 -03:00
parent e4fd86d53a
commit 8f75ab231f
8 changed files with 46 additions and 14 deletions

View File

@ -554,6 +554,36 @@ bool QLocalServer::waitForNewConnection(int msec, bool *timedOut)
return !d->pendingConnections.isEmpty();
}
/*!
Sets the backlog queue size of to be accepted connections to \a
size. The operating system might reduce or ignore this value.
By default, the queue size is 50.
\note This property must be set prior to calling listen().
\since 6.3
\sa listenBacklogSize()
*/
void QLocalServer::setListenBacklogSize(int size)
{
Q_D(QLocalServer);
d->listenBacklog = size;
}
/*!
Returns the backlog queue size of to be accepted connections.
\since 6.3
\sa setListenBacklogSize()
*/
int QLocalServer::listenBacklogSize() const
{
Q_D(const QLocalServer);
return d->listenBacklog;
}
QT_END_NAMESPACE
#include "moc_qlocalserver.cpp"

View File

@ -93,6 +93,9 @@ public:
void setMaxPendingConnections(int numConnections);
bool waitForNewConnection(int msec = 0, bool *timedOut = nullptr);
void setListenBacklogSize(int size);
int listenBacklogSize() const;
void setSocketOptions(SocketOptions options);
SocketOptions socketOptions() const;
QBindable<SocketOptions> bindableSocketOptions();

View File

@ -126,6 +126,7 @@ public:
QQueue<QLocalSocket*> pendingConnections;
QString errorString;
QAbstractSocket::SocketError error;
int listenBacklog = 50;
Q_OBJECT_BINDABLE_PROPERTY(QLocalServerPrivate, QLocalServer::SocketOptions, socketOptions)
};

View File

@ -56,6 +56,8 @@ void QLocalServerPrivate::init()
bool QLocalServerPrivate::listen(const QString &requestedServerName)
{
tcpServer.setListenBacklogSize(listenBacklog);
if (!tcpServer.listen(QHostAddress::LocalHost))
return false;

View File

@ -184,7 +184,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
}
// listen for connections
if (-1 == qt_safe_listen(listenSocket, 50)) {
if (-1 == qt_safe_listen(listenSocket, listenBacklog)) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;

View File

@ -53,9 +53,6 @@
// before it is read. Pipewriter is used for write buffering.
#define BUFSIZE 0
// ###: This should be a property. Should replace the insane 50 on unix as well.
#define SYSTEM_MAX_PENDING_SOCKETS 8
QT_BEGIN_NAMESPACE
bool QLocalServerPrivate::addListener()
@ -256,7 +253,7 @@ bool QLocalServerPrivate::listen(const QString &name)
connectionEventNotifier = new QWinEventNotifier(eventHandle , q);
q->connect(connectionEventNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_onNewConnection()));
for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i)
for (int i = 0; i < listenBacklog; ++i)
if (!addListener())
return false;

View File

@ -654,26 +654,25 @@ int QTcpServer::maxPendingConnections() const
size. The operating system might reduce or ignore this value.
By default, the queue size is 50.
\note This setting is only used when listen() is called.
\note This property must be set prior to calling listen().
\since 6.3
\sa listenBacklog()
\sa listenBacklogSize()
*/
void QTcpServer::setListenBacklog(int size)
void QTcpServer::setListenBacklogSize(int size)
{
d_func()->listenBacklog = size;
}
/*!
Returns the backlog queue size of to be accepted connections. The
default is 50.
Returns the backlog queue size of to be accepted connections.
\since 6.3
\sa setListenBacklog()
\sa setListenBacklogSize()
*/
int QTcpServer::listenBacklog() const
int QTcpServer::listenBacklogSize() const
{
return d_func()->listenBacklog;
}

View File

@ -69,8 +69,8 @@ public:
void setMaxPendingConnections(int numConnections);
int maxPendingConnections() const;
void setListenBacklog(int size);
int listenBacklog() const;
void setListenBacklogSize(int size);
int listenBacklogSize() const;
quint16 serverPort() const;
QHostAddress serverAddress() const;