Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -399,6 +399,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 @@ -507,6 +509,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
12 changes: 8 additions & 4 deletions src/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class CChannel : public QObject
void SetAddress ( const CHostAddress& NAddr ) { InetAddr = NAddr; }
const CHostAddress& GetAddress() const { return InetAddr; }

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

void ResetInfo()
{
bIsIdentified = false;
Expand Down Expand Up @@ -186,7 +189,8 @@ class CChannel : public QObject
}

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

// channel info
CChannelCoreInfo ChannelInfo;
Expand Down Expand Up @@ -255,9 +259,9 @@ 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 OnNewConnection() { emit NewConnection(); }
Expand All @@ -282,7 +286,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 );
};
49 changes: 45 additions & 4 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ CClient::CClient ( const quint16 iPortNumber,

QObject::connect ( &ConnLessProtocol, &CProtocol::CLRedServerListReceived, this, &CClient::CLRedServerListReceived );

QObject::connect ( &ConnLessProtocol, &CProtocol::CLTcpSupported, this, &CClient::CLTcpSupported );

QObject::connect ( &ConnLessProtocol, &CProtocol::CLConnClientsListMesReceived, this, &CClient::CLConnClientsListMesReceived );

QObject::connect ( &ConnLessProtocol, &CProtocol::CLPingReceived, this, &CClient::OnCLPingReceived );
Expand Down Expand Up @@ -249,11 +251,50 @@ void CClient::OnSendProtMessage ( CVector<uint8_t> vecMessage )
Socket.SendPacket ( vecMessage, Channel.GetAddress() );
}

void CClient::OnSendCLProtMessage ( CHostAddress InetAddr, CVector<uint8_t> vecMessage )
void CClient::OnSendCLProtMessage ( CHostAddress InetAddr, CVector<uint8_t> vecMessage, CTcpConnection* pTcpConnection, bool bUseTcpClient )
{
if ( pTcpConnection )
{
qWarning() << "Client send cannot use TCP server";
return;
}

// the protocol queries me to call the function to send the message
// send it through the network
Socket.SendPacket ( vecMessage, InetAddr );
if ( bUseTcpClient )
{
// create a TCP client connection and send message
QTcpSocket* pSocket = new QTcpSocket ( this );

#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 )
# define ERRORSIGNAL &QTcpSocket::errorOccurred
#else
# define ERRORSIGNAL QOverload<QAbstractSocket::SocketError>::of ( &QAbstractSocket::error )
#endif
connect ( pSocket, ERRORSIGNAL, this, [this, pSocket] ( QAbstractSocket::SocketError err ) {
Q_UNUSED ( err );

qWarning() << "- TCP connection error:" << pSocket->errorString();
// may want to specifically handle ConnectionRefusedError?
pSocket->deleteLater();
} );

connect ( pSocket, &QTcpSocket::connected, this, [this, pSocket, InetAddr, vecMessage]() {
// connection succeeded, give it to a CTcpConnection
CTcpConnection* pTcpConnection =
new CTcpConnection ( pSocket, InetAddr, nullptr, &Channel ); // client connection, will self-delete on disconnect

pTcpConnection->write ( (const char*) &( (CVector<uint8_t>) vecMessage )[0], vecMessage.Size() );

// the CTcpConnection object will pass the reply back up to CClient::Channel
} );

pSocket->connectToHost ( InetAddr.InetAddr, InetAddr.iPort );
}
else
{
Socket.SendPacket ( vecMessage, InetAddr );
}
}

void CClient::OnInvalidPacketReceived ( CHostAddress RecHostAddr )
Expand All @@ -268,10 +309,10 @@ void CClient::OnInvalidPacketReceived ( CHostAddress RecHostAddr )
}
}

void CClient::OnDetectedCLMessage ( CVector<uint8_t> vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr )
void CClient::OnDetectedCLMessage ( CVector<uint8_t> vecbyMesBodyData, int iRecID, CHostAddress RecHostAddr, CTcpConnection* pTcpConnection )
{
// connection less messages are always processed
ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, iRecID, RecHostAddr );
ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, iRecID, RecHostAddr, pTcpConnection );
}

