diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index b9789e213a58ddfae724791ed91f29d0a03a6984..8d7987a8c2f1d674cf229932164073c5d27579a2 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -81,6 +81,7 @@ static constexpr int ICE_INIT_TIMEOUT {5};
 static constexpr int ICE_NEGOTIATION_TIMEOUT {60};
 
 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 */)
     : SIPAccountBase(accountID), via_addr_()
@@ -402,9 +403,9 @@ void RingAccount::unserialize(const YAML::Node &node)
     using yaml_utils::parseValue;
 
     SIPAccountBase::unserialize(node);
-    in_port_t port {DHT_DEFAULT_PORT};
-    parseValue(node, Conf::DHT_PORT_KEY, port);
-    dhtPort_ = port ? port : DHT_DEFAULT_PORT;
+    parseValue(node, Conf::DHT_PORT_KEY, dhtPort_);
+    if (not dhtPort_)
+        dhtPort_ = getRandomEvenPort(DHT_PORT_RANGE);
     dhtPortUsed_ = dhtPort_;
     checkIdentityPath();
 }
@@ -498,8 +499,8 @@ void RingAccount::setAccountDetails(const std::map<std::string, std::string> &de
     if (hostname_ == "")
         hostname_ = DHT_DEFAULT_BOOTSTRAP;
     parseInt(details, Conf::CONFIG_DHT_PORT, dhtPort_);
-    if (dhtPort_ == 0)
-        dhtPort_ = DHT_DEFAULT_PORT;
+    if (not dhtPort_)
+        dhtPort_ = getRandomEvenPort(DHT_PORT_RANGE);
     dhtPortUsed_ = dhtPort_;
     checkIdentityPath();
 }
@@ -672,7 +673,7 @@ void RingAccount::doRegister_()
             dht_.join();
         }
         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));
             auto status = std::max(s4, s6);
             switch(status) {
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index 84cb1411a5b3cf17e6dbc5bb3956e142671b86ca..073d93dbb43dc9c11ca7aa78c039e69b3e491f5c 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -79,6 +79,7 @@ class RingAccount : public SIPAccountBase {
         constexpr static const char * const ACCOUNT_TYPE = "RING";
         constexpr static const in_port_t DHT_DEFAULT_PORT = 4222;
         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 {
             return ACCOUNT_TYPE;
@@ -340,7 +341,7 @@ class RingAccount : public SIPAccountBase {
          * selected in the configuration in the case that UPnP is used and the
          * 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.
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index f497069459bb7875491f609ec7e28dbf40950b07..7302913c271bc0cd7116a7774f77b503d857880e 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -247,7 +247,17 @@ SIPAccountBase::getPortsReservation() noexcept -> decltype(getPortsReservation()
     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
 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
     return result;
 }
 
+uint16_t
+SIPAccountBase::acquirePort(uint16_t port)
+{
+    getPortsReservation()[port / 2] = true;
+}
+
 void
 SIPAccountBase::releasePort(uint16_t port) noexcept
 {
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index 0874f81cf4f19bb611c6f23c26631e5255e38c35..1cef21d25a3876bf764e726f58c1235952ae65d5 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -292,7 +292,43 @@ protected:
      */
     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 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;
 
 private: