Commit ac7f9b10 authored by Adrien Béraud's avatar Adrien Béraud Committed by Guillaume Roguez

ringaccount: use a random port by default

Refs #69174

(cherry picked from master, commit e0284a70)

Change-Id: I4332aa7f3b66b8dbae156ed2f4dc9f9f98ab2a4e
parent aa5b4fef
...@@ -81,6 +81,7 @@ static constexpr int ICE_INIT_TIMEOUT {5}; ...@@ -81,6 +81,7 @@ static constexpr int ICE_INIT_TIMEOUT {5};
static constexpr int ICE_NEGOTIATION_TIMEOUT {60}; static constexpr int ICE_NEGOTIATION_TIMEOUT {60};
constexpr const char * const RingAccount::ACCOUNT_TYPE; constexpr const char * const RingAccount::ACCOUNT_TYPE;
constexpr const std::pair<uint16_t, uint16_t> RingAccount::DHT_PORT_RANGE;
RingAccount::RingAccount(const std::string& accountID, bool /* presenceEnabled */) RingAccount::RingAccount(const std::string& accountID, bool /* presenceEnabled */)
: SIPAccountBase(accountID), via_addr_() : SIPAccountBase(accountID), via_addr_()
...@@ -402,9 +403,9 @@ void RingAccount::unserialize(const YAML::Node &node) ...@@ -402,9 +403,9 @@ void RingAccount::unserialize(const YAML::Node &node)
using yaml_utils::parseValue; using yaml_utils::parseValue;
SIPAccountBase::unserialize(node); SIPAccountBase::unserialize(node);
in_port_t port {DHT_DEFAULT_PORT}; parseValue(node, Conf::DHT_PORT_KEY, dhtPort_);
parseValue(node, Conf::DHT_PORT_KEY, port); if (not dhtPort_)
dhtPort_ = port ? port : DHT_DEFAULT_PORT; dhtPort_ = getRandomEvenPort(DHT_PORT_RANGE);
dhtPortUsed_ = dhtPort_; dhtPortUsed_ = dhtPort_;
checkIdentityPath(); checkIdentityPath();
} }
...@@ -498,8 +499,8 @@ void RingAccount::setAccountDetails(const std::map<std::string, std::string> &de ...@@ -498,8 +499,8 @@ void RingAccount::setAccountDetails(const std::map<std::string, std::string> &de
if (hostname_ == "") if (hostname_ == "")
hostname_ = DHT_DEFAULT_BOOTSTRAP; hostname_ = DHT_DEFAULT_BOOTSTRAP;
parseInt(details, Conf::CONFIG_DHT_PORT, dhtPort_); parseInt(details, Conf::CONFIG_DHT_PORT, dhtPort_);
if (dhtPort_ == 0) if (not dhtPort_)
dhtPort_ = DHT_DEFAULT_PORT; dhtPort_ = getRandomEvenPort(DHT_PORT_RANGE);
dhtPortUsed_ = dhtPort_; dhtPortUsed_ = dhtPort_;
checkIdentityPath(); checkIdentityPath();
} }
...@@ -672,7 +673,7 @@ void RingAccount::doRegister_() ...@@ -672,7 +673,7 @@ void RingAccount::doRegister_()
dht_.join(); dht_.join();
} }
auto identity = loadIdentity(); auto identity = loadIdentity();
dht_.run(dhtPortUsed_, identity.second, false, [=](dht::Dht::Status s4, dht::Dht::Status s6) { dht_.run((in_port_t)dhtPortUsed_, identity.second, false, [=](dht::Dht::Status s4, dht::Dht::Status s6) {
RING_WARN("Dht status : IPv4 %s; IPv6 %s", dhtStatusStr(s4), dhtStatusStr(s6)); RING_WARN("Dht status : IPv4 %s; IPv6 %s", dhtStatusStr(s4), dhtStatusStr(s6));
auto status = std::max(s4, s6); auto status = std::max(s4, s6);
switch(status) { switch(status) {
......
...@@ -79,6 +79,7 @@ class RingAccount : public SIPAccountBase { ...@@ -79,6 +79,7 @@ class RingAccount : public SIPAccountBase {
constexpr static const char * const ACCOUNT_TYPE = "RING"; constexpr static const char * const ACCOUNT_TYPE = "RING";
constexpr static const in_port_t DHT_DEFAULT_PORT = 4222; constexpr static const in_port_t DHT_DEFAULT_PORT = 4222;
constexpr static const char * const DHT_DEFAULT_BOOTSTRAP = "bootstrap.ring.cx"; constexpr static const char * const DHT_DEFAULT_BOOTSTRAP = "bootstrap.ring.cx";
constexpr static const std::pair<uint16_t, uint16_t> DHT_PORT_RANGE {4000, 8888};
const char* getAccountType() const { const char* getAccountType() const {
return ACCOUNT_TYPE; return ACCOUNT_TYPE;
...@@ -340,7 +341,7 @@ class RingAccount : public SIPAccountBase { ...@@ -340,7 +341,7 @@ class RingAccount : public SIPAccountBase {
* selected in the configuration in the case that UPnP is used and the * selected in the configuration in the case that UPnP is used and the
* configured port is already used by another client * configured port is already used by another client
*/ */
in_port_t dhtPortUsed_ {DHT_DEFAULT_PORT}; UsedPort dhtPortUsed_ {DHT_DEFAULT_PORT};
/** /**
* The TLS settings, used only if tls is chosen as a sip transport. * The TLS settings, used only if tls is chosen as a sip transport.
......
...@@ -247,7 +247,17 @@ SIPAccountBase::getPortsReservation() noexcept -> decltype(getPortsReservation() ...@@ -247,7 +247,17 @@ SIPAccountBase::getPortsReservation() noexcept -> decltype(getPortsReservation()
return portsInUse; return portsInUse;
} }
// returns even number in range [lower, upper] uint16_t
SIPAccountBase::getRandomEvenPort(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 (getPortsReservation()[result / 2]);
return result;
}
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
{ {
...@@ -262,6 +272,12 @@ SIPAccountBase::acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range ...@@ -262,6 +272,12 @@ SIPAccountBase::acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range
return result; return result;
} }
uint16_t
SIPAccountBase::acquirePort(uint16_t port)
{
getPortsReservation()[port / 2] = true;
}
void void
SIPAccountBase::releasePort(uint16_t port) noexcept SIPAccountBase::releasePort(uint16_t port) noexcept
{ {
......
...@@ -292,7 +292,43 @@ protected: ...@@ -292,7 +292,43 @@ protected:
*/ */
std::pair<uint16_t, uint16_t> videoPortRange_ {49152, (MAX_PORT) - 2}; std::pair<uint16_t, uint16_t> videoPortRange_ {49152, (MAX_PORT) - 2};
struct UsedPort {
UsedPort() {};
UsedPort(UsedPort&& o) : port_(o.port_) {
o.port_ = 0;
}
UsedPort(in_port_t p) : port_(p) {
if (port_)
acquirePort(port_);
};
~UsedPort() {
if (port_)
releasePort(port_);
};
UsedPort& operator=(UsedPort&& o) {
if (port_)
releasePort(port_);
port_ = o.port_;
o.port_ = 0;
return *this;
}
UsedPort& operator=(in_port_t p) {
if (port_)
releasePort(port_);
port_ = p;
if (port_)
acquirePort(port_);
return *this;
}
explicit operator in_port_t() const { return port_; }
private:
in_port_t port_ {0};
NON_COPYABLE(UsedPort);
};
static std::array<bool, HALF_MAX_PORT>& getPortsReservation() noexcept; static std::array<bool, HALF_MAX_PORT>& getPortsReservation() noexcept;
static uint16_t acquirePort(uint16_t port);
uint16_t getRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const; uint16_t acquireRandomEvenPort(const std::pair<uint16_t, uint16_t>& range) const;
private: private:
......
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