[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#987167: unblock: jamulus/3.6.2+dfsg1-3



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: tg@mirbsd.de

Please unblock package jamulus

[ Reason ]
This is threefold:
• I promised to write a manpage and only now was able to do so, as
  well as tackle the lintian duplicate file (in /usr/share/doc/) tag
• Upstream introduced a breaking change in the official server list
  so I updated the server list in the program
• A few targetted bugfixes:
  – correctly escape messages received from clients (HTML injection)
  – cease sending a packet to Cloudflare to determine the (nōn-NAT)
    external interface / IP address (privacy fix)
  – add --serverpublicip to support running servers behind IPv4 NAT,
    which is a prerequisite to make the privacy fix from above apply
    (and very helpful to enable more users to run Jamulus instances)

Upstream also had the “great” idea to move their GitHub project, so
I updated all URLs (Homepage, debian/watch, UMEYAGA, docs, etc.) to
the new address. This is mostly because control passed from the
original developer to a project/group now.

[ Impact ]
• missing manpage
• upstream doesn’t commit to keep the old server DNS entries for
  the entire lifetime of Debian, mostly because they use the domain
  from the initial developer, who’s leaving the project, and the
  new servers use the new jamulus.io (shared) domain; users would
  have to specify the correct central servers on the command line
• possibility of HTML injection in messages
• privacy issue of sending a packet to Cloudflare (AIUI server-only)
• inability to correctly run servers behind IPv4 NAT in some situations
• old URLs that may or may not be kept alive indefinitely

[ Tests ]
I’ve manually tested most of the changes including running a server.

[ Risks ]
The patches are backports/cherry-picks from upstream, and this is a
leaf package, so I’d consider this low-risk. (In fact, the commits
to backport were pointed out to me by upstream.)

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]

