<div dir="auto"><div>First of all, thank you Jason for detailed analysis of the QWS' source and tips about what can be done next.</div><div dir="auto"><br></div><div dir="auto">I will of course report this to Qt JIRA as soon as I rule out error on my end. </div><div dir="auto"><br></div><div dir="auto">About the stuff with endsWith(), keep in mind that I have long periods of time when server works just fine. Clinets can connect to it and their connection method is just the same. </div><div dir="auto"><br></div><div dir="auto">When we test connection to the server we either use our client - game written in Unity3D, or its WebGL version deployed to the Facebook's GameRoom.</div><div dir="auto"><br></div><div dir="auto">Currently our server has disabled preemptive client authorization, so even using <a href="https://www.websocket.org/echo.html">https://www.websocket.org/echo.html</a> is sufficient to connect.</div><div dir="auto"><br></div><div dir="auto">In either case, connection is rejected.</div><div dir="auto"><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Thu, 4 Apr 2019, 17:03 Jason H, <<a href="mailto:jhihn@gmx.com" target="_blank" rel="noreferrer">jhihn@gmx.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That's NOT what I was going for!! I specifically said I have not tested any of those theories. I ALSO said I have used it successfully. Do not let my speculation hold you up. The more eyes (users) we have on this the better it will be. <br>
<br>
At this point Jakub should probably file a bug at <a href="https://bugreports.qt.io/secure/Dashboard.jspa" rel="noreferrer noreferrer noreferrer" target="_blank">https://bugreports.qt.io/secure/Dashboard.jspa</a> , as this is not my bug and I have no ability to reproduce it. Feel free to attach my speculation and/or tag me. <br>
<br>
Given that it takes a while for this to show up, I'm increasingly confident that the endsWith() is the issue. A slow client might deliver the bytes in an unpredictable way. If the client doesn't wait to send the request after a successful header, and just sends it blindly, endsWith() won't work. <br>
<br>
Also, I am looking at the wireshark pcap and there is no 0d 0a ("\r\n") sequence (much less 0a 0a 0d 0a ("\r\n\r\n"), so maybe it's the client's fault? So I could also still be TOTALLY wrong. <br>
<br>
> Sent: Thursday, April 04, 2019 at 10:41 AM<br>
> From: "alexander golks" <<a href="mailto:alex@golks.de" rel="noreferrer noreferrer" target="_blank">alex@golks.de</a>><br>
> To: No recipient address<br>
> Cc: <a href="mailto:interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">interest@qt-project.org</a><br>
> Subject: Re: [Interest] QWebSocketServer - server randomly stops accepting connections<br>
><br>
> i was going to switch some codebase to websocket server, too,<br>
> but reading this lets me think again...<br>
> <br>
> thanks ;)<br>
> <br>
> Am Thu, 4 Apr 2019 16:33:19 +0200<br>
> schrieb "Jason H" <<a href="mailto:jhihn@gmx.com" rel="noreferrer noreferrer" target="_blank">jhihn@gmx.com</a>>:<br>
> <br>
> > I looked at the private implementation of QWebSocketServer, QWebSocketServerPrivate.<br>
> >  <br>
> > I haven't tested it, but there are a few concerns:<br>
> >  <br>
> > 1. That for errorString(), it first checks if it doesn't have an error then returns the QTcpSocket errorString(). But if you just look at serverError() it only reports it's own error and nothing at the QTcpSocket level. This means that if you only check serverError() you won't catch QTcpServer error. This is probably a bug. QWebSocketProtocol::CloseCode needs to be able to express QAbstractSocket::SocketErrors as well.<br>
> >  <br>
> > 2. QWebSocketServerPrivate::handshakeReceived() has a check of pTcpSocket->bytesAvailable()).endsWith(QByteArrayLiteral("\r\n\r\n") Such position-reliant checks are bad form. There's no reason for it to end with, it should probably be using contains()<br>
> >  <br>
> > 3. There are multiple `if` blocks that don't set an error. This isn't wrong, as the handhake bytes may come in slowly and take multiple re-parsings, (something to add to your fuzzer?) but you can wind up in an uncaught error state.<br>
> >  <br>
> >  <br>
> >  <br>
> > Sent: Thursday, April 04, 2019 at 10:07 AM<br>
> > From: "Jason H" <<a href="mailto:jhihn@gmx.com" rel="noreferrer noreferrer" target="_blank">jhihn@gmx.com</a>><br>
> > To: "Narolewski Jakub" <<a href="mailto:izowiuz@gmail.com" rel="noreferrer noreferrer" target="_blank">izowiuz@gmail.com</a>><br>
> > Cc: <a href="mailto:interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">interest@qt-project.org</a><br>
> > Subject: Re: [Interest] QWebSocketServer - server randomly stops accepting connections<br>
> > So, yeah, I was thinking of QTcpServer::incommingConnection(). That function is used in multithreadding because you use the descriptor to make a socket on the proper thread. Looks like QWebSocketServer is not multithreaded. <br>
> >  <br>
> > I've used Qt's websockets, and I've used QTcpServer extensively on 5-nines stuff. Never saw anything like this. <br>
> >  <br>
> > Next steps: <br>
> > - QWebSocketServer::setMaxPendingConnections() set this to 0, 1, or 100, see what (if anything) changes.<br>
> > - Use QTcpServer to and QWebSocketServer::handleConnection(QTcpSocket*) to handle the connection yourself just to get QWebSocketServer out of the initial connection stuff.<br>
> >  <br>
> > Whatever the cause, I think you're in bug territory, either in Qt or the linux kernel. Both of those is unlikely.  There is one more possibilty, if you're using secure sockets, maybe something is failing at the SSL level? Like your SSL implementation stops working for whatever reason?<br>
> >  <br>
> > Sent: Thursday, April 04, 2019 at 9:13 AM<br>
> > From: "Narolewski Jakub" <<a href="mailto:izowiuz@gmail.com" rel="noreferrer noreferrer" target="_blank">izowiuz@gmail.com</a>><br>
> > To: "Jason H" <<a href="mailto:jhihn@gmx.com" rel="noreferrer noreferrer" target="_blank">jhihn@gmx.com</a>><br>
> > Cc: <a href="mailto:interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">interest@qt-project.org</a><br>
> > Subject: Re: [Interest] QWebSocketServer - server randomly stops accepting connections<br>
> > That's the thing. I already handle connections and disconnections in my code - including logging relevant information.<br>
> > When I implemented this I heavily based on the example that you linked to.<br>
> > WSS communication is single threaded - only way to communicate with the outside world from different thread is to send custom QEvent onto the Server instance.<br>
> > QWebSocketServer does not seem to have the method incomingConnection in it's public API or maybe I already went mad :P I react to the QWebSocketServer::newConnection signal.<br>
> > <br>
> > Last RST from client at 33 second mark is our client-side timeout.<br>
> > This is the code that handles websocket stuff, I have stripped some parts that are less important:<br>
> > <br>
> > // server connects<br>
> > connect(m_wsServer, &QWebSocketServer::acceptError, this, [this](QAbstractSocket::SocketError socketError) {<br>
> >         qCritical() << "QWebSocketServer - acceptError:" << socketError;<br>
> > });<br>
> > <br>
> > connect(m_wsServer, &QWebSocketServer::peerVerifyError, this, [this](const QSslError& error) {<br>
> >         qCritical() << "QWebSocketServer - peerVerifyError:" << error;<br>
> > });<br>
> > <br>
> > connect(m_wsServer, &QWebSocketServer::serverError, this, [this](QWebSocketProtocol::CloseCode closeCode) {<br>
> >         qCritical() << "QWebSocketServer - serverError:" << closeCode;<br>
> > });<br>
> > <br>
> > connect(m_wsServer, &QWebSocketServer::sslErrors, this, [this](const QList<QSslError>& errors) {<br>
> >         qCritical() << "QWebSocketServer - sslErrors:" << errors;<br>
> > });<br>
> > <br>
> > connect(m_wsServer, &QWebSocketServer::closed, this, [this]() {<br>
> >         qCritical() << "QWebSocketServer - closed, serverError():" << m_wsServer->errorString();<br>
> > });<br>
> > <br>
> > connect(m_wsServer, &QWebSocketServer::newConnection, this, [this]() {<br>
> >         QWebSocket* clientSocket = m_wsServer->nextPendingConnection();<br>
> >         qInfo() << "Got connection from client:" << clientSocket->peerAddress();<br>
> > <br>
> >         [ client initialization stuff ]<br>
> > <br>
> >         connect(clientSocket, &QWebSocket::binaryMessageReceived, this, [this](const QByteArray& message) {<br>
> >                 auto client = sender()->property("client").value<Client*>();<br>
> > <br>
> >                 [ message deserialization ]<br>
> >         });<br>
> > <br>
> >         connect(clientSocket, &QWebSocket::disconnected, this, [this]() {<br>
> >                 auto client = sender()->property("client").value<Client*>();<br>
> >                 qInfo() << client->sayHello() << "is disconnected.";<br>
> > <br>
> >                 client->handleDisconnection();<br>
> > <br>
> >                 [ clinet cleanup stuff ]<br>
> >         });<br>
> > });<br>
> > <br>
> > Client's handleDisconnection() function does:<br>
> > <br>
> > void i9ms::Client::handleDisconnection()<br>
> > {<br>
> >         m_isConnected = false;<br>
> >         m_websocket->deleteLater();<br>
> >         m_websocket   = nullptr;<br>
> > }<br>
> > <br>
> > Nothing from this lands in system logs. It seems that QWebSocketServer::newConnection() is just not emited.<br>
> > As I wrote earlier I have a timerEvent that logs QWebSocketServer's state - once every ten minutes.<br>
> > It happily reports that server is listening, has no pending connections and it's internal 'errorString' is empty - even if it is mute from the outside.<br>
> > <br>
> > It's hard for me to pinpoint exactly what causes this. 'Time' is my best guess.<br>
> > I'm also not sure if quantity of connections plays a role here.<br>
> > <br>
> > I have a 'fuzzer-bot' that spams hundreds of connections and messages at the server in short period of time.<br>
> > Malformed messages, out-of-order client state changes, ugly words - you name it we have it.<br>
> > QWebSocketServer handles it well enough for us but then, at some time in future WHILE being completely idle, server goes silent.<br>
> > On the other hand I can start the server, connect - disconnect one client, leave it for a while in idle and same thing happens, leaving me one step closer to dementia.<br>
> >  <br>
> > On Wed, 3 Apr 2019, 22:32 Jason H, <<a href="mailto:jhihn@gmx.com" rel="noreferrer noreferrer" target="_blank">jhihn@gmx.com</a>> wrote:<br>
> > Addendum, <br>
> > >  <br>
> > > How much does you code diverge from the example? <a href="https://doc.qt.io/qt-5/echoserver.html" rel="noreferrer noreferrer noreferrer" target="_blank">https://doc.qt.io/qt-5/echoserver.html</a><br>
> > > Can you hack that to receive your traffic or augment your code to to do what it does?<br>
> > > Note that the QWebSocket server does not take ownership of the QWebSocket, you have to track that manually. Using the code they provide, I would also log your connected clients. See the slot EchoServer::socketDisconnected()<br>
> > > _______________________________________________ Interest mailing list <a href="mailto:Interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">Interest@qt-project.org</a> <a href="https://lists.qt-project.org/listinfo/interest" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.qt-project.org/listinfo/interest</a><br>
> > <br>
> <br>
> <br>
> -- <br>
> /*<br>
>  *  printk(KERN_ERR "happy meal: Transceiver BigMac ATTACK!");<br>
>  *    linux-2.6.19/drivers/net/sunhme.c<br>
>  */<br>
> _______________________________________________<br>
> Interest mailing list<br>
> <a href="mailto:Interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">Interest@qt-project.org</a><br>
> <a href="https://lists.qt-project.org/listinfo/interest" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.qt-project.org/listinfo/interest</a><br>
><br>
_______________________________________________<br>
Interest mailing list<br>
<a href="mailto:Interest@qt-project.org" rel="noreferrer noreferrer" target="_blank">Interest@qt-project.org</a><br>
<a href="https://lists.qt-project.org/listinfo/interest" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.qt-project.org/listinfo/interest</a><br>
</blockquote></div></div></div>