Commit efff7016 authored by Guillaume Roguez's avatar Guillaume Roguez Committed by Stepan Salenikovich

sipaccountbase: remove portsInUse_ global variable

This patch removes a static global variable initialization order disaster.
(also a coding rules violation)

Refs #67228

Change-Id: Ie8eda34d1049c3c45d476f6b2a2437923c2eeec9
parent 8a106bc2
......@@ -396,7 +396,7 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
* Random generator engine
* Logical account state shall never rely on the state of the random generator.
*/
mutable std::mt19937_64 rand_ {};
mutable std::mt19937_64 rand_;
/**
* UPnP IGD controller and the mutex to access it
......
......@@ -46,8 +46,6 @@
namespace ring {
bool SIPAccountBase::portsInUse_[HALF_MAX_PORT];
SIPAccountBase::SIPAccountBase(const std::string& accountID)
: Account(accountID), link_(getSIPVoIPLink())
{}
......@@ -69,9 +67,9 @@ validate(std::string &member, const std::string &param, const T& valid)
}
static void
updateRange(int min, int max, std::pair<uint16_t, uint16_t> &range)
updateRange(uint16_t min, uint16_t max, std::pair<uint16_t, uint16_t> &range)
{
if (min > 0 and (max > min) and max <= MAX_PORT - 2) {
if (min > 0 and (max > min) and max <= SIPAccountBase::MAX_PORT - 2) {
range.first = min;
range.second = max;
}
......@@ -319,24 +317,33 @@ SIPAccountBase::setTransport(const std::shared_ptr<SipTransport>& t)
transport_->addStateListener(reinterpret_cast<uintptr_t>(this), std::bind(&SIPAccountBase::onTransportStateChanged, this, std::placeholders::_1, std::placeholders::_2));
}
auto
SIPAccountBase::getPortsReservation() noexcept -> decltype(getPortsReservation())
{
// Note: static arrays are zero-initialized
static std::remove_reference<decltype(getPortsReservation())>::type portsInUse;
return portsInUse;
}
// returns even number in range [lower, upper]
uint16_t
SIPAccountBase::acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const
{
std::uniform_int_distribution<uint16_t> dist(range.first/2, range.second/2);
uint16_t result;
do {
result = 2 * dist(rand_);
} while (portsInUse_[result / 2]);
} while (getPortsReservation()[result / 2]);
portsInUse_[result / 2] = true;
getPortsReservation()[result / 2] = true;
return result;
}
void
SIPAccountBase::releasePort(uint16_t port)
SIPAccountBase::releasePort(uint16_t port) noexcept
{
portsInUse_[port / 2] = false;
getPortsReservation()[port / 2] = false;
}
uint16_t
......
......@@ -101,14 +101,15 @@ class SIPCall;
* @file sipaccount.h
* @brief A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink)
*/
enum {MAX_PORT = 65536};
enum {HALF_MAX_PORT = MAX_PORT / 2};
enum class MatchRank {NONE, PARTIAL, FULL};
class SIPAccountBase : public Account {
public:
constexpr static const char * const OVERRTP_STR = "overrtp";
constexpr static const char * const SIPINFO_STR = "sipinfo";
constexpr static unsigned MAX_PORT {65536};
constexpr static unsigned HALF_MAX_PORT {MAX_PORT / 2};
/**
* Constructor
......@@ -248,12 +249,6 @@ public:
virtual std::string getServerUri() const = 0;
uint16_t generateAudioPort() const;
#ifdef RING_VIDEO
uint16_t generateVideoPort() const;
#endif
static void releasePort(uint16_t port);
virtual void setTransport(const std::shared_ptr<SipTransport>& = nullptr);
inline const std::shared_ptr<SipTransport>& getTransport() {
......@@ -269,6 +264,18 @@ public:
*/
pjsip_tpselector getTransportSelector();
/**
* Socket port generators for media
* Note: given ports are application wide, a port cannot be given again
* by any account instances until it's released by the static method
* releasePort().
*/
uint16_t generateAudioPort() const;
#ifdef RING_VIDEO
uint16_t generateVideoPort() const;
#endif
static void releasePort(uint16_t port) noexcept;
protected:
virtual void serialize(YAML::Emitter &out);
virtual void serializeTls(YAML::Emitter &out);
......@@ -362,7 +369,7 @@ protected:
*/
std::pair<uint16_t, uint16_t> videoPortRange_ {49152, (MAX_PORT) - 2};
static bool portsInUse_[HALF_MAX_PORT];
static std::array<bool, HALF_MAX_PORT>& getPortsReservation() noexcept;
uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment