From 4dd1932decf86bcfbe1355966f1dac037777b892 Mon Sep 17 00:00:00 2001
From: atraczyk <andreastraczyk@gmail.com>
Date: Mon, 14 Nov 2016 10:12:17 -0500
Subject: [PATCH] cherry-pick commits: from:
 dae99566886348b420ab5a0f43cb3a6c8f548a22 to:  
 d1682f6aebb391f5763238bfaaea227555972fe0

Change-Id: I1cb799a778bc6f80b385d8cb40c5ddf3ed1d2c3a
---
 .gitignore                                    |   5 +-
 Makefile.am                                   |   2 +-
 README                                        |   2 +-
 bin/dbus/Makefile.am                          |   2 +-
 bin/restcpp/Makefile.am                       |   2 +-
 configure.ac                                  |   6 +-
 doc/dbus-api/Makefile.am                      |   2 +-
 globals.mak => globals.mk                     |   1 +
 src/Makefile.am                               |   4 +-
 src/call.cpp                                  |   2 +
 src/client/Makefile.am                        |   2 +-
 src/client/configurationmanager.cpp           |   8 +-
 src/ice_transport.cpp                         |  95 ++--
 src/ice_transport.h                           |   5 +-
 src/im/Makefile.am                            |   2 +-
 src/manager.cpp                               |  21 +-
 src/manager.h                                 |   9 +
 src/media/Makefile.am                         |   2 +-
 src/media/audio/Makefile.am                   |   2 +-
 src/media/audio/alsa/Makefile.am              |   2 +-
 src/media/audio/coreaudio/Makefile.am         |   2 +-
 src/media/audio/jack/Makefile.am              |   2 +-
 src/media/audio/opensl/Makefile.am            |   2 +-
 src/media/audio/portaudio/Makefile.am         |   2 +-
 src/media/audio/pulseaudio/Makefile.am        |   2 +-
 src/media/audio/sound/Makefile.am             |   2 +-
 src/media/media_decoder.cpp                   |   5 +-
 src/media/media_decoder.h                     |   1 +
 src/media/media_device.h                      |   1 -
 src/media/video/Makefile.am                   |   2 +-
 src/media/video/androidvideo/Makefile.am      |   2 +-
 src/media/video/osxvideo/Makefile.am          |   2 +-
 src/media/video/test/Makefile.am              |   2 +-
 .../video/uwpvideo/video_device_impl.cpp      |  19 +-
 src/media/video/v4l2/Makefile.am              |   2 +-
 src/media/video/v4l2/vaapi.cpp                |   2 +-
 src/media/video/video_base.cpp                |  10 +-
 src/media/video/video_base.h                  |   1 -
 src/media/video/video_device.h                |   4 -
 src/media/video/video_device_monitor.cpp      |   2 -
 src/media/video/video_receive_thread.cpp      |   8 +-
 src/media/video/video_receive_thread.h        |   3 +-
 src/media/video/video_rtp_session.cpp         |   8 +-
 src/media/video/winvideo/Makefile.am          |   2 +-
 src/preferences.cpp                           |  29 ++
 src/preferences.h                             |  20 +
 src/ringdht/Makefile.am                       |   2 +-
 src/ringdht/eth/libdevcore/Makefile.am        |   2 +-
 src/ringdht/eth/libdevcrypto/Makefile.am      |   2 +-
 src/ringdht/namedirectory.cpp                 | 445 +++++++++++-------
 src/ringdht/namedirectory.h                   |  26 +-
 src/ringdht/ringaccount.cpp                   |  38 +-
 src/ringdht/ringaccount.h                     |   1 +
 src/security/Makefile.am                      |   2 +-
 src/sip/Makefile.am                           |   2 +-
 src/sip/sipcall.cpp                           |   4 +-
 src/upnp/Makefile.am                          |   2 +-
 57 files changed, 503 insertions(+), 336 deletions(-)
 rename globals.mak => globals.mk (96%)

diff --git a/.gitignore b/.gitignore
index 4b390e5f50..f4a3e4a0f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,9 +69,10 @@ config_auto.h
 # Ignore temp files
 *~
 
-# Cscope/Ctags files
+# Cscope/Ctags/Etags files
 cscope.*
 tags
+TAGS
 TAGS.LST
 ID
 