void CClient::OnJittBufSizeChanged ( int iNewJitBufSize )
Expand Down
16 changes: 12 additions & 4 deletions src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,15 @@ class CClient : public QObject

void CreateCLServerListReqVerAndOSMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqVersionAndOSMes ( InetAddr ); }

void CreateCLServerListReqConnClientsListMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqConnClientsListMes ( InetAddr ); }
void CreateCLServerListReqConnClientsListMes ( const CHostAddress& InetAddr, bool bUseTcpClient )
{
ConnLessProtocol.CreateCLReqConnClientsListMes ( InetAddr, bUseTcpClient );
}

void CreateCLReqServerListMes ( const CHostAddress& InetAddr ) { ConnLessProtocol.CreateCLReqServerListMes ( InetAddr ); }
void CreateCLReqServerListMes ( const CHostAddress& InetAddr, bool bUseTcpClient )
{
ConnLessProtocol.CreateCLReqServerListMes ( InetAddr, bUseTcpClient );
}

int EstimatedOverallDelay ( const int iPingTimeMs );

Expand Down Expand Up @@ -427,7 +433,7 @@ protected slots:
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
void OnInvalidPacketReceived ( CHostAddress RecHostAddr );

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

void OnReqJittBufSize() { CreateServerJitterBufferMessage(); }
void OnJittBufSizeChanged ( int iNewJitBufSize );
Expand All @@ -442,7 +448,7 @@ protected slots:
}
void OnCLPingReceived ( CHostAddress InetAddr, int iMs );

void OnSendCLProtMessage ( CHostAddress InetAddr, CVector<uint8_t> vecMessage );
void OnSendCLProtMessage ( CHostAddress InetAddr, CVector<uint8_t> vecMessage, CTcpConnection* pTcpConnection, bool bUseTcpClient );

void OnCLPingWithNumClientsReceived ( CHostAddress InetAddr, int iMs, int iNumClients );

Expand Down Expand Up @@ -471,6 +477,8 @@ protected slots:

void CLRedServerListReceived ( CHostAddress InetAddr, CVector<CServerInfo> vecServerInfo );

void CLTcpSupported ( CHostAddress InetAddr, int iID );

void CLConnClientsListMesReceived ( CHostAddress InetAddr, CVector<CChannelInfo> vecChanInfo );

void CLPingTimeWithNumClientsReceived ( CHostAddress InetAddr, int iPingTime, int iNumClients );
Expand Down
2 changes: 2 additions & 0 deletions src/clientdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ CClientDlg::CClientDlg ( CClient* pNCliP,

QObject::connect ( pClient, &CClient::CLRedServerListReceived, this, &CClientDlg::OnCLRedServerListReceived );

QObject::connect ( pClient, &CClient::CLTcpSupported, this, &CClientDlg::OnCLTcpSupported );

QObject::connect ( pClient, &CClient::CLConnClientsListMesReceived, this, &CClientDlg::OnCLConnClientsListMesReceived );

QObject::connect ( pClient, &CClient::CLPingTimeWithNumClientsReceived, this, &CClientDlg::OnCLPingTimeWithNumClientsReceived );
Expand Down
9 changes: 7 additions & 2 deletions src/clientdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,16 @@ public slots:

void OnNewLocalInputText ( QString strChatText ) { pClient->CreateChatTextMes ( strChatText ); }

void OnReqServerListQuery ( CHostAddress InetAddr ) { pClient->CreateCLReqServerListMes ( InetAddr ); }
void OnReqServerListQuery ( CHostAddress InetAddr, bool bUseTcpClient ) { pClient->CreateCLReqServerListMes ( InetAddr, bUseTcpClient ); }

void OnCreateCLServerListPingMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListPingMes ( InetAddr ); }

void OnCreateCLServerListReqVerAndOSMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListReqVerAndOSMes ( InetAddr ); }

void OnCreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr ) { pClient->CreateCLServerListReqConnClientsListMes ( InetAddr ); }
void OnCreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr, bool bUseTcpClient )
{
pClient->CreateCLServerListReqConnClientsListMes ( InetAddr, bUseTcpClient );
}

void OnCLServerListReceived ( CHostAddress InetAddr, CVector<CServerInfo> vecServerInfo )
{
Expand All @@ -220,6 +223,8 @@ public slots:
ConnectDlg.SetServerList ( InetAddr, vecServerInfo, true );
}

void OnCLTcpSupported ( CHostAddress InetAddr, int iID ) { ConnectDlg.SetTcpSupported ( InetAddr, iID ); }

void OnCLConnClientsListMesReceived ( CHostAddress InetAddr, CVector<CChannelInfo> vecChanInfo )
{
ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo );
Expand Down
2 changes: 1 addition & 1 deletion src/clientrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ CClientRpc::CClientRpc ( CClient* pClient, CClientSettings* pSettings, CRpcServe
if ( NetworkUtil::ParseNetworkAddress ( jsonDirectoryIp.toString(), haDirectoryAddress, false ) )
{
// send the request for the server list
pClient->CreateCLReqServerListMes ( haDirectoryAddress );
pClient->CreateCLReqServerListMes ( haDirectoryAddress, false ); // UDP
response["result"] = "ok";
}
else
Expand Down
72 changes: 69 additions & 3 deletions src/connectdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ void CConnectDlg::RequestServerList()
false ) )
{
// send the request for the server list
emit ReqServerListQuery ( haDirectoryAddress );
emit ReqServerListQuery ( haDirectoryAddress, false ); // UDP

// start timer, if this message did not get any respond to retransmit
// the server list request message
Expand Down Expand Up @@ -379,7 +379,7 @@ void CConnectDlg::OnTimerReRequestServList()
{
// note that this is a connection less message which may get lost
// and therefore it makes sense to re-transmit it
emit ReqServerListQuery ( haDirectoryAddress );
emit ReqServerListQuery ( haDirectoryAddress, false ); // UDP
}
}