unblock jamulus/3.6.2+dfsg1-3
diff -Nru jamulus-3.6.2+dfsg1/debian/Jamulus.1 jamulus-3.6.2+dfsg1/debian/Jamulus.1
--- jamulus-3.6.2+dfsg1/debian/Jamulus.1	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/Jamulus.1	2021-04-11 16:04:20.000000000 +0200
@@ -0,0 +1,272 @@
+.\" Manual page for Jamulus
+.\" Copyright (c) 2021
+.\"     mirabilos <tg@debian.org>
+.\" Published under the same terms as Jamulus itself.
+.\"-
+.Dd April 11, 2021
+.Dt JAMULUS 1
+.Os
+.Sh NAME
+.Nm Jamulus
+.Nd real-time collaborative music session
+.Sh SYNOPSIS
+.Nm
+.Op Fl c | Fl \-connect Ar address
+.Op Fl d | Fl \-discononquit
+.Op Fl e | Fl \-centralserver Ar hostname
+.Op Fl F | Fl \-fastupdate
+.Op Fl f | Fl \-listfilter Ar filter
+.Op Fl h | Fl \&? | Fl \-help
+.Op Fl i | Fl \-inifile Ar file
+.Op Fl j | Fl \-nojackconnect
+.Op Fl L | Fl \-licence
+.Op Fl l | Fl \-log Ar file
+.Op Fl M | Fl \-mutestream
+.Op Fl m | Fl \-htmlstatus Ar file
+.Op Fl n | Fl \-nogui
+.Op Fl o | Fl \-serverinfo Ar info
+.Op Fl p | Fl \-port Ar number
+.Op Fl R | Fl \-recording Ar directory
+.Op Fl s | Fl \-server
+.Op Fl T | Fl \-multithreading
+.Op Fl t | Fl \-notranslation
+.Op Fl u | Fl \-numchannels
+.Op Fl v | Fl \-version
+.Op Fl w | Fl \-welcomemessage Ar message
+.Op Fl z | Fl \-startminimized
+.Op Fl \-clientname Ar name
+.Op Fl \-ctrlmidich Ar MIDISetup
+.Op Fl \-mutemyown
+.Op Fl \-norecord
+.Op Fl \-serverpublicip Ar ip
+.Op Fl \-showallservers
+.Op Fl \-showanalyzerconsole
+.Sh DESCRIPTION
+.Nm Jamulus ,
+a low-latency audio client and server, enables musicians to perform real-time
+.Dq jam
+sessions over the internet.
+It is available across multiple platforms, so participants of any field
+can communicate without specialist setup requirements.
+This is not restricted to music, of course; other use
+.Pq perhaps conferencing?
+is also possible.
+.Pp
+One participant starts
+.Nm
+in server mode, ideally on a dedicated server (virtual) machine;
+all participants start the (graphical) client which transmits audio
+to the server, receiving back a mixed stream.
+Use of a metronome is recommended.
+Clients should be connected using ethernet, not wireless, and use
+proper headphone and microphone connections, not Bluetooth.
+The server should run on a low-latency system, ideally not a VM.
+.Pp
+Running
+.Nm
+without any extra options launches the full graphical client.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl c | Fl \-connect Ar address
+.Pq client mode only
+connect to the given server
+.Ar address
+.Pq Ar hostname Ns Op Ar :port
+at startup
+.It Fl d | Fl \-discononquit
+.Pq server mode only
+disconnect all clients on quit
+.It Fl e | Fl \-centralserver Ar hostname
+.Pq server mode only
+make the server public and set its genre by setting the address
+of the central server to use to
+.Ar hostname ;
+see also
+.Fl o ;
+to be a central server, use
+.Dq Li localhost
+.It Fl F | Fl \-fastupdate
+.Pq server mode only
+use 64 samples frame size mode, which reduces latency if clients connect with
+.Dq enable small network buffers
+turned on; requires a faster CPU to avoid dropouts and uses more bandwidth to
+connected clients
+.It Fl f | Fl \-listfilter Ar filter
+.Pq central server mode only
+whitelist servers allowed to register on the server list;
+.Ar filter
+must consist of semicolon-separated IP addresses
+.It Fl h | Fl \&? | Fl \-help
+display a short help text and exit immediately
+.It Fl i | Fl \-inifile Ar file
+.Pq client and non-headless server mode only
+override default initialisation file with
+.Ar file
+.It Fl j | Fl \-nojackconnect
+.Pq client mode only
+do not automatically connect to JACK
+.It Fl L | Fl \-licence
+.Pq server mode only
+require clients to accept the agreement shown in the welcome message
+.Pq use Fl w No to set the text
+before they are allowed joining
+.It Fl l | Fl \-log Ar file
+.Pq server mode only
+enable logging to
+.Ar file
+.It Fl M | Fl \-mutestream
+.Pq client mode only
+start in muted state
+.It Fl m | Fl \-htmlstatus Ar file
+.Pq server mode only
+write server status and list of connected clients, in HTML format, to
+.Ar file
+periodically
+.It Fl n | Fl \-nogui
+disable the GUI
+.It Fl o | Fl \-serverinfo Ar info
+.Pq public servers only
+set server location details, formatted as
+.Sm off
+.Xo
+.Ar name Li \&;
+.Ar city Li \&;
+.Ar locale
+.Xc
+.Sm on
+where
+.Ar locale
+is the numeric value of a
+.Li QLocale ;
+see
+.Pa https://doc.qt.io/qt\-5/qlocale.html#Country\-enum
+for a list
+.It Fl p | Fl \-port Ar number
+set the local UDP port to use to
+.Ar number
+.Pq default: 22124
+.It Fl R | Fl \-recording Ar directory
+.Pq server mode only
+enable recording
+.Pq but see Fl \-norecord
+storing tracks in
+.Ar directory
+.It Fl s | Fl \-server
+start in server mode
+.It Fl T | Fl \-multithreading
+.Pq server mode only
+use multithreading to make better use of multi-core CPUs and
+support more clients
+.It Fl t | Fl \-notranslation
+disable translations, use built-in English strings
+.It Fl u | Fl \-numchannels
+.Pq server mode only
+set maximum number of channels
+.Pq and , therefore , users ;
+default is 10, maximum is 150
+.It Fl v | Fl \-version
+display version information and exit immediately
+.It Fl w | Fl \-welcomemessage Ar message
+.Pq server mode only
+show
+.Ar message
+.Pq may contain HTML and inline CSS
+to users on connect
+.It Fl z | Fl \-startminimized
+.Pq server mode only
+start with minimised window
+.It Fl \-clientname Ar name
+.Pq client mode only
+set window title and JACK client name
+.It Fl \-ctrlmidich Ar MIDISetup
+.Pq client mode only
+set MIDI controller channel to listen on, control number offset and
+consecutive CC numbers (channels); format:
+.Sm off
+.Xo
+.Ar channel
+.Op Li \&;f Ar off Li \&* Ar nchans
+.Op Li \&;p Ar off Li \&* Ar nchans
+.Op Li \&;s Ar off Li \&* Ar nchans
+.Op Li \&;m Ar off Li \&* Ar nchans
+.Xc
+.Sm on
+.Pp
+The first semicolon-separated element sets the MIDI channel
+.Nm
+listens on for control messages.
+The other elements specify the items to control by their
+first literal letter (f\ =\ volume fader, p\ =\ pan, m\ =\ mute,
+s\ =\ solo) directly followed by the offset (CC number) to start from,
+a literal asterisk, and the amount of consecutive CC numbers to assign.
+Fader strips in the mixer window are controlled in ascending order from
+left to right.
+.Nm
+does not provide feedback as to the current state of the Solo and Mute
+buttons so the controller must track and signal their state locally.
+.It Fl \-mutemyown
+.Pq headless client only
+mute my channel in my personal mix
+.It Fl \-norecord
+.Pq server mode only
+do not automatically start recording even if configured with
+.Fl R
+.It Fl \-serverpublicip Ar ip
+.Pq server mode only
+configure public Legacy IP address when both the central server
+and the actual server are situated behind the same NAT, so that
+clients can connect
+.It Fl \-showallservers
+.Pq client mode only
+show all registered servers in the serverlist regardless whether a ping
+to the server is possible or not
+.Pq debugging command
+.It Fl \-showanalyzerconsole
+.Pq client mode only
+show analyser console to debug network buffer properties
+.Pq debugging command
+.El
+.Pp
+Note that the debugging commands are not intended for general use.
+.Pp
+.Nm Jamulus
+knows four modes of operation: client mode and three kinds of server
+.Pq private , public , central .
+A private server is unlisted, clients can only connect if given
+the address (IP address and port).
+A public server will contact a central server (whose address must be
+given at server startup) and show up in that server's list; clients
+can retrieve a list of public servers from the central server.
+Several central servers are operated by the Jamulus project; there is
+a central server for each genre, which is how public servers are
+categorised into genres.
+.Sh SEE ALSO
+.Xr qjackctl 1
+.Bl -tag -width Ds
+.It Pa https://jamulus.io/wiki/Software\-Manual
+online handbook
+.It Pa https://jamulus.io/wiki/Choosing\-a\-Server\-Type
+more details on the individual server types
+.It Pa https://jamulus.io/wiki/Running\-a\-Server
+documentation on server configuration
+.It Pa https://jamulus.io/wiki/Central\-Servers
+current list of central servers operated by the Jamulus project,
+controlling the
+.Dq genre
+.It Pa https://jamulus.io/wiki/Tips\-Tricks\-More
+verbose
+.Fl \-ctrlmidich
+documentation and other more or less useful information
+.El
+.Sh AUTHORS
+.An -nosplit
+.An mirabilos Aq tg@debian.org
+wrote this manual page for the Debian project,
+but it may be used elsewhere as well.
+.Sh BUGS
+This manual page was derived from the source code and summarises
+some of the information from the website, but it could be more helpful.
+.Pp
+Some of the networking code seems to assume Legacy IP
+.Pq IPv4 .
diff -Nru jamulus-3.6.2+dfsg1/debian/changelog jamulus-3.6.2+dfsg1/debian/changelog
--- jamulus-3.6.2+dfsg1/debian/changelog	2021-01-26 00:03:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/changelog	2021-04-11 16:04:40.000000000 +0200
@@ -1,3 +1,21 @@
+jamulus (3.6.2+dfsg1-3) unstable; urgency=low
+
+  * Update GitHub URLs
+    - the repository moved to a{n, new} organisation
+    - GitHub’s tags and releases pages changed tarball links
+  * Mark diff as applied upstream
+  * Run jdupes on the installed documentation as lintian demands
+  * Ship a manpage (Debian-specific for now)
+  * Merge updated list of central (genre) servers offered by upstream
+  * Also apply upstream fix for memory leaks
+  * Add patch to correctly escape messages received from clients
+  * Backport code around --serverpublicip to support running servers
+    behind IPv4 NAT; also a prerequisite of the following patch
+  * Privacy fix: cease sending a packet to Cloudflare to determine
+    the (nōn-NAT) external interface / IP address
+
+ -- Thorsten Glaser <tg@mirbsd.de>  Sun, 11 Apr 2021 16:04:40 +0200
+
 jamulus (3.6.2+dfsg1-2) unstable; urgency=low
 
   * Upload to unstable
diff -Nru jamulus-3.6.2+dfsg1/debian/control jamulus-3.6.2+dfsg1/debian/control
--- jamulus-3.6.2+dfsg1/debian/control	2020-12-29 20:28:29.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/control	2021-04-11 15:44:40.000000000 +0200
@@ -4,6 +4,7 @@
 Maintainer: Thorsten Glaser <tg@mirbsd.de>
 Homepage: https://jamulus.io/
 Build-Depends: debhelper-compat (= 13),