@@ -112,4 +113,4 @@ __pycache__
 contrib/*
 !contrib/bootstrap
 !contrib/src
-!contrib/tarballs
\ No newline at end of file
+!contrib/tarballs
diff --git a/Makefile.am b/Makefile.am
index 11fccbf362..d8952086b8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-include globals.mak
+include globals.mk
 
 # Makefile.am
 
diff --git a/README b/README
index bf138a7727..f06c971b37 100644
--- a/README
+++ b/README
@@ -79,7 +79,7 @@ make install
 Done !
 
 More details available here:
-https://tuleap.ring.cx/wiki/index.php?pagename=How%20To%20Build%20Ring&group_id=101
+https://tuleap.ring.cx/plugins/mediawiki/wiki/ring/index.php/Build_Instructions
 
 
 How to compile on OSX
diff --git a/bin/dbus/Makefile.am b/bin/dbus/Makefile.am
index fda17a225b..99eec615bf 100644
--- a/bin/dbus/Makefile.am
+++ b/bin/dbus/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libclient_dbus.la
 
diff --git a/bin/restcpp/Makefile.am b/bin/restcpp/Makefile.am
index 2f5e1e5c2e..57401c1fa1 100644
--- a/bin/restcpp/Makefile.am
+++ b/bin/restcpp/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libclient_rest.la
 
diff --git a/configure.ac b/configure.ac
index e83b479cf3..6455f8a21a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl Ring - configure.ac for automake 1.9 and autoconf 2.59
 
 dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ([2.65])
-AC_INIT([Ring],[2.3.0],[ring@lists.savoirfairelinux.net],[ring])
+AC_INIT([Ring],[3.0.0],[ring@lists.savoirfairelinux.net],[ring])
 
 AC_COPYRIGHT([[Copyright (c) Savoir-faire Linux 2004-2016]])
 AC_REVISION([$Revision$])
@@ -396,6 +396,10 @@ AC_DEFINE_UNQUOTED([HAVE_RINGNS], `if test "x$enable_ringns" != "xno"; then echo
 # Rest C++ with restbed
 AC_ARG_WITH([restcpp],
     AS_HELP_STRING([--with-restcpp], [enable rest support with C++]))
+AC_ARG_ENABLE([restbed_old_api], AS_HELP_STRING([--enable-restbed-old-api], [Use the old restbed API]))
+AS_IF([test "x$enable_restbed_old_api" = "xyes"], [
+  AC_DEFINE([RESTBED_OLD_API], [], [Defined if you use the old restbed API])
+])
 
 AS_IF([test "x$enable_ringns" != "xno" || test "x$with_restcpp" = "xyes"],
   AC_CHECK_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files])));
diff --git a/doc/dbus-api/Makefile.am b/doc/dbus-api/Makefile.am
index b7064e5dd9..b7f84139e1 100644
--- a/doc/dbus-api/Makefile.am
+++ b/doc/dbus-api/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 XSLTPROC=xsltproc --xinclude --nonet
 PYTHON=python
diff --git a/globals.mak b/globals.mk
similarity index 96%
rename from globals.mak
rename to globals.mk
index a467a69a63..218680204e 100644
--- a/globals.mak
+++ b/globals.mk
@@ -34,6 +34,7 @@ AM_CPPFLAGS = \
 	-DENABLE_TRACE \
 	-DRING_REVISION=\"$(RING_REVISION)\" \
 	-DRING_DIRTY_REPO=\"$(RING_DIRTY_REPO)\" \
+    -DPJSIP_MAX_PKT_LEN=8000 \
 	$(SPEEXCODEC) \
 	$(GSMCODEC) \
 	$(OPUSCODEC)
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c36d1799b..3a85be6565 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-include ../globals.mak
+include ../globals.mk
 
 RING_VIDEO_LIBS=
 
@@ -124,7 +124,7 @@ libring_la_SOURCES = \
 		noncopyable.h \
 		utf8_utils.h \
 		ring_types.h \
-		intrin.h \
+		compiler_intrinsics.h \
 		array_size.h \
 		account_schema.h \
 		registration_states.h \
diff --git a/src/call.cpp b/src/call.cpp
index aac915369a..9e93391e77 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -465,6 +465,8 @@ Call::merge(std::shared_ptr<Call> scall)
     std::lock_guard<std::recursive_mutex> lk2 (call.callMutex_, std::adopt_lock);
     auto pendingInMessages = std::move(call.pendingInMessages_);
     iceTransport_ = std::move(call.iceTransport_);
+    if (peerNumber_.empty())
+        peerNumber_ = std::move(call.peerNumber_);
     peerDisplayName_ = std::move(call.peerDisplayName_);
     localAddr_ = call.localAddr_;
     localAudioPort_ = call.localAudioPort_;
diff --git a/src/client/Makefile.am b/src/client/Makefile.am
index cb26ade38f..fd4e3a32f0 100644
--- a/src/client/Makefile.am
+++ b/src/client/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libclient.la
 
diff --git a/src/client/configurationmanager.cpp b/src/client/configurationmanager.cpp
index 97132fec0a..eb7b0e04d7 100644
--- a/src/client/configurationmanager.cpp
+++ b/src/client/configurationmanager.cpp
@@ -838,9 +838,13 @@ bool lookupName(const std::string& account, const std::string& nameserver, const
 {
 #if HAVE_RINGNS
     if (account.empty()) {
-        ring::NameDirectory::instance(nameserver).lookupName(name, [name](const std::string& result, ring::NameDirectory::Response response) {
+        auto cb = [name](const std::string& result, ring::NameDirectory::Response response) {
             ring::emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>("", (int)response, result, name);
-        });
+        };
+        if (nameserver.empty())
+            ring::NameDirectory::lookupUri(name, "", cb);
+        else
+            ring::NameDirectory::instance(nameserver).lookupName(name, cb);
         return true;
     } else if (auto acc = ring::Manager::instance().getAccount<RingAccount>(account)) {
         acc->lookupName(name);
diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index a0128fd9ca..00c538c32b 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -26,8 +26,10 @@
 #include "upnp/upnp_control.h"
 
 #include <pjlib.h>
+#include <msgpack.hpp>
 
 #include <utility>
+#include <tuple>
 #include <algorithm>
 #include <sstream>
 #include <chrono>
@@ -438,56 +440,48 @@ IceTransport::start(const Attribute& rem_attrs,
     return true;
 }
 
-std::string
-IceTransport::unpackLine(std::vector<uint8_t>::const_iterator& begin,
-                         std::vector<uint8_t>::const_iterator& end)
-{
-    if (std::distance(begin, end) <= 0)
-        return {};
-
-    // Search for EOL
-    std::vector<uint8_t>::const_iterator line_end(begin);
-    while (line_end != end && *line_end != NEW_LINE && *line_end)
-        ++line_end;
-
-    if (std::distance(begin, line_end) <= 0)
-        return {};
-
-    std::string str(begin, line_end);
-
-    // Consume the new line character
-    if (std::distance(line_end, end) > 0)
-        ++line_end;
-
-    begin = line_end;
-    return str;
-}
-
 bool
 IceTransport::start(const std::vector<uint8_t>& rem_data)
 {
-    auto begin = rem_data.cbegin();
-    auto end = rem_data.cend();
-    auto rem_ufrag = unpackLine(begin, end);
-    auto rem_pwd = unpackLine(begin, end);
-    if (rem_pwd.empty() or rem_pwd.empty()) {
-        RING_ERR("ICE remote attributes parsing error");
-        return false;
-    }
+    std::string rem_ufrag;
+    std::string rem_pwd;
     std::vector<IceCandidate> rem_candidates;
+
+    auto data = reinterpret_cast<const char*>(rem_data.data());
+    auto size = rem_data.size();
+
     try {
-        while (true) {
-            IceCandidate candidate;
-            const auto line = unpackLine(begin, end);
-            if (line.empty())
-                break;
-            if (getCandidateFromSDP(line, candidate))
-                rem_candidates.push_back(candidate);
+        std::size_t offset = 0;
+        auto result = msgpack::unpack(data, size, offset);
+        auto version = result.get().as<uint8_t>();
+        RING_DBG("[ice:%p] rx msg v%u", this, version);
+        if (version == 1) {
+            result = msgpack::unpack(data, size, offset);
+            std::tie(rem_ufrag, rem_pwd) = result.get().as<std::pair<std::string, std::string>>();
+            result = msgpack::unpack(data, size, offset);
+            auto comp_cnt = result.get().as<uint8_t>();
+            while (comp_cnt-- > 0) {
+                result = msgpack::unpack(data, size, offset);
+                IceCandidate cand;
+                for (const auto& line : result.get().as<std::vector<std::string>>()) {
+                    if (getCandidateFromSDP(line, cand))
+                        rem_candidates.emplace_back(std::move(cand));
+                }
+            }
+        } else {
+            RING_ERR("[ice:%p] invalid msg version", this);
+            return false;
         }
-    } catch (std::exception& e) {
-        RING_ERR("ICE remote candidates parsing error");
+    } catch (const msgpack::unpack_error& e) {
+        RING_ERR("[ice:%p] remote msg unpack error: %s", this, e.what());
         return false;
     }
+
+    if (rem_pwd.empty() or rem_pwd.empty() or rem_candidates.empty()) {
+        RING_ERR("[ice:%p] invalid remote attributes", this);
+        return false;
+    }
+
     return start({rem_ufrag, rem_pwd}, rem_candidates);
 }
 
@@ -736,19 +730,20 @@ IceTransport::selectUPnPIceCandidates()
 }
 
 std::vector<uint8_t>
-IceTransport::getLocalAttributesAndCandidates() const
+IceTransport::packIceMsg() const
 {
+    static constexpr uint8_t ICE_MSG_VERSION = 1;
+
     if (not isInitialized())
         return {};
 
     std::stringstream ss;
-    ss << local_ufrag_ << NEW_LINE;
-    ss << local_pwd_ << NEW_LINE;
-    for (unsigned i=0; i<component_count_; i++) {
-        const auto& candidates = getLocalCandidates(i);
-        for (const auto& c : candidates)
-            ss << c << NEW_LINE;
-    }
+    msgpack::pack(ss, ICE_MSG_VERSION);
+    msgpack::pack(ss, std::make_pair(local_ufrag_, local_pwd_));
+    msgpack::pack(ss, static_cast<uint8_t>(component_count_));
+    for (unsigned i=0; i<component_count_; i++)
+        msgpack::pack(ss, getLocalCandidates(i));
+
     auto str(ss.str());
     return std::vector<uint8_t>(str.begin(), str.end());
 }
diff --git a/src/ice_transport.h b/src/ice_transport.h
index 1b635c2c42..622c155742 100644
--- a/src/ice_transport.h
+++ b/src/ice_transport.h
@@ -190,7 +190,7 @@ class IceTransport {
         /**
          * Returns serialized ICE attributes and candidates.
          */
-        std::vector<uint8_t> getLocalAttributesAndCandidates() const;
+        std::vector<uint8_t> packIceMsg() const;
 
         bool getCandidateFromSDP(const std::string& line, IceCandidate& cand);
 
@@ -228,9 +228,6 @@ class IceTransport {
                                        pj_ice_strans_op op,
                                        pj_status_t status);
 
