From efff7016e7b314fbccf6a86a886c9b24c2b9c1c1 Mon Sep 17 00:00:00 2001 From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> Date: Thu, 26 Feb 2015 12:59:49 -0500 Subject: [PATCH] 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 --- daemon/src/account.h | 2 +- daemon/src/sip/sipaccountbase.cpp | 23 +++++++++++++++-------- daemon/src/sip/sipaccountbase.h | 25 ++++++++++++++++--------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/daemon/src/account.h b/daemon/src/account.h index 6165cc4cfc..3cb0d25a4c 100644 --- a/daemon/src/account.h +++ b/daemon/src/account.h @@ -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 diff --git a/daemon/src/sip/sipaccountbase.cpp b/daemon/src/sip/sipaccountbase.cpp index 110a350b50..cbdd6c9280 100644 --- a/daemon/src/sip/sipaccountbase.cpp +++ b/daemon/src/sip/sipaccountbase.cpp @@ -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 ¶m, 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 diff --git a/daemon/src/sip/sipaccountbase.h b/daemon/src/sip/sipaccountbase.h index 52841bf20e..bd31dcfb7c 100644 --- a/daemon/src/sip/sipaccountbase.h +++ b/daemon/src/sip/sipaccountbase.h @@ -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 -- GitLab