+  jdupes,
   libjack-jackd2-dev,
   qtbase5-dev,
   qtdeclarative5-dev,
diff -Nru jamulus-3.6.2+dfsg1/debian/copyright jamulus-3.6.2+dfsg1/debian/copyright
--- jamulus-3.6.2+dfsg1/debian/copyright	2020-12-29 21:57:20.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/copyright	2021-04-11 15:44:40.000000000 +0200
@@ -1,7 +1,7 @@
 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: Jamulus
 Upstream-Contact: https://sourceforge.net/p/llcon/discussion/
-Source: https://github.com/corrados/jamulus
+Source: https://github.com/jamulussoftware/jamulus
 # Removed embedded convenience code copies and binaries
  Removed embedded binaries (libs blocked by #686777)
 Copyright: 2004–2020 Volker Fischer and others
diff -Nru jamulus-3.6.2+dfsg1/debian/jamulus.lintian-overrides jamulus-3.6.2+dfsg1/debian/jamulus.lintian-overrides
--- jamulus-3.6.2+dfsg1/debian/jamulus.lintian-overrides	2020-12-29 20:28:29.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/jamulus.lintian-overrides	2021-04-11 15:44:40.000000000 +0200
@@ -1,15 +1,2 @@
-# I promise to write one for the second upload
-# (the first upload goes to experimental and
-# has to pass ftpmaster NEW; the second one
-# will promote it to unstable) documenting the
-# then-current state of command line options,
-# as they can change…
-jamulus: no-manual-page usr/bin/Jamulus
-
 # false positive; I checked all invocations of gcc and g++ in the build log
 jamulus: hardening-no-fortify-functions usr/bin/Jamulus
-
-# for now, ignore them; it’s 4 small files, and the next (upstream) version
-# will most likely not ship them at all; otherwise I’ll tackle it in the
-# (second) upload (like above)
-jamulus: duplicate-files usr/share/doc/jamulus/homepage/*
diff -Nru jamulus-3.6.2+dfsg1/debian/jamulus.manpages jamulus-3.6.2+dfsg1/debian/jamulus.manpages
--- jamulus-3.6.2+dfsg1/debian/jamulus.manpages	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/jamulus.manpages	2021-04-11 15:57:31.000000000 +0200
@@ -0,0 +1 @@
+debian/Jamulus.1
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/1073.diff jamulus-3.6.2+dfsg1/debian/patches/1073.diff
--- jamulus-3.6.2+dfsg1/debian/patches/1073.diff	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/1073.diff	2021-04-11 15:44:40.000000000 +0200
@@ -0,0 +1,97 @@
+Origin: upstream, commit:f95d2e97dd102a9a77d809ac4bfb711b1213a19b
+Author: Tony Mountifield <tony@mountifield.org>
+Description: Fix memory leaks in Jam Recorder
+
+--- a/src/recorder/jamcontroller.cpp
++++ b/src/recorder/jamcontroller.cpp
+@@ -30,7 +30,8 @@ CJamController::CJamController() :
+     bRecorderInitialised ( false ),
+     bEnableRecording     ( false ),
+     strRecordingDir      ( "" ),
+-    pthJamRecorder       ( nullptr )
++    pthJamRecorder       ( nullptr ),
++    pJamRecorder         ( nullptr )
+ {
+ }
+ 
+@@ -87,11 +88,19 @@ void CJamController::SetRecordingDir ( Q
+         // Hopefully changing recording directory will NOT happen during a long jam...
+         emit EndRecorderThread();
+         pthJamRecorder->wait();
++        delete pthJamRecorder;
+         pthJamRecorder = nullptr;
+     }
+ 
+     if ( !newRecordingDir.isEmpty() )
+     {
++        if ( pJamRecorder != nullptr )
++        {
++            // We have a reference to a CJamRecorder instance that should now have finished.
++            // Clean up the instance before replacing it.
++            delete pJamRecorder;
++            pJamRecorder = nullptr;
++        }
+         pJamRecorder = new recorder::CJamRecorder ( newRecordingDir, iServerFrameSizeSamples );
+         strRecorderErrMsg = pJamRecorder->Init();
+         bRecorderInitialised = ( strRecorderErrMsg == QString::null );
+--- a/src/recorder/jamrecorder.cpp
++++ b/src/recorder/jamrecorder.cpp
+@@ -45,7 +45,8 @@ CJamClient::CJamClient(const qint64 fram
+     startFrame (frame),
+     numChannels (static_cast<uint16_t>(_numChannels)),
+     name (name),
+-    address (address)
++    address (address),
++    out (nullptr)
+ {
+     // At this point we may not have much of a name
+     QString fileName = ClientName() + "-" + QString::number(frame) + "-" + QString::number(_numChannels);
+@@ -88,8 +89,12 @@ void CJamClient::Frame(const QString _na
+  */
+ void CJamClient::Disconnect()
+ {
+-    static_cast<CWaveStream*>(out)->finalise();
+-    out = nullptr;
++    if (out)
++    {
++        static_cast<CWaveStream*>(out)->finalise();
++        delete out;
++        out = nullptr;
++    }
+ 
+     wavFile->close();
+ 
+@@ -135,6 +140,22 @@ CJamSession::CJamSession(QDir recordBase
+ }
+ 
+ /**
++ * @brief CJamSession::~CJamSession
++ */
++CJamSession::~CJamSession()
++{
++    // free up any active jamClientConnections
++    for (int i = 0; i < jamClientConnections.count(); i++ )
++    {
++        if ( jamClientConnections[i] )
++        {
++            delete jamClientConnections[i];
++            jamClientConnections[i] = nullptr;
++        }
++    }
++}
++
++/**
+  * @brief CJamSession::DisconnectClient Capture details of the departing client's connection
+  * @param iChID the channel id of the client that disconnected
+  */
+--- a/src/recorder/jamrecorder.h
++++ b/src/recorder/jamrecorder.h
+@@ -108,6 +108,8 @@ public:
+ 
+     CJamSession(QDir recordBaseDir);
+ 
++    virtual ~CJamSession();
++
+     void Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples);
+ 
+     void End();
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/1092.diff jamulus-3.6.2+dfsg1/debian/patches/1092.diff
--- jamulus-3.6.2+dfsg1/debian/patches/1092.diff	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/1092.diff	2021-04-11 15:44:40.000000000 +0200
@@ -0,0 +1,67 @@
+Origin: upstream, commit:cd8ba805d209247a754747e7fe39559879951d14
+Author: Christian Hoffmann <mail@hoffmann-christian.info>
+Description: Server: Use a traffic-less way to get external IP
+ .
+ Previously, the code for finding the current machine's external
+ IP address created a TCP connection to Cloudflare's DNS. This is unnecessary.
+ Instead, just creating a socket to a non-private IP suffices to find
+ that IP. We still use Cloudflare's IP, but we will no longer send any traffic
+ there as we use an UDP socket without actually sending any data.
+ .
+ Credit for finding this approach goes to @atsampson.
+ Fixes #633.
+
+--- a/src/global.h
++++ b/src/global.h
+@@ -109,10 +109,12 @@ LED bar:      lbr
+ #define SOFTWARE_MANUAL_URL              "https://github.com/corrados/jamulus/blob/master/src/res/homepage/manual.md";
+ 
+ // determining server internal address uses well-known host and port
+-// (You can change the service used here to something like Cloudflare (1.1.1.1), Google DNS (8.8.8.8), or something else reliable)
+-#define WELL_KNOWN_HOST                  "1.1.1.1" // CloudFlare
+-#define WELL_KNOWN_PORT                  53        // DNS
+-#define IP_LOOKUP_TIMEOUT                500       // ms
++// 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_PORT                  DEFAULT_PORT_NUMBER
++#define IP_LOOKUP_TIMEOUT                500                 // ms
+ 
+ // system sample rate (the sound card and audio coder works on this sample rate)
+ #define SYSTEM_SAMPLE_RATE_HZ            48000 // Hz
+--- a/src/serverlist.cpp
++++ b/src/serverlist.cpp
+@@ -54,6 +54,7 @@ CServerListManager::CServerListManager (
+         // User-supplied --serverpublicip
+         qhaServerPublicIP = QHostAddress ( strServerPublicIP );
+     }
++    qDebug() << "Using" << qhaServerPublicIP.toString() << "as external IP.";
+     SlaveCurLocalHostAddress = CHostAddress ( qhaServerPublicIP, iNPortNum );
+ 
+     // prepare the server info information
+--- a/src/util.cpp
++++ b/src/util.cpp
+@@ -1015,7 +1015,10 @@ bool NetworkUtil::ParseNetworkAddress (
+ 
+ CHostAddress NetworkUtil::GetLocalAddress()
+ {
+-    QTcpSocket socket;
++    QUdpSocket socket;
++    // As we are using UDP, the connectToHost() does not generate any traffic at all.
++    // We just require a socket which is pointed towards the Internet in
++    // order to find out the IP of our own external interface:
+     socket.connectToHost ( WELL_KNOWN_HOST, WELL_KNOWN_PORT );
+ 
+     if ( socket.waitForConnected ( IP_LOOKUP_TIMEOUT ) )
+--- a/src/util.h
++++ b/src/util.h
+@@ -25,7 +25,7 @@
+ #pragma once
+ 
+ #include <QCoreApplication>
+-#include <QTcpSocket>
++#include <QUdpSocket>
+ #include <QHostAddress>
+ #include <QHostInfo>
+ #ifndef HEADLESS
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/885.diff jamulus-3.6.2+dfsg1/debian/patches/885.diff
--- jamulus-3.6.2+dfsg1/debian/patches/885.diff	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/885.diff	2021-04-11 15:44:40.000000000 +0200
@@ -0,0 +1,493 @@
+Origin: upstream, commit:0192af181ea4ba5e71feface3df5899e032ba031,
+ commit:72ff3ae2c199d891c59863070b510107be9e487a
+Author: Volker Fischer <corrados@users.noreply.github.com>
+Description: introduced new server lists: Any Genre 2, Choral/Barbershop (#875)
+ and update hostnames
+X-Debian-Note: stripped down to minimum needed because we’re freezing,
+ but added updated translations, for users’ benefits
+
+--- a/src/connectdlg.cpp
++++ b/src/connectdlg.cpp
+@@ -74,10 +74,12 @@ CConnectDlg::CConnectDlg ( CClientSettin
+     // central server address type combo box
+     cbxCentServAddrType->clear();
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) );
+-    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ALL_GENRES ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ANY_GENRE2 ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ANY_GENRE3 ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CLASSICAL_FOLK ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CHORAL ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
+ 
+     cbxCentServAddrType->setWhatsThis ( "<b>" + tr ( "Server List Selection" ) + ":</b> " + tr (
+--- a/src/global.h
++++ b/src/global.h
+@@ -94,12 +94,14 @@ LED bar:      lbr
+ #define DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ( 2 * SYSTEM_FRAME_SIZE_SAMPLES )
+ 
+ // default server address and port numbers
+-#define DEFAULT_SERVER_ADDRESS           "jamulus.fischvolk.de"
++#define DEFAULT_SERVER_ADDRESS           "anygenre1.jamulus.io"
+ #define DEFAULT_PORT_NUMBER              22124
+-#define CENTSERV_ALL_GENRES              "jamulusallgenres.fischvolk.de:22224"
+-#define CENTSERV_GENRE_ROCK              "jamulusrock.fischvolk.de:22424"
+-#define CENTSERV_GENRE_JAZZ              "jamulusjazz.fischvolk.de:22324"
+-#define CENTSERV_GENRE_CLASSICAL_FOLK    "jamulusclassical.fischvolk.de:22524"
++#define CENTSERV_ANY_GENRE2              "anygenre2.jamulus.io:22224"
++#define CENTSERV_ANY_GENRE3              "anygenre3.jamulus.io:22624"
++#define CENTSERV_GENRE_ROCK              "rock.jamulus.io:22424"
++#define CENTSERV_GENRE_JAZZ              "jazz.jamulus.io:22324"
++#define CENTSERV_GENRE_CLASSICAL_FOLK    "classical.jamulus.io:22524"
++#define CENTSERV_GENRE_CHORAL            "choral.jamulus.io:22724"
+ 
+ // getting started and software manual URL
+ #define CLIENT_GETTING_STARTED_URL       "https://jamulus.io/wiki/Getting-Started";
+--- a/src/res/translation/translation_de_DE.ts
++++ b/src/res/translation/translation_de_DE.ts
+@@ -1705,6 +1705,16 @@
+         <translation>Alle Genres</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Alle Genres 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Alle Genres 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Genre Rock</translation>
+@@ -1715,6 +1725,21 @@
+         <translation>Genre Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Genre Klassik/Volksmusik</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Genre Chor/Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Alle Genres 1</translation>
++    </message>
++    <message>
+         <source>Genre Rock/Jazz</source>
+         <translation type="vanished">Genre Rock/Jazz</translation>
+     </message>
+--- a/src/res/translation/translation_es_ES.ts
++++ b/src/res/translation/translation_es_ES.ts
+@@ -1717,6 +1717,16 @@
+         <translation>Todos los Géneros</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Cualquier Género 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Cualquier Género 3</translation>
++    </message>
++    <message>
+         <source>Genre Rock/Jazz</source>
+         <translation type="vanished">Género Rock/Jazz</translation>
+     </message>
+@@ -1736,6 +1746,21 @@
+         <translation>Género Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Género Clásico/Folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Género Coral/Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Cualquier Género 1</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="608"/>
+         <source>Default</source>
+         <translation>Predeterminado</translation>
+--- a/src/res/translation/translation_fr_FR.ts
++++ b/src/res/translation/translation_fr_FR.ts
+@@ -1373,6 +1373,16 @@
+         <translation>Tous les genres</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Tout genre 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Tout genre 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="605"/>
+         <source>Genre Classical/Folk/Choral</source>
+         <translation>Genre classique/folk/choeur</translation>
+@@ -1388,6 +1398,21 @@
+         <translation>Genre Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Genre classique/folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Genre chorale/barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Tout genre 1</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="608"/>
+         <source>Default</source>
+         <translation>Défaut</translation>
+--- a/src/res/translation/translation_it_IT.ts
++++ b/src/res/translation/translation_it_IT.ts
+@@ -1722,6 +1722,16 @@
+         <translation>Tutti i Generi</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Tutti i Generi 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Tutti i Generi 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Genere Rock</translation>
+@@ -1732,6 +1742,21 @@
+         <translation>Genere Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Genere Classica / Folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Genere Corale / Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Tutti i Generi 1</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="605"/>
+         <source>Genre Classical/Folk/Choral</source>
+         <translation>Genere Classica/Folk/Corale</translation>
+--- a/src/res/translation/translation_nl_NL.ts
++++ b/src/res/translation/translation_nl_NL.ts
+@@ -1677,6 +1677,16 @@
+         <translation>Alle genres</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Ieder Genre 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Ieder Genre 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Genre Rock</translation>
+@@ -1687,6 +1697,21 @@
+         <translation>Genre Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Genre Klassiek/Folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Genre Koor/Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Ieder Genre 1</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="605"/>
+         <source>Genre Classical/Folk/Choral</source>
+         <translation>Genre Klassiek/Folk/Zang</translation>
+--- a/src/res/translation/translation_pl_PL.ts
++++ b/src/res/translation/translation_pl_PL.ts
+@@ -1373,6 +1373,16 @@
+         <translation>Wszystkie style</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Każdy styl 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Każdy styl 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Rock</translation>
+@@ -1383,6 +1393,21 @@
+         <translation>Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Klasyka/folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Chór/zespół wokalny</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Każdy styl 1</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="605"/>
+         <source>Genre Classical/Folk/Choral</source>
+         <translation>Klasyka/Folk/Chór</translation>
+--- a/src/res/translation/translation_pt_BR.ts
++++ b/src/res/translation/translation_pt_BR.ts
+@@ -1708,6 +1708,16 @@
+         <translation>Servidor Geral</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Gênero Variado 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Gênero Variado 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Servidor Rock</translation>
+@@ -1718,6 +1728,21 @@
+         <translation>Servidor Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Gênero Clássico/Folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Gênero Coral/Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Gênero Variado 1</translation>
++    </message>
++    <message>
+         <source>Genre Rock/Jazz</source>
+         <translation type="vanished">Servidor Rock/Jazz</translation>
+     </message>
+--- a/src/res/translation/translation_pt_PT.ts
++++ b/src/res/translation/translation_pt_PT.ts
+@@ -1701,6 +1701,16 @@
+         <translation>Servidor Geral</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Qualquer Estilo 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Qualquer Estilo 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Servidor Rock</translation>
+@@ -1711,6 +1721,21 @@
+         <translation>Servidor Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Estilo Clássico/Folk</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Estilo Coral/Barbershop</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="632"/>
++        <source>Any Genre 1</source>
++        <translation>Qualquer Estilo 1</translation>
++    </message>
++    <message>
+         <source>Genre Rock/Jazz</source>
+         <translation type="vanished">Servidor Rock/Jazz</translation>
+     </message>
+--- a/src/res/translation/translation_sv_SE.ts
++++ b/src/res/translation/translation_sv_SE.ts
+@@ -1447,6 +1447,16 @@
+         <translation>Alla genrer</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="614"/>
++        <source>Any Genre 2</source>
++        <translation>Alla genrer 2</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="617"/>
++        <source>Any Genre 3</source>
++        <translation>Alla genrer 3</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="599"/>
+         <source>Genre Rock</source>
+         <translation>Genre Rock</translation>
+@@ -1457,6 +1467,16 @@
+         <translation>Genre Jazz</translation>
+     </message>
+     <message>
++        <location filename="../../util.h" line="626"/>
++        <source>Genre Classical/Folk</source>
++        <translation>Genre Klassisk/Folkmusik</translation>
++    </message>
++    <message>
++        <location filename="../../util.h" line="629"/>
++        <source>Genre Choral/Barbershop</source>
++        <translation>Genre Choral/Barbershop</translation>
++    </message>
++    <message>
+         <location filename="../../util.h" line="605"/>
+         <source>Genre Classical/Folk/Choral</source>
+         <translation>Genre Klassiskt/Folkmusik/Kör</translation>
+--- a/src/serverdlg.cpp
++++ b/src/serverdlg.cpp
+@@ -242,10 +242,12 @@ lvwClients->setMinimumHeight ( 140 );
+     // central server address type combo box
+     cbxCentServAddrType->clear();
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) );
+-    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ALL_GENRES ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ANY_GENRE2 ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ANY_GENRE3 ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CLASSICAL_FOLK ) );
++    cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CHORAL ) );
+     cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
+     cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pServer->GetCentralServerAddressType() ) );
+ 
+--- a/src/util.cpp
++++ b/src/util.cpp
+@@ -1038,10 +1038,12 @@ QString NetworkUtil::GetCentralServerAdd
+     switch ( eCentralServerAddressType )
+     {
+     case AT_CUSTOM:               return strCentralServerAddress;
+-    case AT_ALL_GENRES:           return CENTSERV_ALL_GENRES;
++    case AT_ANY_GENRE2:           return CENTSERV_ANY_GENRE2;
++    case AT_ANY_GENRE3:           return CENTSERV_ANY_GENRE3;
+     case AT_GENRE_ROCK:           return CENTSERV_GENRE_ROCK;
+     case AT_GENRE_JAZZ:           return CENTSERV_GENRE_JAZZ;
+     case AT_GENRE_CLASSICAL_FOLK: return CENTSERV_GENRE_CLASSICAL_FOLK;
++    case AT_GENRE_CHORAL:         return CENTSERV_GENRE_CHORAL;
+     default:                      return DEFAULT_SERVER_ADDRESS; // AT_DEFAULT
+     }
+ }
+--- a/src/util.h
++++ b/src/util.h
+@@ -578,11 +578,13 @@ enum ECSAddType
+ {
+     // used for settings -> enum values should be fixed
+     AT_DEFAULT = 0,
+-    AT_ALL_GENRES = 1,
+-    AT_GENRE_ROCK = 2,
+-    AT_GENRE_JAZZ = 3,
+-    AT_GENRE_CLASSICAL_FOLK = 4,
+-    AT_CUSTOM = 5 // Must be the last entry!
++    AT_ANY_GENRE2 = 1,
++    AT_ANY_GENRE3 = 2,
++    AT_GENRE_ROCK = 3,
++    AT_GENRE_JAZZ = 4,
++    AT_GENRE_CLASSICAL_FOLK = 5,
++    AT_GENRE_CHORAL = 6,
++    AT_CUSTOM = 7 // Must be the last entry!
+ };
+ 
+ inline QString csCentServAddrTypeToString ( ECSAddType eAddrType )
+@@ -592,8 +594,11 @@ inline QString csCentServAddrTypeToStrin
+     case AT_CUSTOM:
+         return QCoreApplication::translate ( "CClientSettingsDlg", "Custom" );
+ 
+-    case AT_ALL_GENRES:
+-        return QCoreApplication::translate ( "CClientSettingsDlg", "All Genres" );
++    case AT_ANY_GENRE2:
++        return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 2" );
++
++    case AT_ANY_GENRE3:
++        return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 3" );
+ 
+     case AT_GENRE_ROCK:
+         return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Rock" );
+@@ -602,10 +607,13 @@ inline QString csCentServAddrTypeToStrin
+         return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Jazz" );
+ 
+     case AT_GENRE_CLASSICAL_FOLK:
+-        return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Classical/Folk/Choral" );
++        return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Classical/Folk" );
++
++    case AT_GENRE_CHORAL:
++        return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Choral/Barbershop" );
+ 
+     default: // AT_DEFAULT
+-        return QCoreApplication::translate ( "CClientSettingsDlg", "Default" );
++        return QCoreApplication::translate ( "CClientSettingsDlg", "Any Genre 1" );
+     }
+ }
+ 
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/939.diff jamulus-3.6.2+dfsg1/debian/patches/939.diff
--- jamulus-3.6.2+dfsg1/debian/patches/939.diff	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/939.diff	2021-04-11 15:44:40.000000000 +0200
@@ -0,0 +1,15 @@
+Origin: upstream, commit:6ffd1fd3e3182174f3a7b837d3d4b67aeae171e8
+Author: Adam Sampson <ats@offog.org>
+Description: Escape chat messages at the server.
+
+--- a/src/server.cpp
++++ b/src/server.cpp
+@@ -1396,7 +1396,7 @@ void CServer::CreateAndSendChatTextForAl
+         "<font color=""" + sCurColor + """>(" +
+         QTime::currentTime().toString ( "hh:mm:ss AP" ) + ") <b>" +
+         ChanName.toHtmlEscaped() +
+-        "</b></font> " + strChatText;
++        "</b></font> " + strChatText.toHtmlEscaped();
+ 
+ 
+     // Send chat text to all connected clients ---------------------------------
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/954.diff jamulus-3.6.2+dfsg1/debian/patches/954.diff
--- jamulus-3.6.2+dfsg1/debian/patches/954.diff	1970-01-01 01:00:00.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/954.diff	2021-04-11 15:51:30.000000000 +0200
@@ -0,0 +1,240 @@
+Origin: upstream,
+ commit:5f239a8f22c8107e1feef608d1ffadc5d36760b4,
+ commit:4800e05089a348a1c83631cc7c125259035df5f5
+Author: Christian Hoffmann <mail@hoffmann-christian.info>
+Description: Support running servers behind NAT:
+ .
+ 1. Add support for --serverpublicip
+ .
+    When running servers and registering them with a central server,
+    Jamulus will auto-detect the external IP of the current machine.
+    However, this will not be a publicly reachable IP when using NAT and a
+    central server in the same private network.
+    This means, that the server is inaccessible via that central server.
+ .
+    Therefore, add a new command line option --serverpublicip to override
+    this auto-detection.
+ .
+    Note: This still requires that proper port forwarding is set up. It also
+    assumes that ports are forwarded symmetrically, i.e.
+            external-ip:22124 -> internal-ip:22124
+ .
+    Required for #888.
+ .
+ 2. Add support for central servers+slaves behind NAT
+ .
+    Previously, the server list handed out the originating address
+    of a slave server to any client.
+    A special case was implemented to hand out internal addresses
+    instead of public addresses when both the slave server and the
+    client are assumed to be behind the same NAT.
+ .
+    This commit adds another special case for running central servers
+    and slave servers behind NAT while serving clients from the Internet.
+    In such a setup, slave servers would only be known by their internal
+    address to the central server. As such, clients would be served an
+    internal IP address which they cannot use.
+ .
+    When slave servers make use of the newly added --serverpublicip flag,
+    they can now override their internal IP address with the proper public
+    IP address.
+ .
+    This commit adapts the server list logic to make use of an IP which is
+    provided in this way.
+ .
+    Fixes #888.
+X-Debian-Note: prerequisite for 1092.diff (privacy fix)
+
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -85,6 +85,7 @@ int main ( int argc, char** argv )
+     QString      strRecordingDirName         = "";
+     QString      strCentralServer            = "";
+     QString      strServerInfo               = "";
++    QString      strServerPublicIP           = "";
+     QString      strServerListFilter         = "";
+     QString      strWelcomeMessage           = "";
+     QString      strClientName               = APP_NAME;
+@@ -392,6 +393,22 @@ int main ( int argc, char** argv )
+         }
+ 
+ 
++        // Server Public IP --------------------------------------------------
++        if ( GetStringArgument ( tsConsole,
++                                 argc,
++                                 argv,
++                                 i,
++                                 "--serverpublicip", // no short form
++                                 "--serverpublicip",
++                                 strArgument ) )
++        {
++            strServerPublicIP = strArgument;
++            tsConsole << "- server public ip: " << strServerPublicIP << endl;
++            CommandLineOptions << "--serverpublicip";
++            continue;
++        }
++
++
+         // Server info ---------------------------------------------------------
+         if ( GetStringArgument ( tsConsole,
+                                  argc,
+@@ -684,6 +701,7 @@ int main ( int argc, char** argv )
+                              strHTMLStatusFileName,
+                              strCentralServer,
+                              strServerInfo,
++                             strServerPublicIP,
+                              strServerListFilter,
+                              strWelcomeMessage,
+                              strRecordingDirName,
+@@ -800,6 +818,9 @@ QString UsageArguments ( char **argv )
+         "  -u, --numchannels     maximum number of channels\n"
+         "  -w, --welcomemessage  welcome message on connect\n"
+         "  -z, --startminimized  start minimizied\n"
++        "      --serverpublicip  specify your public IP address when\n"
++        "                        running a slave and your own central server\n"
++        "                        behind the same NAT\n"
+         "\nClient only:\n"
+         "  -M, --mutestream      starts the application in muted state\n"
+         "      --mutemyown       mute me in my personal mix (headless only)\n"
+--- a/src/protocol.cpp
++++ b/src/protocol.cpp
+@@ -303,6 +303,9 @@ CONNECTION LESS MESSAGES
+       NOTE: In the PROTMESSID_CLM_SERVER_LIST list, this field will be empty
+       as only the initial IP address should be used by the client.  Where
+       necessary, that value will contain the server internal address.
++      When running a central server and a slave server behind the same NAT,
++      this field is used the other way round: It will contain the public
++      IP in this case which will be served to clients from the Internet.
+ 
+ 
+ - PROTMESSID_CLM_REGISTER_SERVER_EX: Register a server, providing extended server
+--- a/src/server.cpp
++++ b/src/server.cpp
+@@ -226,6 +226,7 @@ CServer::CServer ( const int          iN
+                    const QString&     strCentralServer,
+                    const QString&     strServerInfo,
+                    const QString&     strServerListFilter,
++                   const QString&     strServerPublicIP,
+                    const QString&     strNewWelcomeMessage,
+                    const QString&     strRecordingDirName,
+                    const bool         bNDisconnectAllClientsOnQuit,
+@@ -245,6 +246,7 @@ CServer::CServer ( const int          iN
+     ServerListManager           ( iPortNumber,
+                                   strCentralServer,
+                                   strServerInfo,
++                                  strServerPublicIP,
+                                   strServerListFilter,
+                                   iNewMaxNumChan,
+                                   &ConnLessProtocol ),
+--- a/src/server.h
++++ b/src/server.h
+@@ -176,6 +176,7 @@ public:
+               const QString&     strCentralServer,
+               const QString&     strServerInfo,
+               const QString&     strServerListFilter,
++              const QString&     strServerPublicIP,
+               const QString&     strNewWelcomeMessage,
+               const QString&     strRecordingDirName,
+               const bool         bNDisconnectAllClientsOnQuit,
+--- a/src/serverlist.cpp
++++ b/src/serverlist.cpp
+@@ -29,6 +29,7 @@ CServerListManager::CServerListManager (
+                                          const QString& sNCentServAddr,
+                                          const QString& strServerInfo,
+                                          const QString& strServerListFilter,
++                                         const QString& strServerPublicIP,
+                                          const int      iNumChannels,
+                                          CProtocol*     pNConLProt )
+     : tsConsoleStream           ( *( ( new ConsoleWriterFactory() )->get() ) ),
+@@ -42,7 +43,18 @@ CServerListManager::CServerListManager (
+     SetCentralServerAddress ( sNCentServAddr );
+ 
+     // set the server internal address, including internal port number
+-    SlaveCurLocalHostAddress = CHostAddress( NetworkUtil::GetLocalAddress().InetAddr, iNPortNum );
++    QHostAddress qhaServerPublicIP;
++    if ( strServerPublicIP == "" )
++    {
++        // No user-supplied override via --serverpublicip -> use auto-detection
++        qhaServerPublicIP = NetworkUtil::GetLocalAddress().InetAddr;
++    }
++    else
++    {
++        // User-supplied --serverpublicip
++        qhaServerPublicIP = QHostAddress ( strServerPublicIP );
++    }
++    SlaveCurLocalHostAddress = CHostAddress ( qhaServerPublicIP, iNPortNum );
+ 
+     // prepare the server info information
+     QStringList slServInfoSeparateParams;
+@@ -443,6 +455,20 @@ void CServerListManager::CentralServerQu
+                 {
+                     vecServerInfo[iIdx].HostAddr = ServerList[iIdx].LHostAddr;
+                 }
++                else if ( !NetworkUtil::IsPrivateNetworkIP ( InetAddr.InetAddr ) &&
++                          NetworkUtil::IsPrivateNetworkIP ( vecServerInfo[iIdx].HostAddr.InetAddr ) &&
++                          !NetworkUtil::IsPrivateNetworkIP ( ServerList[iIdx].LHostAddr.InetAddr ) )
++                {
++                    // We've got a request from a public client, the server
++                    // list's entry's primary address is a private address,
++                    // but it supplied an additional public address using
++                    // --serverpublicip.
++                    // In this case, use the latter.
++                    // This is common when running a central server with slave
++                    // servers behind a NAT and dealing with external, public
++                    // clients.
++                    vecServerInfo[iIdx].HostAddr = ServerList[iIdx].LHostAddr;
++                }
+                 else
+                 {
+                     // create "send empty message" for all registered servers
+--- a/src/serverlist.h
++++ b/src/serverlist.h
+@@ -128,6 +128,7 @@ public:
+                          const QString& sNCentServAddr,
+                          const QString& strServerInfo,
+                          const QString& strServerListFilter,
++                         const QString& strServerPublicIP,
+                          const int      iNumChannels,
+                          CProtocol*     pNConLProt );
+ 
+--- a/src/util.cpp
++++ b/src/util.cpp
+@@ -1054,6 +1054,28 @@ QString NetworkUtil::FixAddress ( const
+     return strAddress.simplified().replace ( " ", "" );
+ }
+ 
++// Return whether the given HostAdress is within a private IP range
++// as per RFC 1918 & RFC 5735.
++bool NetworkUtil::IsPrivateNetworkIP ( const QHostAddress &qhAddr )
++{
++    // https://www.rfc-editor.org/rfc/rfc1918
++    // https://www.rfc-editor.org/rfc/rfc5735
++    static QList<QPair<QHostAddress, int>> addresses =
++    {
++        QPair<QHostAddress, int> ( QHostAddress ( "10.0.0.0" ), 8 ),
++        QPair<QHostAddress, int> ( QHostAddress ( "127.0.0.0" ), 8 ),
++        QPair<QHostAddress, int> ( QHostAddress ( "172.16.0.0" ), 12 ),
++        QPair<QHostAddress, int> ( QHostAddress ( "192.168.0.0" ), 16 ),
++    };
++
++    foreach ( auto item, addresses ) {
++        if ( qhAddr.isInSubnet ( item ) ) {
++            return true;
++        }
++    }
++    return false;
++}
++
+ 
+ // Instrument picture data base ------------------------------------------------
+ CVector<CInstPictures::CInstPictProps>& CInstPictures::GetTable ( const bool bReGenerateTable )
+--- a/src/util.h
++++ b/src/util.h
+@@ -1088,6 +1088,7 @@ public:
+     static CHostAddress GetLocalAddress();
+     static QString      GetCentralServerAddress ( const ECSAddType eCentralServerAddressType,
+                                                   const QString&   strCentralServerAddress );
++    static bool         IsPrivateNetworkIP ( const QHostAddress& qhAddr );
+ };
+ 
+ 
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/branding.diff jamulus-3.6.2+dfsg1/debian/patches/branding.diff
--- jamulus-3.6.2+dfsg1/debian/patches/branding.diff	2020-12-29 23:12:10.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/branding.diff	2021-04-11 15:44:40.000000000 +0200
@@ -15,7 +15,7 @@
  
 --- a/src/util.cpp
 +++ b/src/util.cpp
-@@ -1543,7 +1543,10 @@ QString GetVersionAndNameStr ( const boo
+@@ -1570,7 +1570,10 @@ QString GetVersionAndNameStr ( const boo
          strVersionText += " *** ";
      }
  
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/manual-link.diff jamulus-3.6.2+dfsg1/debian/patches/manual-link.diff
--- jamulus-3.6.2+dfsg1/debian/patches/manual-link.diff	2020-12-29 20:28:29.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/manual-link.diff	2021-04-11 15:44:40.000000000 +0200
@@ -5,7 +5,7 @@
 
 --- a/src/global.h
 +++ b/src/global.h
-@@ -104,7 +104,7 @@ LED bar:      lbr
+@@ -106,7 +106,7 @@ LED bar:      lbr
  // getting started and software manual URL
  #define CLIENT_GETTING_STARTED_URL       "https://jamulus.io/wiki/Getting-Started";
  #define SERVER_GETTING_STARTED_URL       "https://jamulus.io/wiki/Running-a-Server";
@@ -13,4 +13,4 @@
 +#define SOFTWARE_MANUAL_URL              "https://jamulus.io/wiki/Software-Manual";
  
  // determining server internal address uses well-known host and port
- // (You can change the service used here to something like Cloudflare (1.1.1.1), Google DNS (8.8.8.8), or something else reliable)
+ // We just need a valid, public Internet IP here. We will not send any
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/series jamulus-3.6.2+dfsg1/debian/patches/series
--- jamulus-3.6.2+dfsg1/debian/patches/series	2020-12-29 23:12:10.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/series	2021-04-11 15:44:40.000000000 +0200
@@ -1,3 +1,8 @@
+885.diff
+939.diff
+954.diff
+1073.diff
+1092.diff
 manual-link.diff
 use-lrelease.diff
 branding.diff
diff -Nru jamulus-3.6.2+dfsg1/debian/patches/use-lrelease.diff jamulus-3.6.2+dfsg1/debian/patches/use-lrelease.diff
--- jamulus-3.6.2+dfsg1/debian/patches/use-lrelease.diff	2020-12-29 23:12:10.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/patches/use-lrelease.diff	2021-04-11 15:44:40.000000000 +0200
@@ -1,6 +1,7 @@
 Description: generate compiled translation files correctly
 Author: mirabilos <tg@debian.org>
-Forwarded: https://github.com/corrados/jamulus/pull/799
+Forwarded: https://github.com/jamulussoftware/jamulus/pull/799
+Applied-Upstream: 3.7.0
 
 --- a/Jamulus.pro
 +++ b/Jamulus.pro
diff -Nru jamulus-3.6.2+dfsg1/debian/rules jamulus-3.6.2+dfsg1/debian/rules
--- jamulus-3.6.2+dfsg1/debian/rules	2021-01-26 00:02:41.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/rules	2021-04-11 15:44:40.000000000 +0200
@@ -46,3 +46,6 @@
 
 override_dh_auto_configure:
 	dh_auto_configure -- ${CONFIG_ARGS}
+
+execute_after_dh_link:
+	jdupes -rl debian/jamulus/usr/share/doc/jamulus/homepage
diff -Nru jamulus-3.6.2+dfsg1/debian/upstream/metadata jamulus-3.6.2+dfsg1/debian/upstream/metadata
--- jamulus-3.6.2+dfsg1/debian/upstream/metadata	2020-12-29 20:28:29.000000000 +0100
+++ jamulus-3.6.2+dfsg1/debian/upstream/metadata	2021-04-11 15:44:40.000000000 +0200
@@ -3,14 +3,14 @@
     "GitHub",
     "SourceForge"
   ],
-  "Bug-Database": "https://github.com/corrados/jamulus/issues";,
-  "Changelog": "https://github.com/corrados/jamulus/blob/master/ChangeLog";,
+  "Bug-Database": "https://github.com/jamulussoftware/jamulus/issues";,
+  "Changelog": "https://github.com/jamulussoftware/jamulus/blob/master/ChangeLog";,
   "Documentation": "https://jamulus.io/wiki/Software-Manual";,
   "Donation": "https://sourceforge.net/p/llcon/discussion/533517/thread/cea6e1d97b/";,
   "FAQ": "https://jamulus.io/wiki/Client-Troubleshooting";,
   "Name": "Jamulus",
-  "Repository": "git@github.com:corrados/jamulus.git",
-  "Repository-Browse": "https://github.com/corrados/jamulus";,
+  "Repository": "git@github.com:jamulussoftware/jamulus.git",
+  "Repository-Browse": "https://github.com/jamulussoftware/jamulus";,
   "Screenshots": [
     "https://jamulus.io/wiki/Demos";
   ]
diff -Nru jamulus-3.6.2+dfsg1/debian/watch jamulus-3.6.2+dfsg1/debian/watch
--- jamulus-3.6.2+dfsg1/debian/watch	2020-04-26 17:01:51.000000000 +0200
+++ jamulus-3.6.2+dfsg1/debian/watch	2021-04-11 15:44:40.000000000 +0200
@@ -4,6 +4,6 @@
   compression=gz,\
   uversionmangle=s/_/./g,\
   dversionmangle=s/\+dfsg[0-9]+$// \
- https://github.com/corrados/jamulus/releases \
- .*/corrados/jamulus/archive/r([0-9]+(?:_[0-9]+)*)\.tar\.gz \
+ https://github.com/jamulussoftware/jamulus/releases \
+ .*/jamulussoftware/jamulus/archive/refs/tags/r([0-9]+(?:_[0-9]+)*)\.tar\.gz \
 debian debian/repack

Reply to: