Support TCP for protocol messages#3636
Conversation
5e1a658 to
0ae51e2
Compare
7ad1d1f to
d939e5b
Compare
|
So the next stage of implementation has been achieved: client-side support in the Connect dialog.
It has been tested by using Examples for a directory-enabled server running on port 22120:
Note that
|
|
The next step is to try implementing the connected-mode TCP described here |
| bool bUseTranslation = true; | ||
| bool bCustomPortNumberGiven = false; | ||
| bool bEnableIPv6 = false; | ||
| bool bEnableTcp = false; |
There was a problem hiding this comment.
Since we'll have a long time for the 4.0 release, I'd enable it by default soon (of course once we've tested that the basics work)
There was a problem hiding this comment.
No, I disagree. It's a server-only option, and most servers operators will not need to enable TCP support. Only those running large directories or large servers will need to, and they also need to understand and configure their firewall requirements.
TCP support in the client will indeed be enabled by default, but will only take effect when talking to a directory or server that has enabled it.
If a server operator enables TCP without having configured their firewall correctly, client users could have problems as the server would advertise TCP support to the client, but the client could be unable to connect.
There was a problem hiding this comment.
Can we not give an error message or fallback procedure in case the TCP connection timed out?
There was a problem hiding this comment.
Yes, I'm sure we can. I haven't yet tested that scenario.
But it doesn't negate my view that server-side TCP support needs to be an explicit option.
|
Well I've finished implementing everything I intended to, for directory, server and client, so it's ready for reviewing and trying out, as and when time permits (post 3.12.0). I have a private directory and server built and running with TCP support, at In order to demonstrate the use of TCP in a new client's connect dialog, it will be necessary to use custom firewall filters on the client end to temporarily drop incoming UDP Jamulus protocol messages containing a server list or connected clients list. There is full forward and backward compatibility between clients and servers built with TCP support and older versions. |
|
Keeping as draft, because it will need quite a few debug messages removed before merging. |
Constructor for CTcpConnection made polymorphic for client and server.
|
This is rebased and ready for thorough review now. A few comments:
|
|
I'd rather wait now until #3710 is completed, so we can include this new feature in the message being proposed there. Other than that, I can't see anything wrong with the code: that doesn't mean I fully understand it :). |
I disagree. The (The point is that the client only uses TCP when necessary, not every time in any case) So I've no problem with using #3710 purely for information that the server supports TCP connection, but that can't replace the So this PR can, or maybe even should, precede #3710, and the latter can then include the fact the feature is enabled in its own information. |
OK, I guess I don't follow this. Somewhere ( (As you've got new files, I'd like them in after the AGPL 3.0+ change, too, so you can be first to put just the AGPL 3.0+ banner on a file to show how it's done.) |
OK, I'll put something together over the next few days.
Cool, I can do that. For new files, does the header need to include lines 10-17, the part about pre/post 3.12.1dev? Or is that only applicable to existing files? |
|
For new files, no - just keep the AGPL bits. |
|
So I think I'll need significant time to review this. I won't have a lot of time for this in the next week. In the meantime we should make this production ready and cleaned up if needed. |
|
I've added |
I want to leave the commit history and the qDebug messages in place while it is being reviewed and tested. Once the team is happy with the operation, I will tidy up the commits and comment out the qDebug messages that would be too noisy for production. |
There was a problem hiding this comment.
Thanks, makes sense. Next to try and work out how the fits around it 🙂 .
| // create a TCP client connection and send message | ||
| QTcpSocket* pSocket = new QTcpSocket ( this ); | ||
|
|
||
| // timer for TCP connect timeout shorter than Qt default 30 seconds |
There was a problem hiding this comment.
If this is the keep alive timer - say that and say it's 15 seconds - rather than saying what it isn't.
There was a problem hiding this comment.
No, it's the connect timeout. Qt by default returns "connect timeout" after no acceptance for 30 seconds. There's no point waiting that long - it will either succeed within a couple of seconds or never, nowadays.
The keepalive timer is separate from that.
There was a problem hiding this comment.
OK - so still say what the number is.
Also, even though it's the client, I'd issue a warning level message with the source and dest ip/port numbers.
| pTimer->deleteLater(); | ||
|
|
||
| qWarning() << "- TCP connection error:" << pSocket->errorString(); | ||
| // may want to specifically handle ConnectionRefusedError? |
There was a problem hiding this comment.
The problem is knowing why the connection was refused. Saying "Maybe check your firewall" isn't much help. Client-side is always tricky because most diagnostics never get looked at.
| TimerPing.start ( PING_UPDATE_TIME_SERVER_LIST_MS ); | ||
| } | ||
|
|
||
| void CConnectDlg::SetTcpSupported ( const CHostAddress& InetAddr, int iID ) |
There was a problem hiding this comment.
I don't like this being UI-specific code.
The RPC interface will have the same problem.
| { | ||
| // ID out of range or channel not connected - reject connection | ||
| pTcpConnection->disconnectFromHost(); | ||
| qDebug() << "- rejected invalid client ID"; |
There was a problem hiding this comment.
Warning not Debug. This should never happen.
| { | ||
| // IP address mismatch - reject connection | ||
| pTcpConnection->disconnectFromHost(); | ||
| qDebug() << "- rejected mismatched IP address"; |
There was a problem hiding this comment.
Warning not Debug, as above.
|
|
||
| CChannel* pChannel = &vecChannels[iChanID]; | ||
|
|
||
| qDebug() << "- request to link TCP connection with UDP client at" << pChannel->GetAddress().toString(); |
There was a problem hiding this comment.
If this is the long lived connection, this should be info level.
| void OnCLReqVersionAndOS ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLVersionAndOSMes ( InetAddr ); } | ||
|
|
||
| void OnCLReqConnClientsList ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, CreateChannelList() ); } | ||
| void OnCLReqConnClientsList ( CHostAddress InetAddr, CTcpConnection* pTcpConnection ) |
There was a problem hiding this comment.
We should not really allow .h files to have multi-line methods...
|
|
||
| void CTcpConnection::OnDisconnected() | ||
| { | ||
| qDebug() << "- Jamulus-TCP: disconnected from:" << tcpAddress.toString(); |
|
|
||
| void CTcpConnection::OnTimerIdleTimeout() | ||
| { | ||
| // qDebug() << "- ConnTimeout timer" << this << "from TCP" << tcpAddress.toString(); |
There was a problem hiding this comment.
Hm. Should we ever normally get an idle timeout? Doesn't it mean something didn't clear down the connection properly?
There was a problem hiding this comment.
No, not normally. It's just to prevent a connection hanging around if a user's internet goes down suddenly without disconnecting, for example. Many types of servers implement an idle timeout for such a scenario.
There was a problem hiding this comment.
Any "should never happen", I'd like to have warnings for, really. If they do happen regularly, we'll want to know whether there's a flaw in the logic.
| QString ( "- Jamulus-TCP: Server started on %1:%2" ).arg ( pTcpServer->serverAddress().toString() ).arg ( pTcpServer->serverPort() ) ); | ||
| return true; | ||
| } | ||
| qInfo() << "- Jamulus-TCP: Unable to start server:" << pTcpServer->errorString(); |
There was a problem hiding this comment.
Logging source IP, source port, target IP and target port would be useful, though. The operator could use them to determine the cause of the problem.
Short description of changes
Support fallback to TCP for protocol messages, in order to overcome potential loss of large messages due to UDP fragmentation.
Currently an incomplete draft, for comment as development continues.CHANGELOG: Client/Server: Support TCP fallback for protocol messages.
Context: Fixes an issue?
Discussed in issue #3242.
Does this change need documentation? What needs to be documented and how?
It will need documentation once design and development are complete. Particularly need to explain the firewall requirements for a server or directory.
Status of this Pull Request
Incomplete, still under development. Main server side complete and working. Client side development in progress.Complete and ready for review and testing.Still marked draft asit needs some of the debug messages to be commented out before merging.What is missing until this pull request can be merged?
A lot of testing of both server and client. Intended for Jamulus 4.0.0.
Checklist