removed the reuse-address flag on the listen socket

This commit is contained in:
Arvid Norberg 2010-06-17 17:14:56 +00:00
parent 19df3dbc2f
commit 26c4a819c8
6 changed files with 36 additions and 18 deletions

View File

@ -1,3 +1,4 @@
* made the reuse-address flag configurable on the listen socket
* moved UDP trackers over to use a single socket * moved UDP trackers over to use a single socket
* added feature to make asserts log to a file instead of breaking the process * added feature to make asserts log to a file instead of breaking the process
(production asserts) (production asserts)
@ -32,6 +33,7 @@
incoming connection incoming connection
* added more detailed instrumentation of the disk I/O thread * added more detailed instrumentation of the disk I/O thread
* removed the reuse-address flag on the listen socket
* fixed bug where local peer discovery and DHT wouldn't be announced to without trackers * fixed bug where local peer discovery and DHT wouldn't be announced to without trackers
* fixed bug in bdecoder when decoding invalid messages * fixed bug in bdecoder when decoding invalid messages
* added build warning when building with UNICODE but the standard library * added build warning when building with UNICODE but the standard library

View File

@ -207,9 +207,12 @@ The ``session`` class has the following synopsis::
bool is_listening() const; bool is_listening() const;
unsigned short listen_port() const; unsigned short listen_port() const;
enum { listen_reuse_address = 1 };
bool listen_on( bool listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, char const* interface = 0); , char const* interface = 0
, int flags = 0);
std::auto_ptr<alert> pop_alert(); std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
@ -917,7 +920,8 @@ is_listening() listen_port() listen_on()
unsigned short listen_port() const; unsigned short listen_port() const;
bool listen_on( bool listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, char const* interface = 0); , char const* interface = 0
, int flags = 0);
``is_listening()`` will tell you whether or not the session has successfully ``is_listening()`` will tell you whether or not the session has successfully
opened a listening port. If it hasn't, this function will return false, and opened a listening port. If it hasn't, this function will return false, and
@ -946,6 +950,11 @@ listen on multiple interfaces (typically 0.0.0.0 and ::). This means that if you
IPv6 interface doesn't work, you may still see a listen_failed_alert_, even though IPv6 interface doesn't work, you may still see a listen_failed_alert_, even though
the IPv4 port succeeded. the IPv4 port succeeded.
The ``flags`` parameter can either be 0 or ``session::listen_reuse_address``, which
will set the reuse address socket option on the listen socket(s). By default, the
listen socket does not use reuse address. If you're running a service that needs
to run on a specific port no matter if it's in use, set this flag.
If you're also starting the DHT, it is a good idea to do that after you've called If you're also starting the DHT, it is a good idea to do that after you've called
``listen_on()``, since the default listen port for the DHT is the same as the tcp ``listen_on()``, since the default listen port for the DHT is the same as the tcp
listen socket. If you start the DHT first, it will assume the tcp port is free and listen socket. If you start the DHT first, it will assume the tcp port is free and

View File

@ -161,7 +161,7 @@ namespace libtorrent
#endif #endif
void main_thread(); void main_thread();
void open_listen_port(); void open_listen_port(bool reuse_address);
// if we are listening on an IPv6 interface // if we are listening on an IPv6 interface
// this will return one of the IPv6 addresses on this // this will return one of the IPv6 addresses on this
@ -236,7 +236,8 @@ namespace libtorrent
bool listen_on( bool listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, const char* net_interface = 0); , const char* net_interface = 0
, int flags = 0);
bool is_listening() const; bool is_listening() const;
torrent_handle add_torrent(add_torrent_params const&, error_code& ec); torrent_handle add_torrent(add_torrent_params const&, error_code& ec);
@ -580,7 +581,8 @@ namespace libtorrent
boost::shared_ptr<socket_type> m_i2p_listen_socket; boost::shared_ptr<socket_type> m_i2p_listen_socket;
#endif #endif
listen_socket_t setup_listener(tcp::endpoint ep, int retries, bool v6_only = false); listen_socket_t setup_listener(tcp::endpoint ep, int retries
, bool v6_only, bool reuse_address);
// the settings for the client // the settings for the client
session_settings m_settings; session_settings m_settings;

View File

@ -322,9 +322,12 @@ namespace libtorrent
// this function will return false on failure. // this function will return false on failure.
// If it fails, it will also generate alerts describing // If it fails, it will also generate alerts describing
// the error. It will return true on success. // the error. It will return true on success.
enum { listen_reuse_address = 1 };
bool listen_on( bool listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, const char* net_interface = 0); , const char* net_interface = 0
, int flags = 0);
// returns the port we ended up listening on // returns the port we ended up listening on
unsigned short listen_port() const; unsigned short listen_port() const;

View File

@ -548,10 +548,10 @@ namespace libtorrent
bool session::listen_on( bool session::listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, const char* net_interface) , const char* net_interface, int flags)
{ {
mutex::scoped_lock l(m_impl->m_mutex); mutex::scoped_lock l(m_impl->m_mutex);
return m_impl->listen_on(port_range, net_interface); return m_impl->listen_on(port_range, net_interface, flags);
} }
unsigned short session::listen_port() const unsigned short session::listen_port() const

View File

@ -744,7 +744,8 @@ namespace aux {
boost::bind(&session_impl::on_dht_announce, this, _1)); boost::bind(&session_impl::on_dht_announce, this, _1));
#endif #endif
open_listen_port(); // no reuse_address
open_listen_port(false);
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this))); m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
} }
@ -1304,12 +1305,13 @@ namespace aux {
} }
session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep session_impl::listen_socket_t session_impl::setup_listener(tcp::endpoint ep
, int retries, bool v6_only) , int retries, bool v6_only, bool reuse_address)
{ {
error_code ec; error_code ec;
listen_socket_t s; listen_socket_t s;
s.sock.reset(new socket_acceptor(m_io_service)); s.sock.reset(new socket_acceptor(m_io_service));
s.sock->open(ep.protocol(), ec); s.sock->open(ep.protocol(), ec);
if (reuse_address)
s.sock->set_option(socket_acceptor::reuse_address(true), ec); s.sock->set_option(socket_acceptor::reuse_address(true), ec);
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
if (ep.protocol() == tcp::v6()) if (ep.protocol() == tcp::v6())
@ -1380,7 +1382,7 @@ namespace aux {
return s; return s;
} }
void session_impl::open_listen_port() void session_impl::open_listen_port(bool reuse_address)
{ {
// close the open listen sockets // close the open listen sockets
m_listen_sockets.clear(); m_listen_sockets.clear();
@ -1396,7 +1398,7 @@ namespace aux {
listen_socket_t s = setup_listener( listen_socket_t s = setup_listener(
tcp::endpoint(address_v4::any(), m_listen_interface.port()) tcp::endpoint(address_v4::any(), m_listen_interface.port())
, m_listen_port_retries); , m_listen_port_retries, false, reuse_address);
if (s.sock) if (s.sock)
{ {
@ -1420,7 +1422,7 @@ namespace aux {
{ {
s = setup_listener( s = setup_listener(
tcp::endpoint(address_v6::any(), m_listen_interface.port()) tcp::endpoint(address_v6::any(), m_listen_interface.port())
, m_listen_port_retries, true); , m_listen_port_retries, true, reuse_address);
if (s.sock) if (s.sock)
{ {
@ -1450,7 +1452,7 @@ namespace aux {
// binds to the given interface // binds to the given interface
listen_socket_t s = setup_listener( listen_socket_t s = setup_listener(
m_listen_interface, m_listen_port_retries); m_listen_interface, m_listen_port_retries, false, reuse_address);
if (s.sock) if (s.sock)
{ {
@ -3193,7 +3195,7 @@ namespace aux {
bool session_impl::listen_on( bool session_impl::listen_on(
std::pair<int, int> const& port_range std::pair<int, int> const& port_range
, const char* net_interface) , const char* net_interface, int flags)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3223,7 +3225,7 @@ namespace aux {
m_listen_interface = new_interface; m_listen_interface = new_interface;
open_listen_port(); open_listen_port(flags & session::listen_reuse_address);
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
m_logger = create_log("main_session", listen_port(), false); m_logger = create_log("main_session", listen_port(), false);
@ -3430,7 +3432,7 @@ namespace aux {
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_listen_interface.port() != 0) if (m_listen_interface.port() != 0)
open_listen_port(); open_listen_port(false);
if (m_dht) if (m_dht)
{ {