diff --git a/daemon/src/ringdht/sip_transport_ice.cpp b/daemon/src/ringdht/sip_transport_ice.cpp
index daa4ea5b36dcdbdab56789fb4251530dfc4fbf25..593d217bce4154c0cc5a4b4d47ff0eaba8032e4d 100644
--- a/daemon/src/ringdht/sip_transport_ice.cpp
+++ b/daemon/src/ringdht/sip_transport_ice.cpp
@@ -165,10 +165,10 @@ SipIceTransport::~SipIceTransport()
 }
 
 void
-SipIceTransport::start()
+SipIceTransport::loop()
 {
-    using namespace std::placeholders;
-    ice_->setOnRecv(comp_id_, std::bind(&SipIceTransport::onRecv, this, _1, _2));
+    while (ice_->getNextPacketSize(comp_id_) > 0)
+        onRecv();
 }
 
 IpAddr
@@ -215,11 +215,11 @@ SipIceTransport::send(pjsip_tx_data *tdata, const pj_sockaddr_t *rem_addr,
 }
 
 ssize_t
-SipIceTransport::onRecv(uint8_t* buf, size_t len)
+SipIceTransport::onRecv()
 {
-    auto max_size = std::min<size_t>(sizeof(rdata.pkt_info.packet) - rdata.pkt_info.len, len);
-    std::copy_n(buf, max_size, (uint8_t*)rdata.pkt_info.packet + rdata.pkt_info.len);
-    rdata.pkt_info.len += max_size;
+    rdata.pkt_info.len += ice_->recv(comp_id_,
+        (uint8_t*)rdata.pkt_info.packet+rdata.pkt_info.len,
+        sizeof(rdata.pkt_info.packet)-rdata.pkt_info.len);
     rdata.pkt_info.zero = 0;
     pj_gettimeofday(&rdata.pkt_info.timestamp);
 
diff --git a/daemon/src/ringdht/sip_transport_ice.h b/daemon/src/ringdht/sip_transport_ice.h
index 2adccd3a13393d5a21ab21f844fa63858efca0b1..8c891861814345ca05e464ecfb66ef7e71b60b92 100644
--- a/daemon/src/ringdht/sip_transport_ice.h
+++ b/daemon/src/ringdht/sip_transport_ice.h
@@ -49,9 +49,9 @@ struct SipIceTransport
         ~SipIceTransport();
 
         /**
-         * To be called once to start receiving packets
+         * To be called on a regular basis to receive packets
          */
-        void start();
+        void loop();
 
         IpAddr getLocalAddress() const;
 
@@ -76,7 +76,7 @@ struct SipIceTransport
                          int addr_len, void *token,
                          pjsip_transport_callback callback);
 
-        ssize_t onRecv(uint8_t* buf, size_t len);
+        ssize_t onRecv();
 
         pj_status_t shutdown();
 
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index 94ddcd3fe115f9f3d7b04828bf203d091166e514..40f30404f0abeb58e0988bb125f928866e6df57b 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -160,11 +160,14 @@ cp_(cp), pool_(pool), endpt_(endpt)
 #if HAVE_DHT
     pjsip_transport_register_type(PJSIP_TRANSPORT_DATAGRAM, "ICE", pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP), &ice_pj_transport_type_);
 #endif
+
+    Manager::instance().registerEventHandler((uintptr_t)this, [this]{ handleEvents(); });
 }
 
 SipTransportBroker::~SipTransportBroker()
 {
     SFL_DBG("Destroying SipTransportBroker");
+    Manager::instance().unregisterEventHandler((uintptr_t)this);
 
     {
         std::lock_guard<std::mutex> lock(transportMapMutex_);
@@ -239,6 +242,14 @@ SipTransportBroker::transportStateChanged(pjsip_transport* tp, pjsip_transport_s
     }
 }
 
+void
+SipTransportBroker::handleEvents()
+{
+    std::unique_lock<std::mutex> lock(iceMutex_);
+    for (auto& t : iceTransports_)
+        t.loop();
+}
+
 std::shared_ptr<SipTransport>
 SipTransportBroker::findTransport(pjsip_transport* t)
 {
@@ -432,7 +443,6 @@ SipTransportBroker::getIceTransport(const std::shared_ptr<sfl::IceTransport> ice
         std::unique_lock<std::mutex> lock(transportMapMutex_);
         transports_[ret->get()] = ret;
     }
-    sip_ice_tr.start();
     return ret;
 }
 #endif
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index 4c64d4cbe94c13ef002e74721d5891be98d507d2..52f929b4bc2981401d9af6124329e515d16fa80f 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -213,6 +213,8 @@ private:
 
     void transportStateChanged(pjsip_transport*, pjsip_transport_state, const pjsip_transport_state_info*);
 
+    void handleEvents();
+
     /**
      * List of transports so we can bubble the events up.
      */