Skip to content

Commit

Permalink
Further work on IPv6 support
Browse files Browse the repository at this point in the history
Reworked ParseNetworkAddress() to use regex to validate format.
Allows literal IP address (IP4 or IP6) between [ ],
or else IP4 address or hostname without [ ].
Optional :port follows.

Add code to determine routable IPv6 interface address.
Uses Cloudflare's IPv6 DNs resolver address (no traffic sent).

Use LocalHostIPv6 if no local IPv6 address

Add command option and flag for enabling IPv6

Reworked sockaddr handling in OnDataReceived()

Change in_port_t to uint16_t for Windows compatibility

Allow IPv4 only for communicating with Directory Servers

Rework dual-stack socket handling for Windows compatibility

Move sockaddr union definition into socket.h
  • Loading branch information
softins committed Aug 10, 2021
1 parent 9968e41 commit 576d101
Show file tree
Hide file tree
Showing 17 changed files with 343 additions and 177 deletions.
10 changes: 6 additions & 4 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ CClient::CClient ( const quint16 iPortNumber,
const QString& strMIDISetup,
const bool bNoAutoJackConnect,
const QString& strNClientName,
const bool bNEnableIPv6,
const bool bNMuteMeInPersonalMix ) :
ChannelInfo(),
strClientName ( strNClientName ),
Expand All @@ -46,7 +47,7 @@ CClient::CClient ( const quint16 iPortNumber,
bIsInitializationPhase ( true ),
bMuteOutStream ( false ),
fMuteOutStreamGain ( 1.0f ),
Socket ( &Channel, iPortNumber, iQosNumber ),
Socket ( &Channel, iPortNumber, iQosNumber, "", bNEnableIPv6 ),
Sound ( AudioCallback, this, strMIDISetup, bNoAutoJackConnect, strNClientName ),
iAudioInFader ( AUD_FADER_IN_MIDDLE ),
bReverbOnLeftChan ( false ),
Expand All @@ -62,7 +63,8 @@ CClient::CClient ( const quint16 iPortNumber,
eGUIDesign ( GD_ORIGINAL ),
bEnableOPUS64 ( false ),
bJitterBufferOK ( true ),
bNuteMeInPersonalMix ( bNMuteMeInPersonalMix ),
bEnableIPv6 ( bNEnableIPv6 ),
bMuteMeInPersonalMix ( bNMuteMeInPersonalMix ),
iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ),
pSignalHandler ( CSignalHandler::getSingletonP() )
{
Expand Down Expand Up @@ -344,7 +346,7 @@ void CClient::SetRemoteChanGain ( const int iId, const float fGain, const bool b
bool CClient::SetServerAddr ( QString strNAddr )
{
CHostAddress HostAddress;
if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( strNAddr, HostAddress, bEnableIPv6 ) )
{
// apply address to the channel
Channel.SetAddress ( HostAddress );
Expand Down Expand Up @@ -706,7 +708,7 @@ void CClient::OnClientIDReceived ( int iChanID )
// for headless mode we support to mute our own signal in the personal mix
// (note that the check for headless is done in the main.cpp and must not
// be checked here)
if ( bNuteMeInPersonalMix )
if ( bMuteMeInPersonalMix )
{
SetRemoteChanGain ( iChanID, 0, false );
}
Expand Down
4 changes: 3 additions & 1 deletion src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class CClient : public QObject
const QString& strMIDISetup,
const bool bNoAutoJackConnect,
const QString& strNClientName,
const bool bNEnableIPv6,
const bool bNMuteMeInPersonalMix );

virtual ~CClient();
Expand Down Expand Up @@ -347,7 +348,8 @@ class CClient : public QObject
bool bEnableOPUS64;

bool bJitterBufferOK;
bool bNuteMeInPersonalMix;
bool bEnableIPv6;
bool bMuteMeInPersonalMix;
QMutex MutexDriverReinit;

// server settings
Expand Down
6 changes: 4 additions & 2 deletions src/clientdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
const bool bNewShowComplRegConnList,
const bool bShowAnalyzerConsole,
const bool bMuteStream,
const bool bNEnableIPv6,
QWidget* parent ) :
CBaseDlg ( parent, Qt::Window ), // use Qt::Window to get min/max window buttons
pClient ( pNCliP ),
pSettings ( pNSetP ),
bConnectDlgWasShown ( false ),
bMIDICtrlUsed ( !strMIDISetup.isEmpty() ),
bEnableIPv6 ( bNEnableIPv6 ),
eLastRecorderState ( RS_UNDEFINED ), // for SetMixerBoardDeco
eLastDesign ( GD_ORIGINAL ), // "
ClientSettingsDlg ( pNCliP, pNSetP, parent ),
Expand Down Expand Up @@ -560,12 +562,12 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
// Send the request to two servers for redundancy if either or both of them
// has a higher release version number, the reply will trigger the notification.

if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress, bEnableIPv6 ) )
{
pClient->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress );
}

if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress, bEnableIPv6 ) )
{
pClient->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress );
}
Expand Down
2 changes: 2 additions & 0 deletions src/clientdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase
const bool bNewShowComplRegConnList,
const bool bShowAnalyzerConsole,
const bool bMuteStream,
const bool bNEnableIPv6,
QWidget* parent = nullptr );

protected:
Expand All @@ -104,6 +105,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase
bool bConnectDlgWasShown;
bool bMIDICtrlUsed;
bool bDetectFeedback;
bool bEnableIPv6;
ERecorderState eLastRecorderState;
EGUIDesign eLastDesign;
QTimer TimerSigMet;
Expand Down
16 changes: 11 additions & 5 deletions src/connectdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "connectdlg.h"

/* Implementation *************************************************************/
CConnectDlg::CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, QWidget* parent ) :
CConnectDlg::CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, const bool bNEnableIPv6, QWidget* parent ) :
CBaseDlg ( parent, Qt::Dialog ),
pSettings ( pNSetP ),
strSelectedAddress ( "" ),
Expand All @@ -35,7 +35,8 @@ CConnectDlg::CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteR
bReducedServerListReceived ( false ),
bServerListItemWasChosen ( false ),
bListFilterWasActive ( false ),
bShowAllMusicians ( true )
bShowAllMusicians ( true ),
bEnableIPv6 ( bNEnableIPv6 )
{
setupUi ( this );

Expand Down Expand Up @@ -228,10 +229,13 @@ void CConnectDlg::RequestServerList()
// function) when the connect dialog is opened, this seems to be the correct
// time to do it. Note that in case of custom directory server address we
// use iCustomDirectoryIndex as an index into the vector.

// Allow IPv4 only for communicating with Directory Servers
if ( NetworkUtil().ParseNetworkAddress (
NetworkUtil::GetCentralServerAddress ( pSettings->eCentralServerAddressType,
pSettings->vstrCentralServerAddress[pSettings->iCustomDirectoryIndex] ),
CentralServerAddress ) )
CentralServerAddress,
false ) )
{
// send the request for the server list
emit ReqServerListQuery ( CentralServerAddress );
Expand Down Expand Up @@ -730,7 +734,9 @@ void CConnectDlg::OnTimerPing()

// try to parse host address string which is stored as user data
// in the server list item GUI control element
if ( NetworkUtil().ParseNetworkAddress ( lvwServers->topLevelItem ( iIdx )->data ( 0, Qt::UserRole ).toString(), CurServerAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( lvwServers->topLevelItem ( iIdx )->data ( 0, Qt::UserRole ).toString(),
CurServerAddress,
bEnableIPv6 ) )
{
// if address is valid, send ping message using a new thread
QtConcurrent::run ( this, &CConnectDlg::EmitCLServerListPingMes, CurServerAddress );
Expand Down Expand Up @@ -953,4 +959,4 @@ void CConnectDlg::UpdateDirectoryServerComboBox()
cbxDirectoryServer->addItem ( pSettings->vstrCentralServerAddress[i], i );
}
}
}
}
3 changes: 2 additions & 1 deletion src/connectdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class CConnectDlg : public CBaseDlg, private Ui_CConnectDlgBase
Q_OBJECT

public:
CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, QWidget* parent = nullptr );
CConnectDlg ( CClientSettings* pNSetP, const bool bNewShowCompleteRegList, const bool bNEnableIPv6, QWidget* parent = nullptr );

void SetShowAllMusicians ( const bool bState ) { ShowAllMusicians ( bState ); }
bool GetShowAllMusicians() { return bShowAllMusicians; }
Expand Down Expand Up @@ -90,6 +90,7 @@ class CConnectDlg : public CBaseDlg, private Ui_CConnectDlgBase
bool bServerListItemWasChosen;
bool bListFilterWasActive;
bool bShowAllMusicians;
bool bEnableIPv6;

public slots:
void OnServerListItemDoubleClicked ( QTreeWidgetItem* Item, int );
Expand Down
3 changes: 2 additions & 1 deletion src/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ LED bar: lbr
// We just need a valid, public Internet IP here. We will not send any
// traffic there as we will only set up an UDP socket without sending any
// data.
#define WELL_KNOWN_HOST "1.1.1.1" // CloudFlare
#define WELL_KNOWN_HOST "1.1.1.1" // CloudFlare
#define WELL_KNOWN_HOST6 "2606:4700:4700::1111" // CloudFlare
#define WELL_KNOWN_PORT DEFAULT_PORT_NUMBER
#define IP_LOOKUP_TIMEOUT 500 // ms

Expand Down
23 changes: 21 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ int main ( int argc, char** argv )
bool bNoAutoJackConnect = false;
bool bUseTranslation = true;
bool bCustomPortNumberGiven = false;
bool bEnableIPv6 = false;
int iNumServerChannels = DEFAULT_USED_NUM_CHANNELS;
quint16 iPortNumber = DEFAULT_PORT_NUMBER;
quint16 iQosNumber = DEFAULT_QOS_NUMBER;
Expand Down Expand Up @@ -179,6 +180,15 @@ int main ( int argc, char** argv )
continue;
}

// Enable IPv6 ---------------------------------------------------------
if ( GetFlagArgument ( argv, i, "-6", "--enableipv6" ) )
{
bEnableIPv6 = true;
qInfo() << "- IPv6 enabled";
CommandLineOptions << "--enableipv6";
continue;
}

// Server only:

// Disconnect all clients on quit --------------------------------------
Expand Down Expand Up @@ -784,8 +794,14 @@ int main ( int argc, char** argv )
{
// Client:
// actual client object
CClient
Client ( iPortNumber, iQosNumber, strConnOnStartupAddress, strMIDISetup, bNoAutoJackConnect, strClientName, bMuteMeInPersonalMix );
CClient Client ( iPortNumber,
iQosNumber,
strConnOnStartupAddress,
strMIDISetup,
bNoAutoJackConnect,
strClientName,
bEnableIPv6,
bMuteMeInPersonalMix );

// load settings from init-file (command line options override)
CClientSettings Settings ( &Client, strIniFileName );
Expand All @@ -809,6 +825,7 @@ int main ( int argc, char** argv )
bShowComplRegConnList,
bShowAnalyzerConsole,
bMuteStream,
bEnableIPv6,
nullptr );

// show dialog
Expand Down Expand Up @@ -846,6 +863,7 @@ int main ( int argc, char** argv )
bUseMultithreading,
bDisableRecording,
bDelayPan,
bEnableIPv6,
eLicenceType );

#ifndef HEADLESS
Expand Down Expand Up @@ -937,6 +955,7 @@ QString UsageArguments ( char** argv )
" -Q, --qos set the QoS value. Default is 128. Disable with 0\n"
" (see the Jamulus website to enable QoS on Windows)\n"
" -t, --notranslation disable translation (use English language)\n"
" -6, --enableipv6 enable IPv6 addressing (IPv4 is always enabled)\n"
"\n"
"Server only:\n"
" -d, --discononquit disconnect all clients on quit\n"
Expand Down
5 changes: 4 additions & 1 deletion src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,12 @@ CServer::CServer ( const int iNewMaxNumChan,
const bool bNUseMultithreading,
const bool bDisableRecording,
const bool bNDelayPan,
const bool bNEnableIPv6,
const ELicenceType eNLicenceType ) :
bUseDoubleSystemFrameSize ( bNUseDoubleSystemFrameSize ),
bUseMultithreading ( bNUseMultithreading ),
iMaxNumChannels ( iNewMaxNumChan ),
Socket ( this, iPortNumber, iQosNumber, strServerBindIP ),
Socket ( this, iPortNumber, iQosNumber, strServerBindIP, bNEnableIPv6 ),
Logging(),
iFrameCount ( 0 ),
bWriteStatusHTMLFile ( false ),
Expand All @@ -247,11 +248,13 @@ CServer::CServer ( const int iNewMaxNumChan,
strServerPublicIP,
strServerListFilter,
iNewMaxNumChan,
bNEnableIPv6,
&ConnLessProtocol ),
JamController ( this ),
bDisableRecording ( bDisableRecording ),
bAutoRunMinimized ( false ),
bDelayPan ( bNDelayPan ),
bEnableIPv6 ( bNEnableIPv6 ),
eLicenceType ( eNLicenceType ),
bDisconnectAllClientsOnQuit ( bNDisconnectAllClientsOnQuit ),
pSignalHandler ( CSignalHandler::getSingletonP() )
Expand Down
7 changes: 7 additions & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
const bool bNUseMultithreading,
const bool bDisableRecording,
const bool bNDelayPan,
const bool bNEnableIPv6,
const ELicenceType eNLicenceType );

virtual ~CServer();
Expand Down Expand Up @@ -209,6 +210,9 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
void SetEnableDelayPanning ( bool bDelayPanningOn ) { bDelayPan = bDelayPanningOn; }
bool IsDelayPanningEnabled() { return bDelayPan; }

// IPv6 Enabled
bool IsIPv6Enabled() { return bEnableIPv6; }

// Server list management --------------------------------------------------
void UpdateServerList() { ServerListManager.Update(); }

Expand Down Expand Up @@ -368,6 +372,9 @@ class CServer : public QObject, public CServerSlots<MAX_NUM_CHANNELS>
// for delay panning
bool bDelayPan;

// enable IPv6
bool bEnableIPv6;

// messaging
QString strWelcomeMessage;
ELicenceType eLicenceType;
Expand Down
4 changes: 2 additions & 2 deletions src/serverdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,12 @@ lvwClients->setMinimumHeight ( 140 );
// Send the request to two servers for redundancy if either or both of them
// has a higher release version number, the reply will trigger the notification.

if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK1_ADDRESS, UpdateServerHostAddress, pServer->IsIPv6Enabled() ) )
{
pServer->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress );
}

if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress ) )
if ( NetworkUtil().ParseNetworkAddress ( UPDATECHECK2_ADDRESS, UpdateServerHostAddress, pServer->IsIPv6Enabled() ) )
{
pServer->CreateCLServerListReqVerAndOSMes ( UpdateServerHostAddress );
}
Expand Down
Loading

0 comments on commit 576d101

Please sign in to comment.