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 ...@@ -396,7 +396,7 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
* Random generator engine * Random generator engine
* Logical account state shall never rely on the state of the random generator. * 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 * UPnP IGD controller and the mutex to access it
......
...@@ -46,8 +46,6 @@ ...@@ -46,8 +46,6 @@
namespace ring { namespace ring {
bool SIPAccountBase::portsInUse_[HALF_MAX_PORT];
SIPAccountBase::SIPAccountBase(const std::string& accountID) SIPAccountBase::SIPAccountBase(const std::string& accountID)
: Account(accountID), link_(getSIPVoIPLink()) : Account(accountID), link_(getSIPVoIPLink())
{} {}
...@@ -69,9 +67,9 @@ validate(std::string &member, const std::string &param, const T& valid) ...@@ -69,9 +67,9 @@ validate(std::string &member, const std::string &param, const T& valid)
} }
static void 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.first = min;
range.second = max; range.second = max;
} }
...@@ -319,24 +317,33 @@ SIPAccountBase::setTransport(const std::shared_ptr<SipTransport>& t) ...@@ -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)); 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] // returns even number in range [lower, upper]
uint16_t uint16_t
SIPAccountBase::acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const SIPAccountBase::acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const
{ {
std::uniform_int_distribution<uint16_t> dist(range.first/2, range.second/2); std::uniform_int_distribution<uint16_t> dist(range.first/2, range.second/2);
uint16_t result; uint16_t result;
do { do {
result = 2 * dist(rand_); result = 2 * dist(rand_);
} while (portsInUse_[result / 2]); } while (getPortsReservation()[result / 2]);
portsInUse_[result / 2] = true; getPortsReservation()[result / 2] = true;
return result; return result;
} }
void void
SIPAccountBase::releasePort(uint16_t port) SIPAccountBase::releasePort(uint16_t port) noexcept
{ {
portsInUse_[port / 2] = false; getPortsReservation()[port / 2] = false;
} }
uint16_t uint16_t
......
...@@ -101,14 +101,15 @@ class SIPCall; ...@@ -101,14 +101,15 @@ class SIPCall;
* @file sipaccount.h * @file sipaccount.h
* @brief A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink) * @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}; enum class MatchRank {NONE, PARTIAL, FULL};
class SIPAccountBase : public Account { class SIPAccountBase : public Account {
public: public:
constexpr static const char * const OVERRTP_STR = "overrtp"; constexpr static const char * const OVERRTP_STR = "overrtp";
constexpr static const char * const SIPINFO_STR = "sipinfo"; constexpr static const char * const SIPINFO_STR = "sipinfo";
constexpr static unsigned MAX_PORT {65536};
constexpr static unsigned HALF_MAX_PORT {MAX_PORT / 2};
/** /**
* Constructor * Constructor
...@@ -248,12 +249,6 @@ public: ...@@ -248,12 +249,6 @@ public:
virtual std::string getServerUri() const = 0; 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); virtual void setTransport(const std::shared_ptr<SipTransport>& = nullptr);
inline const std::shared_ptr<SipTransport>& getTransport() { inline const std::shared_ptr<SipTransport>& getTransport() {
...@@ -269,6 +264,18 @@ public: ...@@ -269,6 +264,18 @@ public:
*/ */
pjsip_tpselector getTransportSelector(); 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: protected:
virtual void serialize(YAML::Emitter &out); virtual void serialize(YAML::Emitter &out);
virtual void serializeTls(YAML::Emitter &out); virtual void serializeTls(YAML::Emitter &out);
...@@ -362,7 +369,7 @@ protected: ...@@ -362,7 +369,7 @@ protected:
*/ */
std::pair<uint16_t, uint16_t> videoPortRange_ {49152, (MAX_PORT) - 2}; 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; uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
static void 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