diff --git a/ChangeLog b/ChangeLog
index 8f2f58aec..165dc5013 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -30,6 +30,7 @@ release 0.14.2
 	* fixed bug where the files requested from web seeds would be the
 	  renamed file names instead of the original file names in the torrent.
 	* documentation fix of queing section
+	* fixed potential issue in udp_socket (affected udp tracker support)
 
 release 0.14.1
 
diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp
index 0c0f1df6d..a06fc8bee 100644
--- a/include/libtorrent/udp_socket.hpp
+++ b/include/libtorrent/udp_socket.hpp
@@ -52,6 +52,7 @@ namespace libtorrent
 			, udp::endpoint const&, char const* buf, int size)> callback_t;
 
 		udp_socket(io_service& ios, callback_t const& c, connection_queue& cc);
+		~udp_socket();
 
 		bool is_open() const { return m_ipv4_sock.is_open() || m_ipv6_sock.is_open(); }
 		io_service& get_io_service() { return m_ipv4_sock.get_io_service(); }
@@ -65,15 +66,7 @@ namespace libtorrent
 		void set_proxy_settings(proxy_settings const& ps);
 		proxy_settings const& get_proxy_settings() { return m_proxy_settings; }
 
-#ifdef TORRENT_DEBUG
-		~udp_socket()
-		{
-			TORRENT_ASSERT(m_magic == 0x1337);
-			TORRENT_ASSERT(m_outstanding == 0);
-			TORRENT_ASSERT(!m_callback);
-			m_magic = 0;
-		}
-#endif
+		bool is_closed() const { return m_abort; }
 
 	private:
 
@@ -114,6 +107,7 @@ namespace libtorrent
 		tcp::resolver m_resolver;
 		char m_tmp_buf[100];
 		bool m_tunnel_packets;
+		bool m_abort;
 		udp::endpoint m_proxy_addr;
 #ifdef TORRENT_DEBUG
 		int m_magic;
@@ -140,7 +134,6 @@ namespace libtorrent
 		int m_queue_size_limit;
 		int m_rate_limit;
 		int m_quota;
-		bool m_abort;
 		ptime m_last_tick;
 		std::list<queued_packet> m_queue;
 	};
diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp
index 07fa24071..3b3c6c8b8 100644
--- a/src/udp_socket.cpp
+++ b/src/udp_socket.cpp
@@ -24,12 +24,23 @@ udp_socket::udp_socket(asio::io_service& ios, udp_socket::callback_t const& c
 	, m_cc(cc)
 	, m_resolver(ios)
 	, m_tunnel_packets(false)
+	, m_abort(false)
 {
 #ifdef TORRENT_DEBUG
 	m_magic = 0x1337;
 #endif
 }
 
+udp_socket::~udp_socket()
+{
+#ifdef TORRENT_DEBUG
+	TORRENT_ASSERT(m_magic == 0x1337);
+	TORRENT_ASSERT(!m_callback);
+	TORRENT_ASSERT(m_outstanding == 0);
+	m_magic = 0;
+#endif
+}
+
 #ifdef TORRENT_DEBUG
 	#define CHECK_MAGIC check_magic_ cm_(m_magic)
 	struct check_magic_
@@ -119,6 +130,8 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
 			return;
 		}
 
+		if (m_abort) return;
+
 		if (s == &m_ipv4_sock)
 			s->async_receive_from(asio::buffer(m_v4_buf, sizeof(m_v4_buf))
 				, m_v4_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2));
@@ -151,6 +164,9 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
 #ifndef BOOST_NO_EXCEPTIONS
 		} catch(std::exception&) {}
 #endif
+
+		if (m_abort) return;
+
 		s->async_receive_from(asio::buffer(m_v4_buf, sizeof(m_v4_buf))
 			, m_v4_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2));
 	}
@@ -175,6 +191,9 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_
 		} catch(std::exception&) {}
 #endif
 		l.lock();
+
+		if (m_abort) return;
+
 		s->async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf))
 			, m_v6_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2));
 	}
@@ -252,6 +271,7 @@ void udp_socket::close()
 	m_ipv6_sock.close(ec);
 	m_socks5_sock.close(ec);
 	m_resolver.cancel();
+	m_abort = true;
 	if (m_connection_ticket >= 0)
 	{
 		m_cc.done(m_connection_ticket);
@@ -571,7 +591,6 @@ rate_limited_udp_socket::rate_limited_udp_socket(io_service& ios
 	, m_queue_size_limit(200)
 	, m_rate_limit(4000)
 	, m_quota(4000)
-	, m_abort(false)
 	, m_last_tick(time_now())
 {
 	error_code ec;
@@ -602,7 +621,7 @@ bool rate_limited_udp_socket::send(udp::endpoint const& ep, char const* p, int l
 void rate_limited_udp_socket::on_tick(error_code const& e)
 {
 	if (e) return;
-	if (m_abort) return;
+	if (is_closed()) return;
 	error_code ec;
 	ptime now = time_now();
 	m_timer.expires_at(now + seconds(1), ec);
@@ -627,7 +646,6 @@ void rate_limited_udp_socket::on_tick(error_code const& e)
 void rate_limited_udp_socket::close()
 {
 	error_code ec;
-	m_abort = true;
 	m_timer.cancel(ec);
 	udp_socket::close();
 }