-        static std::string unpackLine(std::vector<uint8_t>::const_iterator& begin,
-                                      std::vector<uint8_t>::const_iterator& end);
-
         struct IceSTransDeleter {
                 void operator ()(pj_ice_strans* ptr) {
                     pj_ice_strans_stop_ice(ptr);
diff --git a/src/im/Makefile.am b/src/im/Makefile.am
index 58cf15885a..848864b692 100644
--- a/src/im/Makefile.am
+++ b/src/im/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libim.la
 
diff --git a/src/manager.cpp b/src/manager.cpp
index daac4659fb..6eeaf1e6f1 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -248,8 +248,9 @@ Manager::setAutoAnswer(bool enable)
 Manager::Manager() :
     pluginManager_(new PluginManager)
     , preferences(), voipPreferences(),
-    hookPreference(),  audioPreference(), shortcutPreferences(),
-    hasTriedToRegister_(false)
+    hookPreference(),  audioPreference(), shortcutPreferences()
+    , videoPreferences()
+    , hasTriedToRegister_(false)
     , toneCtrl_(preferences)
     , currentCallMutex_(), dtmfKey_(), dtmfBuf_(0, AudioFormat::MONO())
     , audioLayerMutex_()
@@ -1556,7 +1557,7 @@ Manager::saveConfig()
         hookPreference.serialize(out);
         audioPreference.serialize(out);
 #ifdef RING_VIDEO
-        getVideoDeviceMonitor().serialize(out);
+        videoPreferences.serialize(out);
 #endif
         shortcutPreferences.serialize(out);
 
@@ -2662,7 +2663,7 @@ Manager::loadAccountMap(const YAML::Node &node)
     int errorCount = 0;
     try {
 #ifdef RING_VIDEO
-        getVideoDeviceMonitor().unserialize(node);
+        videoPreferences.unserialize(node);
 #endif
     } catch (const YAML::Exception &e) {
         RING_ERR("%s: No video node in config file", e.what());
@@ -2942,6 +2943,18 @@ Manager::getSinkClient(const std::string& id)
             return sink;
     return nullptr;
 }
+
+bool
+Manager::getDecodingAccelerated() const
+{
+    return videoPreferences.getDecodingAccelerated();
+}
+
+void
+Manager::setDecodingAccelerated(bool isAccelerated)
+{
+    videoPreferences.setDecodingAccelerated(isAccelerated);
+}
 #endif // RING_VIDEO
 
 } // namespace ring
diff --git a/src/manager.h b/src/manager.h
index 2734334847..f472115883 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -117,6 +117,11 @@ class Manager {
          */
         ShortcutPreferences shortcutPreferences;
 
+        /**
+         * Video preferences
+         */
+        VideoPreferences videoPreferences;
+
         // Manager should not be accessed until initialized.
         // FIXME this is an evil hack!
         static std::atomic_bool initialized;
@@ -1013,6 +1018,10 @@ class Manager {
         std::shared_ptr<video::SinkClient> getSinkClient(const std::string& id);
 
         VideoManager& getVideoManager() const { return *videoManager_; }
+
+        bool getDecodingAccelerated() const;
+
+        void setDecodingAccelerated(bool isAccelerated);
 #endif // RING_VIDEO
 
         std::atomic<unsigned> dhtLogLevel {0}; // default = disable
diff --git a/src/media/Makefile.am b/src/media/Makefile.am
index bee4635ad2..c216e36c44 100644
--- a/src/media/Makefile.am
+++ b/src/media/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libmedia.la
 
diff --git a/src/media/audio/Makefile.am b/src/media/audio/Makefile.am
index b26233d9b0..66161b3184 100644
--- a/src/media/audio/Makefile.am
+++ b/src/media/audio/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libaudio.la
 
diff --git a/src/media/audio/alsa/Makefile.am b/src/media/audio/alsa/Makefile.am
index ce6f2ad100..39c9bcdaa9 100644
--- a/src/media/audio/alsa/Makefile.am
+++ b/src/media/audio/alsa/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if BUILD_ALSA
 
diff --git a/src/media/audio/coreaudio/Makefile.am b/src/media/audio/coreaudio/Makefile.am
index be060ee961..c30686629c 100644
--- a/src/media/audio/coreaudio/Makefile.am
+++ b/src/media/audio/coreaudio/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if HAVE_OSX
 noinst_LTLIBRARIES = libcoreaudiolayer.la
diff --git a/src/media/audio/jack/Makefile.am b/src/media/audio/jack/Makefile.am
index 54d900f26c..846dda9485 100644
--- a/src/media/audio/jack/Makefile.am
+++ b/src/media/audio/jack/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if BUILD_JACK
 noinst_LTLIBRARIES = libjacklayer.la
diff --git a/src/media/audio/opensl/Makefile.am b/src/media/audio/opensl/Makefile.am
index 782af06548..b5c3ec0cf5 100644
--- a/src/media/audio/opensl/Makefile.am
+++ b/src/media/audio/opensl/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if BUILD_OPENSL
 
diff --git a/src/media/audio/portaudio/Makefile.am b/src/media/audio/portaudio/Makefile.am
index a8fed9adfe..4313987ed0 100644
--- a/src/media/audio/portaudio/Makefile.am
+++ b/src/media/audio/portaudio/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if BUILD_PORTAUDIO
 
diff --git a/src/media/audio/pulseaudio/Makefile.am b/src/media/audio/pulseaudio/Makefile.am
index 36aed1ff2b..faa11ff40a 100644
--- a/src/media/audio/pulseaudio/Makefile.am
+++ b/src/media/audio/pulseaudio/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 if BUILD_PULSE
 
diff --git a/src/media/audio/sound/Makefile.am b/src/media/audio/sound/Makefile.am
index f2ba42881f..5997ce2684 100644
--- a/src/media/audio/sound/Makefile.am
+++ b/src/media/audio/sound/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libsound.la
 
diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp
index 959e41aca7..378fcdfec4 100644
--- a/src/media/media_decoder.cpp
+++ b/src/media/media_decoder.cpp
@@ -26,6 +26,7 @@
 #include "audio/audiobuffer.h"
 #include "audio/ringbuffer.h"
 #include "audio/resampler.h"
+#include "manager.h"
 
 #if defined(RING_VIDEO) && defined(RING_ACCEL)
 #include "video/accel.h"
@@ -96,7 +97,9 @@ int MediaDecoder::openInput(const DeviceParams& params)
     RING_DBG("Trying to open device %s with format %s, pixel format %s, size %dx%d, rate %lf", params.input.c_str(),
                                                         params.format.c_str(), params.pixel_format.c_str(), params.width, params.height, params.framerate.real());
 
-    enableAccel_ = (params.enableAccel != "0");
+    // if there was a fallback to software decoding, do not enable accel
+    // it has been disabled already by the video_receive_thread
+    enableAccel_ &= Manager::instance().getDecodingAccelerated();
 
     int ret = avformat_open_input(
         &inputCtx_,
diff --git a/src/media/media_decoder.h b/src/media/media_decoder.h
index 1388688283..72531eebae 100644
--- a/src/media/media_decoder.h
+++ b/src/media/media_decoder.h
@@ -94,6 +94,7 @@ class MediaDecoder {
         int getPixelFormat() const;
 
         void setOptions(const std::map<std::string, std::string>& options);
+        void enableAccel(const bool enableAccel) { enableAccel_ = enableAccel; }
 
     private:
         NON_COPYABLE(MediaDecoder);
diff --git a/src/media/media_device.h b/src/media/media_device.h
index abf4826e03..9fb6859434 100644
--- a/src/media/media_device.h
+++ b/src/media/media_device.h
@@ -45,7 +45,6 @@ struct DeviceParams {
     std::string sdp_flags {};
     unsigned offset_x {};
     unsigned offset_y {};
-    std::string enableAccel {};
 };
 
 }
diff --git a/src/media/video/Makefile.am b/src/media/video/Makefile.am
index 80e8469480..d95ddea7da 100644
--- a/src/media/video/Makefile.am
+++ b/src/media/video/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 SUBDIRS= test
 
diff --git a/src/media/video/androidvideo/Makefile.am b/src/media/video/androidvideo/Makefile.am
index 0393a07d60..f651fc05d6 100644
--- a/src/media/video/androidvideo/Makefile.am
+++ b/src/media/video/androidvideo/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libandroidvideo.la
 
diff --git a/src/media/video/osxvideo/Makefile.am b/src/media/video/osxvideo/Makefile.am
index 5da22cf4f7..f471e28a58 100644
--- a/src/media/video/osxvideo/Makefile.am
+++ b/src/media/video/osxvideo/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libosxvideo.la
 
diff --git a/src/media/video/test/Makefile.am b/src/media/video/test/Makefile.am
index 96be9b522d..f4f44aa903 100644
--- a/src/media/video/test/Makefile.am
+++ b/src/media/video/test/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 TESTS=test_shm test_video_input test_video_rtp
 check_PROGRAMS=test_video_rtp test_video_input test_shm
diff --git a/src/media/video/uwpvideo/video_device_impl.cpp b/src/media/video/uwpvideo/video_device_impl.cpp
index 1ae628f82e..ef7aeda35e 100644
--- a/src/media/video/uwpvideo/video_device_impl.cpp
+++ b/src/media/video/uwpvideo/video_device_impl.cpp
@@ -45,26 +45,11 @@ typedef struct {
 } uwp_fmt;
 
 // have all formats map to bgra
-static const std::array<uwp_fmt, 19> uwp_formats {
+static const std::array<uwp_fmt, 4> uwp_formats {
     uwp_fmt { "MJPG",                                           VIDEO_PIXFMT_BGRA       },
     uwp_fmt { "RGB24",                                          VIDEO_PIXFMT_BGRA       },
     uwp_fmt { "NV12",                                           VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "YUY2",                                           VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{30323449-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{56555949-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb78-524f-11ce-9f53-0020af0ba7701}",        VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb7d-524f-11ce-9f53-0020af0ba7701}",        VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb7e-524f-11ce-9f53-0020af0ba770}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb79-524f-11ce-9f53-0020af0ba770}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb7c-524f-11ce-9f53-0020af0ba770}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb7b-524f-11ce-9f53-0020af0ba770}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{e436eb7a-524f-11ce-9f53-0020af0ba770}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{59565955-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{1d4a45f2-e5f6-4b44-8388-f0ae5c0e0c37}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{32595559-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{31313259-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{39555659-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       },
-    uwp_fmt { "{55595659-0000-0010-8000-00AA00389B71}",         VIDEO_PIXFMT_BGRA       }
+    uwp_fmt { "YUY2",                                           VIDEO_PIXFMT_BGRA       }
 };
 
 class VideoDeviceImpl {
diff --git a/src/media/video/v4l2/Makefile.am b/src/media/video/v4l2/Makefile.am
index 99339d3050..cd3cf3dd8e 100644
--- a/src/media/video/v4l2/Makefile.am
+++ b/src/media/video/v4l2/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libv4l2.la
 
diff --git a/src/media/video/v4l2/vaapi.cpp b/src/media/video/v4l2/vaapi.cpp
index 003d1d5cab..e18d5a2d48 100644
--- a/src/media/video/v4l2/vaapi.cpp
+++ b/src/media/video/v4l2/vaapi.cpp
@@ -154,7 +154,7 @@ VaapiAccel::open(AVCodecContext* codecCtx, std::string deviceName)
         return false;
     }
 
-    deviceBufferRef_.reset(av_buffer_ref(hardwareDeviceCtx));
+    deviceBufferRef_.reset(hardwareDeviceCtx);
 
     auto device = reinterpret_cast<AVHWDeviceContext*>(deviceBufferRef_->data);
     vaConfig_ = VA_INVALID_ID;
diff --git a/src/media/video/video_base.cpp b/src/media/video/video_base.cpp
index 2faae31e32..4a88996fd3 100644
--- a/src/media/video/video_base.cpp
+++ b/src/media/video/video_base.cpp
@@ -82,7 +82,6 @@ VideoSettings::VideoSettings(const std::map<std::string, std::string>& settings)
     channel = extractString(settings, "channel");
     video_size = extractString(settings, "size");
     framerate = extractString(settings, "rate");
-    enableAccel = extractString(settings, "enableAccel");
 }
 
 std::map<std::string, std::string>
@@ -92,8 +91,7 @@ VideoSettings::to_map() const
         {"name", name},
         {"size", video_size},
         {"channel", channel},
-        {"rate", framerate},
-        {"enableAccel", enableAccel}
+        {"rate", framerate}
     };
 }
 
@@ -108,7 +106,6 @@ convert<ring::video::VideoSettings>::encode(const ring::video::VideoSettings& rh
     node["video_size"] = rhs.video_size;
     node["channel"] = rhs.channel;
     node["framerate"] = rhs.framerate;
-    node["enableAccel"] = rhs.enableAccel;
     return node;
 }
 
@@ -122,11 +119,6 @@ convert<ring::video::VideoSettings>::decode(const Node& node, ring::video::Video
     rhs.video_size = node["video_size"].as<std::string>();
     rhs.channel = node["channel"].as<std::string>();
     rhs.framerate = node["framerate"].as<std::string>();
-    // optional setting that may or may not be there
-    try {
-        rhs.enableAccel = node["enableAccel"].as<std::string>();
-    } catch (...) {}
-
     return true;
 }
 
diff --git a/src/media/video/video_base.h b/src/media/video/video_base.h
index 0d6fe68c1f..16a9fb2c71 100644
--- a/src/media/video/video_base.h
+++ b/src/media/video/video_base.h
@@ -160,7 +160,6 @@ struct VideoSettings
     std::string channel {};
     std::string video_size {};
     std::string framerate {};
-    std::string enableAccel {};
 };
 
 }} // namespace ring::video
