Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d3d653f
Add TCP handling for Server and Client
softins Jun 29, 2026
84d36ed
Add some debug messages
softins Jun 30, 2026
bac987c
Some fixes recommended by AI review
softins Jul 22, 2026
97c79f5
Use separate TCP sockets for IPv4 and IPv6
softins Jul 25, 2026
b301811
Add a channel token for use by server channels.
softins Jul 26, 2026
9179136
Use channel token to authenticate a long TCP connection
softins Jul 26, 2026
bc81d88
Add operator!= for CHostAddress for completeness
softins Jul 27, 2026
91a6e11
Check that CLM_TCP_SUPPORTED for client ID comes from the connected s…
softins Jul 27, 2026
f47eec7
Only offer TCP mode if the listener started ok
softins Jul 27, 2026
0cc9b7c
Handle unlikely situation where new TCP connection replaces old
softins Jul 27, 2026
c2aa936
Log Error or EOF from TCP socket read
softins Jul 28, 2026
b23ee9f
Update docs/TCP.md to include the channel token for TCP session authe…
softins Jul 28, 2026
12007c6
Minor change to OnReadyRead()
softins Jul 28, 2026
3281ece
Empty pending hashes when opening connect dialog
softins Jul 28, 2026
f77a7a0
Minor updates from review
softins Jul 28, 2026
e9f31fd
Do not log the channel token
softins Jul 28, 2026
c280106
Improvements from AI review
softins Jul 29, 2026
554fd72
Change "TCP supported" to "TCP offered"
softins Aug 1, 2026
473cb32
Updates to TCP.md
softins Aug 15, 2026
19fe97e
Remove debug messages in preparation for production
softins Aug 15, 2026
9580546
Formatting fixes
softins Aug 24, 2026
79f7360
Make message ID available to CL sending functions
softins Sep 7, 2026
bb27e46
Revert to UDP properly if TCP connection fails
softins Sep 7, 2026
c54d4e8
Reset TCP session state in CClient::Stop()
softins Sep 8, 2026
07b2eaf
Add docs/TCP.md to DISTFILES
softins Sep 8, 2026
2aebc02
Improvements to docs/TCP.md after review
softins Sep 8, 2026
698b7e4
Remove unused CFM_UDP_RESULT from fetch modes
softins Sep 8, 2026
edf9295
Remove noisy retry warnings
softins Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Jamulus.pro
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@ HEADERS += src/plugins/audioreverb.h \
src/serverlogging.h \
src/settings.h \
src/socket.h \
src/tcpserver.h \
src/tcpconnection.h \
src/util.h \
src/recorder/jamrecorder.h \
src/recorder/creaperproject.h \
Expand Down Expand Up @@ -520,6 +522,8 @@ SOURCES += src/plugins/audioreverb.cpp \
src/settings.cpp \
src/signalhandler.cpp \
src/socket.cpp \
src/tcpserver.cpp \
src/tcpconnection.cpp \
src/util.cpp \
src/recorder/jamrecorder.cpp \
src/recorder/creaperproject.cpp \
Expand Down
217 changes: 217 additions & 0 deletions docs/TCP.md
Comment thread
pljones marked this conversation as resolved.

Large diffs are not rendered by default.

29 changes: 28 additions & 1 deletion src/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

// CChannel implementation *****************************************************
CChannel::CChannel ( const bool bNIsServer ) :
pTcpConnection ( nullptr ),
vecfGains ( MAX_NUM_CHANNELS, 1.0f ),
vecfPannings ( MAX_NUM_CHANNELS, 0.5f ),
iCurSockBufNumFrames ( INVALID_INDEX ),
Expand All @@ -59,6 +60,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
bIsEnabled ( false ),
bIsServer ( bNIsServer ),
bIsIdentified ( false ),
iChannelToken ( 0 ),
iAudioFrameSizeSamples ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ),
SignalLevelMeter ( false, 0.5 ) // server mode with mono out and faster smoothing
{
Expand Down Expand Up @@ -103,7 +105,7 @@ CChannel::CChannel ( const bool bNIsServer ) :

QObject::connect ( &Protocol, &CProtocol::ChangeChanPan, this, &CChannel::OnChangeChanPan );

QObject::connect ( &Protocol, &CProtocol::ClientIDReceived, this, &CChannel::ClientIDReceived );
QObject::connect ( &Protocol, &CProtocol::ClientIDReceived, this, &CChannel::OnClientIDReceived );

QObject::connect ( &Protocol, &CProtocol::RawAudioSupported, this, &CChannel::RawAudioSupported );

Expand Down Expand Up @@ -764,3 +766,28 @@ void CChannel::UpdateSocketBufferSize()
SetSockBufNumFrames ( SockBuf.GetAutoSetting(), true );
}
}

void CChannel::OnClientIDReceived ( int iChanID ) { emit ClientIDReceived ( iChanID ); }

void CChannel::CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo, CProtocol& ConnLessProtocol )
{
if ( pTcpConnection )
{
ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, vecChanInfo, pTcpConnection );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make clear why the connectionless protocol is used here - I suppose since TCP handles the session, it's enough.

Comment on lines +774 to +776
}
else
{
Protocol.CreateConClientListMes ( vecChanInfo );
}
}

void CChannel::SetTcpConnection ( CTcpConnection* pConnection )
{
if ( pTcpConnection )
{
// this should never happen, but handle it if it does
pTcpConnection->disconnectFromHost();
}

pTcpConnection = pConnection;
}
20 changes: 15 additions & 5 deletions src/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,15 @@ class CChannel : public QObject
void SetEnable ( const bool bNEnStat );
bool IsEnabled() { return bIsEnabled; }

void SetChannelToken ( const quint32 iNChannelToken ) { iChannelToken = iNChannelToken; }
quint32 GetChannelToken() { return iChannelToken; }

void SetAddress ( const CHostAddress& NAddr ) { InetAddr = NAddr; }
const CHostAddress& GetAddress() const { return InetAddr; }

void SetTcpConnection ( CTcpConnection* pConnection );
CTcpConnection* GetTcpConnection() { return pTcpConnection; }

void ResetInfo(); // reset does not emit a message
QString GetName();
void SetChanInfo ( const CChannelCoreInfo& NChanInf );
Expand Down Expand Up @@ -181,7 +187,7 @@ class CChannel : public QObject
void CreateReqChannelLevelListMes() { Protocol.CreateReqChannelLevelListMes(); }
//### TODO: END ###//

void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo ) { Protocol.CreateConClientListMes ( vecChanInfo ); }
void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo, CProtocol& ConnLessProtocol );

void CreateRecorderStateMes ( const ERecorderState eRecorderState ) { Protocol.CreateRecorderStateMes ( eRecorderState ); }

Expand All @@ -206,7 +212,8 @@ class CChannel : public QObject
}

// connection parameters
CHostAddress InetAddr;
CHostAddress InetAddr;
CTcpConnection* pTcpConnection;

// channel info
CChannelCoreInfo ChannelInfo;
Expand Down Expand Up @@ -237,6 +244,8 @@ class CChannel : public QObject
bool bIsServer;
std::atomic<bool> bIsIdentified;

quint32 iChannelToken;

int iNetwFrameSizeFact;
int iNetwFrameSize;
int iCeltNumCodedBytes;
Expand Down Expand Up @@ -275,11 +284,12 @@ public slots:
PutProtocolData ( iRecCounter, iRecID, vecbyMesBodyData, RecHostAddr );
}

void OnProtocolCLMessageReceived ( int iRecID, CVector<uint8_t> vecbyMesBodyData, CHostAddress RecHostAddr )
void OnProtocolCLMessageReceived ( int iRecID, CVector<uint8_t> vecbyMesBodyData, CHostAddress RecHostAddr, CTcpConnection* pTcpConnection )
{
emit DetectedCLMessage ( vecbyMesBodyData, iRecID, RecHostAddr );
emit DetectedCLMessage ( vecbyMesBodyData, iRecID, RecHostAddr, pTcpConnection );
}

void OnClientIDReceived ( int iChanID );
void OnNewConnection() { emit NewConnection(); }

signals:
Expand All @@ -303,7 +313,7 @@ public slots:
void RecorderStateReceived ( ERecorderState eRecorderState );
void Disconnected();

void DetectedCLMessage ( CVector<uint8_t> vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr );
void DetectedCLMessage ( CVector<uint8_t> vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr, CTcpConnection* pTcpConnection );

void ParseMessageBody ( CVector<uint8_t> vecbyMesBodyData, int iRecCounter, int iRecID );
};
Loading
Loading