Expand Down Expand Up @@ -531,6 +531,9 @@ void CConnectDlg::SetServerList ( const CHostAddress& InetAddr, const CVector<CS
// store host address
pNewListViewItem->setData ( LVC_NAME, Qt::UserRole, CurHostAddress.toString() );

enum EClientFetchMode eFetchMode = CFM_UDP_REQUEST; // start off in UDP mode
pNewListViewItem->setData ( LVC_CLIENTS, Qt::UserRole, eFetchMode ); // initialise fetch mode

// per default expand the list item (if not "show all servers")
if ( bShowAllMusicians )
{
Expand All @@ -544,13 +547,67 @@ void CConnectDlg::SetServerList ( const CHostAddress& InetAddr, const CVector<CS
TimerPing.start ( PING_UPDATE_TIME_SERVER_LIST_MS );
}

void CConnectDlg::SetTcpSupported ( const CHostAddress& InetAddr, int iID )
{
qDebug() << "- TCP supported at server" << InetAddr.toString() << "for ID =" << iID;

switch ( iID )
{
case PROTMESSID_CLM_SERVER_LIST:
// if we haven't received the serverlist, it must have got lost due to fragmentation
// retry using TCP instead
if ( !bServerListReceived )
{
// send the request for the server list
emit ReqServerListQuery ( InetAddr, true ); // TCP
}
break;

case PROTMESSID_CLM_CONN_CLIENTS_LIST:
// find the server with the correct address
{
CMappedTreeWidgetItem* pCurListViewItem = FindListViewItem ( InetAddr );

if ( pCurListViewItem )
{
// find the current fetch mode for the client list for this server
enum EClientFetchMode eFetchMode =
static_cast<enum EClientFetchMode> ( pCurListViewItem->data ( LVC_CLIENTS, Qt::UserRole ).toInt() );

if ( eFetchMode == CFM_UDP_REQUEST )
{
// client list not yet received - switch to TCP mode
eFetchMode = CFM_TCP;
pCurListViewItem->setData ( LVC_CLIENTS, Qt::UserRole, eFetchMode ); // remember for future fetches

emit CreateCLServerListReqConnClientsListMes ( InetAddr, true ); // TCP
}
}
}
break;

default:
break;
}
}

void CConnectDlg::SetConnClientsList ( const CHostAddress& InetAddr, const CVector<CChannelInfo>& vecChanInfo )
{
// find the server with the correct address
CMappedTreeWidgetItem* pCurListViewItem = FindListViewItem ( InetAddr );

if ( pCurListViewItem )
{
// find the current fetch mode for the client list for this server
enum EClientFetchMode eFetchMode = static_cast<enum EClientFetchMode> ( pCurListViewItem->data ( LVC_CLIENTS, Qt::UserRole ).toInt() );

if ( eFetchMode != CFM_TCP )
{
// not switched to TCP mode - set to UDP for successful fetch
eFetchMode = CFM_UDP_RESULT;
pCurListViewItem->setData ( LVC_CLIENTS, Qt::UserRole, eFetchMode );
}

// first remove any existing children
DeleteAllListViewItemChilds ( pCurListViewItem );

Expand Down Expand Up @@ -981,7 +1038,16 @@ void CConnectDlg::SetPingTimeAndNumClientsResult ( const CHostAddress& InetAddr,
// connected clients, if not then request the client names
if ( iNumClients != pCurListViewItem->childCount() )
{
emit CreateCLServerListReqConnClientsListMes ( InetAddr );
// find the current fetch mode for the client list for this server
enum EClientFetchMode eFetchMode = static_cast<enum EClientFetchMode> ( pCurListViewItem->data ( LVC_CLIENTS, Qt::UserRole ).toInt() );

if ( eFetchMode != CFM_TCP )
{
// not switched to TCP mode - reset for next UDP fetch
eFetchMode = CFM_UDP_REQUEST;
pCurListViewItem->setData ( LVC_CLIENTS, Qt::UserRole, eFetchMode );
}
emit CreateCLServerListReqConnClientsListMes ( InetAddr, eFetchMode == CFM_TCP ); // UDP or TCP
}

// this is the first time a ping time was received, set item to visible
Expand Down
15 changes: 13 additions & 2 deletions src/connectdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class CConnectDlg : public CBaseDlg, private Ui_CConnectDlgBase

void SetServerList ( const CHostAddress& InetAddr, const CVector<CServerInfo>& vecServerInfo, const bool bIsReducedServerList = false );

void SetTcpSupported ( const CHostAddress& InetAddr, int iID );

void SetConnClientsList ( const CHostAddress& InetAddr, const CVector<CChannelInfo>& vecChanInfo );

void SetPingTimeAndNumClientsResult ( const CHostAddress& InetAddr, const int iPingTime, const int iNumClients );
Expand All @@ -93,6 +95,15 @@ class CConnectDlg : public CBaseDlg, private Ui_CConnectDlgBase
};

protected:
// UDP/TCP mode for fetching client list - stored in data field for LVC_CLIENTS column
enum EClientFetchMode
{
CFM_UDP_REQUEST, // set when sending request by UDP
CFM_UDP_RESULT, // set when received a client list by UDP
CFM_TCP, // set when "TCP Supported" message arrives but client list has not arrived -
// re-request using TCP and remain in TCP mode
};

virtual void showEvent ( QShowEvent* );
virtual void hideEvent ( QHideEvent* );

Expand Down Expand Up @@ -135,8 +146,8 @@ public slots:
void OnCurrentServerItemChanged ( QTreeWidgetItem* current, QTreeWidgetItem* previous );

signals:
void ReqServerListQuery ( CHostAddress InetAddr );
void ReqServerListQuery ( CHostAddress InetAddr, bool bUseTcpClient );
void CreateCLServerListPingMes ( CHostAddress InetAddr );
void CreateCLServerListReqVerAndOSMes ( CHostAddress InetAddr );
void CreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr );
void CreateCLServerListReqConnClientsListMes ( CHostAddress InetAddr, bool bUseTcpClient );
};
Loading
Loading