diff --git a/src/media/video/video_device.h b/src/media/video/video_device.h
index b4e9f69119..504501f810 100644
--- a/src/media/video/video_device.h
+++ b/src/media/video/video_device.h
@@ -128,8 +128,6 @@ public:
                       settings.framerate.c_str());
         }
 
-        settings.enableAccel = "1";
-
         return settings;
     }
 
@@ -143,7 +141,6 @@ public:
         settings.channel = params.channel_name;
         settings.video_size = sizeToString(params.width, params.height);
         settings.framerate = ring::to_string(params.framerate.real());
-        settings.enableAccel = params.enableAccel;
         return settings;
     }
 
@@ -162,7 +159,6 @@ public:
         params.width = size.first;
         params.height = size.second;
         params.framerate = rateFromString(settings.channel, size, settings.framerate);
-        params.enableAccel = settings.enableAccel;
         setDeviceParams(params);
     }
 
diff --git a/src/media/video/video_device_monitor.cpp b/src/media/video/video_device_monitor.cpp
index d5465fc982..384b40556f 100644
--- a/src/media/video/video_device_monitor.cpp
+++ b/src/media/video/video_device_monitor.cpp
@@ -292,9 +292,7 @@ VideoDeviceMonitor::overwritePreferences(VideoSettings settings)
 void
 VideoDeviceMonitor::serialize(YAML::Emitter &out)
 {
-    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
     out << YAML::Key << "devices" << YAML::Value << preferences_;
-    out << YAML::EndMap;
 }
 
 void
diff --git a/src/media/video/video_receive_thread.cpp b/src/media/video/video_receive_thread.cpp
index fa34ac64fb..73e7880125 100644
--- a/src/media/video/video_receive_thread.cpp
+++ b/src/media/video/video_receive_thread.cpp
@@ -41,14 +41,15 @@ using std::string;
 
 VideoReceiveThread::VideoReceiveThread(const std::string& id,
                                        const std::string &sdp,
-                                       const DeviceParams& args) :
+                                       const bool isReset) :
     VideoGenerator::VideoGenerator()
-    , args_(args)
+    , args_()
     , dstWidth_(0)
     , dstHeight_(0)
     , id_(id)
     , stream_(sdp)
     , restartDecoder_(false)
+    , isReset_(isReset)
     , sdpContext_(stream_.str().size(), false, &readFunction, 0, 0, this)
     , sink_ {Manager::instance().createSinkClient(id)}
     , requestKeyFrameCallback_(0)
@@ -74,6 +75,9 @@ bool VideoReceiveThread::setup()
 {
     videoDecoder_.reset(new MediaDecoder());
 
+    // disable accel if there was a fallback to software decoding
+    videoDecoder_->enableAccel(!isReset_);
+
     dstWidth_ = args_.width;
     dstHeight_ = args_.height;
 
diff --git a/src/media/video/video_receive_thread.h b/src/media/video/video_receive_thread.h
index 57d1032de8..773acd1516 100644
--- a/src/media/video/video_receive_thread.h
+++ b/src/media/video/video_receive_thread.h
@@ -47,7 +47,7 @@ class SinkClient;
 
 class VideoReceiveThread : public VideoGenerator {
 public:
-    VideoReceiveThread(const std::string &id, const std::string &sdp, const DeviceParams& args);
+    VideoReceiveThread(const std::string &id, const std::string &sdp, const bool isReset);
     ~VideoReceiveThread();
     void startLoop();
 
@@ -79,6 +79,7 @@ private:
     std::unique_ptr<MediaIOHandle> demuxContext_;
     std::shared_ptr<SinkClient> sink_;
     std::atomic_bool restartDecoder_;
+    bool isReset_;
     void (*requestKeyFrameCallback_)(const std::string &);
     void openDecoder();
     bool decodeFrame();
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index 077dff5363..72b7f97e1c 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -129,13 +129,13 @@ VideoRtpSession::restartSender()
 void VideoRtpSession::startReceiver()
 {
     if (receive_.enabled and not receive_.holding) {
-        DeviceParams receiverArgs = {};
+        bool isReset = false;
         if (receiveThread_) {
             RING_WARN("Restarting video receiver");
-            receiverArgs.enableAccel = "0"; // most likely cause of this restart
+            isReset = true;
         }
         receiveThread_.reset(
-            new VideoReceiveThread(callID_, receive_.receiving_sdp, receiverArgs)
+            new VideoReceiveThread(callID_, receive_.receiving_sdp, isReset)
         );
         /* ebail: keyframe requests can lead to timeout if they are not answered.
          * we decided so to disable them for the moment
@@ -160,7 +160,7 @@ VideoRtpSession::restartReceiver()
     if (not socketPair_)
         return;
 
-    startReceiver(); // disable accel
+    startReceiver();
 }
 
 void VideoRtpSession::start(std::unique_ptr<IceSocket> rtp_sock,
diff --git a/src/media/video/winvideo/Makefile.am b/src/media/video/winvideo/Makefile.am
index 9e45320d6c..3451b694ce 100644
--- a/src/media/video/winvideo/Makefile.am
+++ b/src/media/video/winvideo/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libwinvideo.la
 
diff --git a/src/preferences.cpp b/src/preferences.cpp
index d55ffd9ea7..0f2efb892b 100644
--- a/src/preferences.cpp
+++ b/src/preferences.cpp
@@ -45,6 +45,8 @@
 #endif
 #endif /* HAVE_OPENSL */
 
+#include "client/videomanager.h"
+
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #include <yaml-cpp/yaml.h>
@@ -122,6 +124,10 @@ static const char * const POPUP_SHORT_KEY = "popupWindow";
 static const char * const TOGGLE_HOLD_SHORT_KEY = "toggleHold";
 static const char * const TOGGLE_PICKUP_HANGUP_SHORT_KEY = "togglePickupHangup";
 
+// video preferences
+constexpr const char * const VideoPreferences::CONFIG_LABEL;
+static const char * const DECODING_ACCELERATED_KEY = "decodingAccelerated";
+
 static const char * const DFT_PULSE_LENGTH_STR = "250"; /** Default DTMF lenght */
 static const char * const ALSA_DFT_CARD    = "0";          /** Default sound card index */
 
@@ -537,4 +543,27 @@ void ShortcutPreferences::unserialize(const YAML::Node &in)
     parseValue(node, TOGGLE_PICKUP_HANGUP_SHORT_KEY, togglePickupHangup_);
 }
 
+VideoPreferences::VideoPreferences()
+    : decodingAccelerated_(false)
+{
+}
+
+void VideoPreferences::serialize(YAML::Emitter &out)
+{
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
+    getVideoDeviceMonitor().serialize(out);
+    out << YAML::EndMap;
+}
+
+void VideoPreferences::unserialize(const YAML::Node &in)
+{
+    const auto &node = in[CONFIG_LABEL];
+    // value may or may not be present
+    try {
+        parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
+    } catch (...) { decodingAccelerated_ = false; } // experimental, so disabled by default
+    getVideoDeviceMonitor().unserialize(in);
+}
+
 } // namespace ring
diff --git a/src/preferences.h b/src/preferences.h
index 1a8edbb86b..27716a4fd1 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -439,6 +439,26 @@ class ShortcutPreferences : public Serializable {
         constexpr static const char * const CONFIG_LABEL = "shortcuts";
 };
 
+class VideoPreferences : public Serializable {
+    public:
+        VideoPreferences();
+
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
+
+        bool getDecodingAccelerated() const {
+            return decodingAccelerated_;
+        }
+
+        void setDecodingAccelerated(bool decodingAccelerated) {
+            decodingAccelerated_ = decodingAccelerated;
+        }
+
+    private:
+        bool decodingAccelerated_;
+        constexpr static const char* const CONFIG_LABEL = "video";
+};
+
 } // namespace ring
 
 #endif
diff --git a/src/ringdht/Makefile.am b/src/ringdht/Makefile.am
index ecbc496385..0fc76be20b 100644
--- a/src/ringdht/Makefile.am
+++ b/src/ringdht/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 SUBDIRS = eth/libdevcore eth/libdevcrypto
 
diff --git a/src/ringdht/eth/libdevcore/Makefile.am b/src/ringdht/eth/libdevcore/Makefile.am
index 24aebec25b..4c54d4eb7b 100644
--- a/src/ringdht/eth/libdevcore/Makefile.am
+++ b/src/ringdht/eth/libdevcore/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libdevcore.la
 libdevcore_la_CPPFLAGS = @CPPFLAGS@ -DBOOST_SYSTEM_NO_DEPRECATED
diff --git a/src/ringdht/eth/libdevcrypto/Makefile.am b/src/ringdht/eth/libdevcrypto/Makefile.am
index b94f7ce16c..791c9e12c5 100644
--- a/src/ringdht/eth/libdevcrypto/Makefile.am
+++ b/src/ringdht/eth/libdevcrypto/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 AM_CPPFLAGS += -I../
 noinst_LTLIBRARIES = libdevcrypto.la
diff --git a/src/ringdht/namedirectory.cpp b/src/ringdht/namedirectory.cpp
index 0f6994948d..ec1bb6bc08 100644
--- a/src/ringdht/namedirectory.cpp
+++ b/src/ringdht/namedirectory.cpp
@@ -20,7 +20,9 @@
 #include "logger.h"
 #include "string_utils.h"
 #include "thread_pool.h"
+#include "fileutils.h"
 
+#include <msgpack.hpp>
 #include <json/json.h>
 #include <restbed>
 
@@ -28,154 +30,203 @@
 #include <ciso646>
 #include <sstream>
 #include <regex>
+#include <fstream>
 
 namespace ring {
 
 constexpr const char* const QUERY_NAME {"/name/"};
 constexpr const char* const QUERY_ADDR {"/addr/"};
-const std::regex NAME_VALIDATOR {"^[a-z0-9-_]{3,32}$"};
-const std::regex URI_VALIDATOR {"^(:?[a-zA-Z]+://)?([a-zA-Z0-9\\-._~%!$&'()*+,;=:\\[\\]]+)"};
+constexpr const char* const HTTP_PROTO {"http://"};
+
+/** Parser for Ring URIs.         ( protocol        )    ( username         ) ( hostname                            ) */
+const std::regex URI_VALIDATOR {"^([a-zA-Z]+:(?://)?)?(?:([a-z0-9-_]{1,64})@)?([a-zA-Z0-9\\-._~%!$&'()*+,;=:\\[\\]]+)"};
+const std::regex NAME_VALIDATOR {"^[a-zA-Z0-9-_]{3,32}$"};
 
 constexpr size_t MAX_RESPONSE_SIZE {1024 * 1024};
 
-std::string hostFromUri(const std::string& uri)
+void toLower(std::string& string)
+{
+    std::transform(string.begin(), string.end(), string.begin(), ::tolower);
+}
+
+void
+NameDirectory::lookupUri(const std::string& uri, const std::string& default_server, LookupCallback cb)
 {
     std::smatch pieces_match;
-    if (std::regex_search(uri, pieces_match, URI_VALIDATOR))
-        if (pieces_match.size() == 3)
-            return pieces_match[2].str();
-    return uri;
+    if (std::regex_match(uri, pieces_match, URI_VALIDATOR)) {
+        if (pieces_match.size() == 4) {
+            if (pieces_match[2].length() == 0)
+                instance(default_server).lookupName(pieces_match[3], cb);
+            else
+                instance(pieces_match[3].str()).lookupName(pieces_match[2], cb);
+            return;
+        }
+    }
+    RING_ERR("Can't parse URI: %s", uri.c_str());
+    cb("", Response::invalidName);
 }
 
-NameDirectory::NameDirectory(const std::string& s) : serverUri_(s), serverHost_(hostFromUri(s))
+NameDirectory::NameDirectory(const std::string& s)
+   : serverHost_(s),
+     cachePath_(fileutils::get_cache_dir()+DIR_SEPARATOR_STR+"namecache"+DIR_SEPARATOR_STR+serverHost_)
 {}
 
+void
+NameDirectory::load()
+{
+    loadCache();
+}
+
 NameDirectory& NameDirectory::instance(const std::string& server)
 {
-    const std::string& s = server.empty() ? DEFAULT_SERVER_URI : server;
+    const std::string& s = server.empty() ? DEFAULT_SERVER_HOST : server;
     static std::map<std::string, NameDirectory> instances {};
-    auto it = instances.emplace(s, NameDirectory{s});
-    return it.first->second;
+    auto r = instances.emplace(s, NameDirectory{s});
+    if (r.second)
+        r.first->second.load();
+    return r.first->second;
+}
+
+size_t getContentLength(restbed::Response& reply)
+{
+    size_t length = 0;
+#ifndef RESTBED_OLD_API
+    length =
+#endif
+    reply.get_header("Content-Length", length);
+    return length;
 }
 
 void NameDirectory::lookupAddress(const std::string& addr, LookupCallback cb)
 {
-    auto cacheRes = nameCache_.find(addr);
-    if (cacheRes != nameCache_.end()) {
-        cb(cacheRes->second, Response::found);
-        return;
-    }
+    try {
+        auto cacheRes = nameCache_.find(addr);
+        if (cacheRes != nameCache_.end()) {
+            cb(cacheRes->second, Response::found);
+            return;
+        }
 
-    restbed::Uri uri(serverUri_ + QUERY_ADDR + addr);
-    auto req = std::make_shared<restbed::Request>(uri);
-    req->set_header("Accept", "*/*");
-    req->set_header("Host", serverHost_);
+        restbed::Uri uri(HTTP_PROTO + serverHost_ + QUERY_ADDR + addr);
+        auto req = std::make_shared<restbed::Request>(uri);
+        req->set_header("Accept", "*/*");
+        req->set_header("Host", serverHost_);
 
-    RING_DBG("Address lookup for %s: %s", addr.c_str(), uri.to_string().c_str());
+        RING_DBG("Address lookup for %s: %s", addr.c_str(), uri.to_string().c_str());
 
-    auto ret = restbed::Http::async(req, [this,cb,addr](const std::shared_ptr<restbed::Request>,
-                                             const std::shared_ptr<restbed::Response> reply) {
-        if (reply->get_status_code() == 200) {
-            size_t length = 0;
-            length = reply->get_header("Content-Length", length);
-            if (length > MAX_RESPONSE_SIZE) {
-                cb("", Response::error);
-                return;
-            }
-            restbed::Http::fetch(length, reply);
-            std::string body;
-            reply->get_body(body);
-
-            Json::Value json;
-            Json::Reader reader;
-            if (!reader.parse(body, json)) {
-                RING_ERR("Address lookup for %s: can't parse server response: %s", addr.c_str(), body.c_str());
-                cb("", Response::error);
-                return;
-            }
-            auto name = json["name"].asString();
-            if (not name.empty()) {
-                RING_DBG("Found name for %s: %s", addr.c_str(), name.c_str());
-                addrCache_.emplace(name, addr);
-                nameCache_.emplace(addr, name);
-                cb(name, Response::found);
+        auto ret = restbed::Http::async(req, [this,cb,addr](const std::shared_ptr<restbed::Request>,
+                                                 const std::shared_ptr<restbed::Response> reply) {
+            if (reply->get_status_code() == 200) {
+                size_t length = getContentLength(*reply);
+                if (length > MAX_RESPONSE_SIZE) {
+                    cb("", Response::error);
+                    return;
+                }
+                restbed::Http::fetch(length, reply);
+                std::string body;
+                reply->get_body(body);
+
+                Json::Value json;
+                Json::Reader reader;
+                if (!reader.parse(body, json)) {
+                    RING_ERR("Address lookup for %s: can't parse server response: %s", addr.c_str(), body.c_str());
+                    cb("", Response::error);
+                    return;
+                }
+                auto name = json["name"].asString();
+                if (not name.empty()) {
+                    RING_DBG("Found name for %s: %s", addr.c_str(), name.c_str());
+                    addrCache_.emplace(name, addr);
+                    nameCache_.emplace(addr, name);
+                    cb(name, Response::found);
+                    saveCache();
+                } else {
+                    cb("", Response::notFound);
+                }
             } else {
-                cb("", Response::notFound);
+                cb("", Response::error);
             }
-        } else {
-            cb("", Response::error);
-        }
-    }).share();
+        }).share();
 
-    // avoid blocking on future destruction
-    ThreadPool::instance().run([ret](){ ret.get(); });
+        // avoid blocking on future destruction
+        ThreadPool::instance().run([ret](){ ret.get(); });
+    } catch (const std::exception& e) {
+        RING_ERR("Error when performing address lookup: %s", e.what());
+        cb("", Response::error);
+    }
 }
 
 static const std::string HEX_PREFIX {"0x"};
 
-void NameDirectory::lookupName(const std::string& name, LookupCallback cb)
+void NameDirectory::lookupName(const std::string& n, LookupCallback cb)
 {
-    if (not validateName(name)) {
-        cb(name, Response::invalidName);
-        return;
-    }
-
-    auto cacheRes = addrCache_.find(name);
-    if (cacheRes != addrCache_.end()) {
-        cb(cacheRes->second, Response::found);
-        return;
-    }
-
-    restbed::Uri uri(serverUri_ + QUERY_NAME + name);
-    auto request = std::make_shared<restbed::Request>(std::move(uri));
-    request->set_header("Accept", "*/*");
-    request->set_header("Host", serverHost_);
+    try {
+        std::string name {n};
+        if (not validateName(name)) {
+            cb(name, Response::invalidName);
+            return;
+        }
+        toLower(name);
 
-    RING_DBG("Name lookup for %s: %s", name.c_str(), uri.to_string().c_str());
+        auto cacheRes = addrCache_.find(name);
+        if (cacheRes != addrCache_.end()) {
+            cb(cacheRes->second, Response::found);
+            return;
+        }
 
-    auto ret = restbed::Http::async(request, [this,cb,name](const std::shared_ptr<restbed::Request>,
-                                                 const std::shared_ptr<restbed::Response> reply) {
-        auto code = reply->get_status_code();
-        if (code != 200)
-            RING_DBG("Name lookup for %s: got reply code %d", name.c_str(), code);
-        if (code >= 200 && code < 300) {
-            size_t length = 0;
-            length = reply->get_header("Content-Length", length);
-            if (length > MAX_RESPONSE_SIZE) {
-                cb("", Response::error);
-                return;
-            }
-            restbed::Http::fetch(length, reply);
-            std::string body;
-            reply->get_body(body);
-
-            Json::Value json;
-            Json::Reader reader;
-            if (!reader.parse(body, json)) {
-                RING_ERR("Name lookup for %s: can't parse server response: %s", name.c_str(), body.c_str());
-                cb("", Response::error);
-                return;
-            }
-            auto addr = json["addr"].asString();
-            if (!addr.compare(0, HEX_PREFIX.size(), HEX_PREFIX))
-                addr = addr.substr(HEX_PREFIX.size());
-            if (not addr.empty()) {
-                RING_DBG("Found address for %s: %s", name.c_str(), addr.c_str());
-                addrCache_.emplace(name, addr);
-                nameCache_.emplace(addr, name);
-                cb(addr, Response::found);
-            } else {
+        restbed::Uri uri(HTTP_PROTO + serverHost_ + QUERY_NAME + name);
+        auto request = std::make_shared<restbed::Request>(std::move(uri));
+        request->set_header("Accept", "*/*");
+        request->set_header("Host", serverHost_);
+
+        RING_DBG("Name lookup for %s: %s", name.c_str(), uri.to_string().c_str());
+
+        auto ret = restbed::Http::async(request, [this,cb,name](const std::shared_ptr<restbed::Request>,
+                                                     const std::shared_ptr<restbed::Response> reply) {
+            auto code = reply->get_status_code();
+            if (code != 200)
+                RING_DBG("Name lookup for %s: got reply code %d", name.c_str(), code);
+            if (code >= 200 && code < 300) {
+                size_t length = getContentLength(*reply);
+                if (length > MAX_RESPONSE_SIZE) {
+                    cb("", Response::error);
+                    return;
+                }
+                restbed::Http::fetch(length, reply);
+                std::string body;
+                reply->get_body(body);
+
+                Json::Value json;
+                Json::Reader reader;
+                if (!reader.parse(body, json)) {
+                    RING_ERR("Name lookup for %s: can't parse server response: %s", name.c_str(), body.c_str());
+                    cb("", Response::error);
+                    return;
+                }
+                auto addr = json["addr"].asString();
+                if (!addr.compare(0, HEX_PREFIX.size(), HEX_PREFIX))
+                    addr = addr.substr(HEX_PREFIX.size());
+                if (not addr.empty()) {
+                    RING_DBG("Found address for %s: %s", name.c_str(), addr.c_str());
+                    addrCache_.emplace(name, addr);
+                    nameCache_.emplace(addr, name);
+                    cb(addr, Response::found);
+                    saveCache();
+                } else {
+                    cb("", Response::notFound);
+                }
+            } else if (code >= 400 && code < 500) {
                 cb("", Response::notFound);
+            } else {
+                cb("", Response::error);
             }
-        } else if (code >= 400 && code < 500) {
-            cb("", Response::notFound);
-        } else {
-            cb("", Response::error);
-        }
-    }).share();
+        }).share();
 
-    // avoid blocking on future destruction
-    ThreadPool::instance().run([ret](){ ret.get(); });
+        // avoid blocking on future destruction
+        ThreadPool::instance().run([ret](){ ret.get(); });
+    } catch (const std::exception& e) {
+        RING_ERR("Error when performing name lookup: %s", e.what());
+        cb("", Response::error);
+    }
 }
 
 bool NameDirectory::validateName(const std::string& name) const
@@ -183,79 +234,123 @@ bool NameDirectory::validateName(const std::string& name) const
     return std::regex_match(name, NAME_VALIDATOR);
 }
 
-void NameDirectory::registerName(const std::string& addr, const std::string& name, const std::string& owner, RegistrationCallback cb)
+void NameDirectory::registerName(const std::string& addr, const std::string& n, const std::string& owner, RegistrationCallback cb)
 {
-    if (not validateName(name)) {
-        cb(RegistrationResponse::invalidName);
-        return;
-    }
+    try {
+        std::string name {n};
+        if (not validateName(name)) {
+            cb(RegistrationResponse::invalidName);
+            return;
+        }
+        toLower(name);
+
+        auto cacheRes = addrCache_.find(name);
+        if (cacheRes != addrCache_.end()) {
+            if (cacheRes->second == addr)
+                cb(RegistrationResponse::success);
+            else
+                cb(RegistrationResponse::alreadyTaken);
+            return;
+        }
 
-    auto cacheRes = addrCache_.find(name);
-    if (cacheRes != addrCache_.end()) {
-        if (cacheRes->second == addr)
-            cb(RegistrationResponse::success);
-        else
-            cb(RegistrationResponse::alreadyTaken);
-        return;
-    }
+        auto request = std::make_shared<restbed::Request>(restbed::Uri(HTTP_PROTO + serverHost_ + QUERY_NAME + name));
+        request->set_header("Accept", "*/*");
+        request->set_header("Host", serverHost_);
+        request->set_header("Content-Type", "application/json");
+        request->set_method("POST");
+        std::string body;
+        {
+            std::stringstream ss;
+            ss << "{\"addr\":\"" << addr << "\",\"owner\":\"" << owner << "\"}";
+            body = ss.str();
+        }
+        request->set_body(body);
+        request->set_header("Content-Length", ring::to_string(body.size()));
+
+        auto params = std::make_shared<restbed::Settings>();
+        params->set_connection_timeout(std::chrono::seconds(120));
+
+        RING_WARN("registerName: sending request %s %s", addr.c_str(), name.c_str());
+        auto ret = restbed::Http::async(request,
+                             [this,cb,addr,name](const std::shared_ptr<restbed::Request>,
+                                                 const std::shared_ptr<restbed::Response> reply)
+        {
+            auto code = reply->get_status_code();
+            RING_DBG("Got reply for registration of %s -> %s: code %d", name.c_str(), addr.c_str(), code);
+            if (code >= 200 && code < 300) {
+                size_t length = getContentLength(*reply);
+                if (length > MAX_RESPONSE_SIZE) {
+                    cb(RegistrationResponse::error);
+                    return;
+                }
+                restbed::Http::fetch(length, reply);
+                std::string body;
+                reply->get_body(body);
+
+                Json::Value json;
+                Json::Reader reader;
+                if (!reader.parse(body, json)) {
+                    cb(RegistrationResponse::error);
+                    return;
+                }
+                auto success = json["success"].asBool();
+                RING_DBG("Got reply for registration of %s -> %s: %s", name.c_str(), addr.c_str(), success ? "success" : "failure");
+                if (success) {
+                    addrCache_.emplace(name, addr);
+                    nameCache_.emplace(addr, name);
+                }
+                cb(success ? RegistrationResponse::success : RegistrationResponse::error);
+            } else if (code >= 400 && code < 500) {
+                cb(RegistrationResponse::alreadyTaken);
+            } else {
+                cb(RegistrationResponse::error);
+            }
+        }, params).share();
 
-    auto request = std::make_shared<restbed::Request>(restbed::Uri(serverUri_ + QUERY_NAME + name));
-    request->set_header("Accept", "*/*");
-    request->set_header("Host", serverHost_);
-    request->set_header("Content-Type", "application/json");
-    request->set_method("POST");
-    std::string body;
-    {
-        std::stringstream ss;
-        ss << "{\"addr\":\"" << addr << "\",\"owner\":\"" << owner << "\"}";
-        body = ss.str();
+        // avoid blocking on future destruction
+        ThreadPool::instance().run([ret](){ ret.get(); });
+    } catch (const std::exception& e) {
+        RING_ERR("Error when performing name registration: %s", e.what());
+        cb(RegistrationResponse::error);
     }
-    request->set_body(body);
-    request->set_header("Content-Length", ring::to_string(body.size()));
+}
 
-    auto params = std::make_shared<restbed::Settings>();
-    params->set_connection_timeout(std::chrono::seconds(60));
+void
+NameDirectory::saveCache()
+{
+    fileutils::recursive_mkdir(fileutils::get_cache_dir()+DIR_SEPARATOR_STR+"namecache");
+    std::ofstream file(cachePath_, std::ios::trunc);
+    msgpack::pack(file, nameCache_);
+    RING_DBG("Saved %lu name-address mappings", (long unsigned)nameCache_.size());
+}
 
-    RING_WARN("registerName: sending request %s %s", addr.c_str(), name.c_str());
-    auto ret = restbed::Http::async(request,
-                         [this,cb,addr,name](const std::shared_ptr<restbed::Request>,
-                                             const std::shared_ptr<restbed::Response> reply)
-    {
-        auto code = reply->get_status_code();
-        RING_DBG("Got reply for registration of %s -> %s: code %d", name.c_str(), addr.c_str(), code);
-        if (code >= 200 && code < 300) {
-            size_t length = 0;
-            length = reply->get_header("Content-Length", length);
-            if (length > MAX_RESPONSE_SIZE) {
-                cb(RegistrationResponse::error);
-                return;
-            }
-            restbed::Http::fetch(length, reply);
-            std::string body;
-            reply->get_body(body);
+void
+NameDirectory::loadCache()
+{
+    msgpack::unpacker pac;
 
-            Json::Value json;
-            Json::Reader reader;
-            if (!reader.parse(body, json)) {
-                cb(RegistrationResponse::error);
-                return;
-            }
-            auto success = json["success"].asBool();
-            RING_DBG("Got reply for registration of %s -> %s: %s", name.c_str(), addr.c_str(), success ? "success" : "failure");
-            if (success) {
-                addrCache_.emplace(name, addr);
-                nameCache_.emplace(addr, name);
-            }
-            cb(success ? RegistrationResponse::success : RegistrationResponse::error);
-        } else if (code >= 400 && code < 500) {
-            cb(RegistrationResponse::alreadyTaken);
-        } else {
-            cb(RegistrationResponse::error);
+    // read file
+    {
+        std::ifstream file(cachePath_);
+        if (!file.is_open()) {
+            RING_DBG("Could not load %s", cachePath_.c_str());
+            return;
+        }
+        std::string line;
+        while (std::getline(file, line)) {
+            pac.reserve_buffer(line.size());
+            memcpy(pac.buffer(), line.data(), line.size());
+            pac.buffer_consumed(line.size());
         }
-    }, params).share();
+    }
 
-    // avoid blocking on future destruction
-    ThreadPool::instance().run([ret](){ ret.get(); });
+    // load values
+    msgpack::object_handle oh;
+    if (pac.next(oh))
+        oh.get().convert(nameCache_);
+    for (const auto& m : nameCache_)
+        addrCache_.emplace(m.second, m.first);
+    RING_DBG("Loaded %lu name-address mappings", (long unsigned)nameCache_.size());
 }
 
 }
diff --git a/src/ringdht/namedirectory.h b/src/ringdht/namedirectory.h
index e8acc6f2a4..7528bef1a0 100644
--- a/src/ringdht/namedirectory.h
+++ b/src/ringdht/namedirectory.h
@@ -26,36 +26,44 @@ namespace ring {
 class NameDirectory
 {
 public:
+    enum class Response : int { found = 0, invalidName, notFound, error };
+    enum class RegistrationResponse : int { success = 0, invalidName, alreadyTaken, error };
+
+    using LookupCallback = std::function<void(const std::string& result, Response response)>;
+    using RegistrationCallback = std::function<void(RegistrationResponse response)>;
+
     NameDirectory() {}
     NameDirectory(const std::string& s);
+    void load();
 
     static NameDirectory& instance(const std::string& server);
-    static NameDirectory& instance() { return instance(DEFAULT_SERVER_URI); }
+    static NameDirectory& instance() { return instance(DEFAULT_SERVER_HOST); }
 
-    enum class Response : int { found = 0, invalidName, notFound, error };
-    enum class RegistrationResponse : int { success = 0, invalidName, alreadyTaken, error };
+    static void lookupUri(const std::string& uri, const std::string& default_server, LookupCallback cb);
 
-    using LookupCallback = std::function<void(const std::string& result, Response response)>;
     void lookupAddress(const std::string& addr, LookupCallback cb);
     void lookupName(const std::string& name, LookupCallback cb);
 
-    using RegistrationCallback = std::function<void(RegistrationResponse response)>;
     void registerName(const std::string& addr, const std::string& name, const std::string& owner, RegistrationCallback cb);
 
     const std::string& getServer() const {
-        return serverUri_;
+        return serverHost_;
     }
 
 private:
-    constexpr static const char* const DEFAULT_SERVER_URI = "http://5.196.89.112:3000";
+    constexpr static const char* const DEFAULT_SERVER_HOST = "ns.ring.cx";
+
+    const std::string serverHost_ {DEFAULT_SERVER_HOST};
+    const std::string cachePath_;
 
-    const std::string serverUri_ {DEFAULT_SERVER_URI};
-    const std::string serverHost_ {};
     std::map<std::string, std::string> nameCache_;
     std::map<std::string, std::string> addrCache_;
 
+
     bool validateName(const std::string& name) const;
 
+    void saveCache();
+    void loadCache();
 };
 
 }
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 8147c514a7..e39cc54906 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -237,7 +237,7 @@ RingAccount::newOutgoingSIPCall(const std::string& toUrl)
     } catch (...) {
 #if HAVE_RINGNS
         std::weak_ptr<RingAccount> wthis_ = std::static_pointer_cast<RingAccount>(shared_from_this());
-        nameDir_.get().lookupName(sufix, [wthis_,call](const std::string& result, NameDirectory::Response response) mutable {
+        NameDirectory::lookupUri(sufix, nameServer_, [wthis_,call](const std::string& result, NameDirectory::Response response) mutable {
             runOnMainThread([=]() mutable {
                 if (auto sthis = wthis_.lock()) {
                     try {
@@ -269,6 +269,7 @@ RingAccount::startOutgoingCall(std::shared_ptr<SIPCall>& call, const std::string
 
     const auto toH = dht::InfoHash(toUri);
 
+    call->setPeerNumber(toUri + "@ring.dht");
     call->setState(Call::ConnectionState::TRYING);
     std::weak_ptr<SIPCall> wCall = call;
 
@@ -325,7 +326,7 @@ RingAccount::startOutgoingCall(std::shared_ptr<SIPCall>& call, const std::string
                     const dht::Value::Id callvid  = udist(sthis->rand_);
                     const dht::Value::Id vid  = udist(sthis->rand_);
                     const auto callkey = dht::InfoHash::get("callto:" + dev.dev.toString());
-                    dht::Value val { dht::IceCandidates(callvid, ice->getLocalAttributesAndCandidates()) };
+                    dht::Value val { dht::IceCandidates(callvid, ice->packIceMsg()) };
                     val.id = vid;
 
                     sthis->dht_.putEncrypted(
@@ -528,7 +529,7 @@ void RingAccount::serialize(YAML::Emitter &out)
     out << YAML::Key << Conf::DHT_ALLOW_PEERS_FROM_TRUSTED << YAML::Value << allowPeersFromTrusted_;
 
 #if HAVE_RINGNS
-    out << YAML::Key << DRing::Account::ConfProperties::RingNS::URI << YAML::Value <<  nameDir_.get().getServer();
+    out << YAML::Key << DRing::Account::ConfProperties::RingNS::URI << YAML::Value <<  nameServer_;
 #endif
 
     out << YAML::Key << DRing::Account::ConfProperties::ARCHIVE_PATH << YAML::Value << archivePath_;
@@ -571,9 +572,12 @@ void RingAccount::unserialize(const YAML::Node &node)
     dhtPortUsed_ = dhtPort_;
 
 #if HAVE_RINGNS
-    std::string ringns_server;
-    parseValue(node, DRing::Account::ConfProperties::RingNS::URI, ringns_server);
-    nameDir_ = NameDirectory::instance(ringns_server);
+    try {
+        parseValue(node, DRing::Account::ConfProperties::RingNS::URI, nameServer_);
+    } catch (const std::exception& e) {
+        RING_WARN("can't read name server: %s", e.what());
+    }
+    nameDir_ = NameDirectory::instance(nameServer_);
 #endif
 
     parseValue(node, Conf::DHT_PUBLIC_IN_CALLS, dhtPublicInCalls_);
@@ -1122,6 +1126,10 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string&
             // no receipt or archive, creating new account
             if (archive_password.empty()) {
                 RING_WARN("Password needed to create archive");
+                if (identity_.first) {
+                    ringAccountId_ = identity_.first->getPublicKey().getId().toString();
+                    username_ = RING_URI_PREFIX+ringAccountId_;
+                }
                 setRegistrationState(RegistrationState::ERROR_NEED_MIGRATION);
             } else {
                 if (archive_pin.empty()) {
@@ -1169,9 +1177,9 @@ RingAccount::setAccountDetails(const std::map<std::string, std::string> &details
     parseString(details, DRing::Account::ConfProperties::ARCHIVE_PATH,     archivePath_);
 
 #if HAVE_RINGNS
-    std::string ringns_server;
-    parseString(details, DRing::Account::ConfProperties::RingNS::URI,     ringns_server);
-    nameDir_ = NameDirectory::instance(ringns_server);
+    //std::string ringns_server;
+    parseString(details, DRing::Account::ConfProperties::RingNS::URI,     nameServer_);
+    nameDir_ = NameDirectory::instance(nameServer_);
 #endif
 
     loadAccount(archive_password, archive_pin);
@@ -1206,7 +1214,7 @@ RingAccount::getAccountDetails() const
     //a.emplace(DRing::Account::ConfProperties::ETH::KEY_FILE,               ethPath_);
     a.emplace(DRing::Account::ConfProperties::RingNS::ACCOUNT,               ethAccount_);
 #if HAVE_RINGNS
-    a.emplace(DRing::Account::ConfProperties::RingNS::URI,                  nameDir_.get().getServer());
+    a.emplace(DRing::Account::ConfProperties::RingNS::URI,                   nameDir_.get().getServer());
 #endif
 
     return a;
@@ -1229,7 +1237,7 @@ void
 RingAccount::lookupName(const std::string& name)
 {
     auto acc = getAccountID();
-    nameDir_.get().lookupName(name, [acc,name](const std::string& result, NameDirectory::Response response) {
+    NameDirectory::lookupUri(name, nameServer_, [acc,name](const std::string& result, NameDirectory::Response response) {
         emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>(acc, (int)response, result, name);
     });
 }
@@ -1850,13 +1858,14 @@ RingAccount::replyToIncomingIceMsg(std::shared_ptr<SIPCall> call,
                                   std::shared_ptr<dht::crypto::Certificate> peer_cert)
 {
     const auto vid = udist(rand_);
-    dht::Value val { dht::IceCandidates(peer_ice_msg.id, ice->getLocalAttributesAndCandidates()) };
+    dht::Value val { dht::IceCandidates(peer_ice_msg.id, ice->packIceMsg()) };
     val.id = vid;
 
+    auto from = (peer_cert ? (peer_cert->issuer ? peer_cert->issuer->getId() : peer_cert->getId()) : peer_ice_msg.from).toString();
+
     std::weak_ptr<SIPCall> wcall = call;
 #if HAVE_RINGNS
-    auto from_acc_id = peer_cert ? (peer_cert->issuer ? peer_cert->issuer->getId().toString() : peer_cert->getId().toString()) : peer_ice_msg.from.toString();
-    nameDir_.get().lookupAddress(from_acc_id, [wcall](const std::string& result, const NameDirectory::Response& response){
+    nameDir_.get().lookupAddress(from, [wcall](const std::string& result, const NameDirectory::Response& response){
         if (response == NameDirectory::Response::found)
             if (auto call = wcall.lock())
                 call->setPeerRegistredName(result);
@@ -1886,7 +1895,6 @@ RingAccount::replyToIncomingIceMsg(std::shared_ptr<SIPCall> call,
         return;
     }
 
-    auto from = peer_ice_msg.from.toString();
     call->setPeerNumber(from);
     call->initRecFilename(from);
 
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index 1839fdec87..487fa8080a 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -350,6 +350,7 @@ class RingAccount : public SIPAccountBase {
 
 #if HAVE_RINGNS
         std::reference_wrapper<NameDirectory> nameDir_;
+        std::string nameServer_;
         std::string registeredName_;
 #endif
 
diff --git a/src/security/Makefile.am b/src/security/Makefile.am
index 8321a993b0..87ae2f1826 100644
--- a/src/security/Makefile.am
+++ b/src/security/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libsecurity.la
 libsecurity_la_CXXFLAGS = @CXXFLAGS@ -I$(top_srcdir)/src
diff --git a/src/sip/Makefile.am b/src/sip/Makefile.am
index 71f7b272b3..ded7512cf5 100644
--- a/src/sip/Makefile.am
+++ b/src/sip/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libsiplink.la
 libsiplink_la_CXXFLAGS = @CXXFLAGS@ -I$(top_srcdir)/src
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 5ff8403627..6c62d60698 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -671,7 +671,9 @@ SIPCall::sendTextMessage(const std::map<std::string, std::string>& messages,
             c->sendTextMessage(messages, from);
     } else {
         if (inv) {
-            im::sendSipMessage(inv.get(), messages);
+            try {
+                im::sendSipMessage(inv.get(), messages);
+            } catch (...) {}
         } else {
             pendingOutMessages_.emplace_back(messages, from);
             RING_ERR("[call:%s] sendTextMessage: no invite session for this call", getCallId().c_str());
diff --git a/src/upnp/Makefile.am b/src/upnp/Makefile.am
index 353152f5ba..60a07466cb 100644
--- a/src/upnp/Makefile.am
+++ b/src/upnp/Makefile.am
@@ -1,4 +1,4 @@
-include $(top_srcdir)/globals.mak
+include $(top_srcdir)/globals.mk
 
 noinst_LTLIBRARIES = libupnpcontrol.la
 
-- 
GitLab