2007-09-10 01:52:34 +02:00
|
|
|
/*
|
|
|
|
|
2016-01-18 00:57:46 +01:00
|
|
|
Copyright (c) 2007-2016, Arvid Norberg
|
2007-09-10 01:52:34 +02:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
|
|
|
|
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
|
|
|
|
|
2008-04-07 05:03:34 +02:00
|
|
|
#include "libtorrent/config.hpp"
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/io_service_fwd.hpp"
|
2007-09-10 01:52:34 +02:00
|
|
|
#include "libtorrent/socket.hpp"
|
2009-11-23 09:38:50 +01:00
|
|
|
#include "libtorrent/address.hpp"
|
2009-09-16 05:46:36 +02:00
|
|
|
#include "libtorrent/error_code.hpp"
|
2015-04-19 00:00:27 +02:00
|
|
|
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
2015-04-19 00:00:27 +02:00
|
|
|
|
2007-09-10 01:52:34 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2009-11-23 09:38:50 +01:00
|
|
|
#include <boost/function/function3.hpp>
|
2007-09-10 01:52:34 +02:00
|
|
|
#include <list>
|
|
|
|
|
2015-04-21 03:16:28 +02:00
|
|
|
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
2015-04-19 00:00:27 +02:00
|
|
|
|
2007-09-10 01:52:34 +02:00
|
|
|
namespace libtorrent
|
|
|
|
{
|
|
|
|
|
2013-07-20 03:02:15 +02:00
|
|
|
TORRENT_EXTRA_EXPORT bool is_local(address const& a);
|
|
|
|
TORRENT_EXTRA_EXPORT bool is_loopback(address const& addr);
|
|
|
|
TORRENT_EXTRA_EXPORT bool is_multicast(address const& addr);
|
|
|
|
TORRENT_EXTRA_EXPORT bool is_any(address const& addr);
|
|
|
|
TORRENT_EXTRA_EXPORT bool is_teredo(address const& addr);
|
2012-03-19 00:31:04 +01:00
|
|
|
TORRENT_EXTRA_EXPORT int cidr_distance(address const& a1, address const& a2);
|
2008-02-28 04:09:34 +01:00
|
|
|
|
2009-04-13 07:11:44 +02:00
|
|
|
// determines if the operating system supports IPv6
|
2013-07-20 03:02:15 +02:00
|
|
|
TORRENT_EXTRA_EXPORT bool supports_ipv6();
|
2009-04-13 07:11:44 +02:00
|
|
|
|
2012-03-19 00:31:04 +01:00
|
|
|
TORRENT_EXTRA_EXPORT int common_bits(unsigned char const* b1
|
2008-02-28 04:09:34 +01:00
|
|
|
, unsigned char const* b2, int n);
|
2007-09-20 18:25:07 +02:00
|
|
|
|
2007-09-10 01:52:34 +02:00
|
|
|
typedef boost::function<void(udp::endpoint const& from
|
|
|
|
, char* buffer, int size)> receive_handler_t;
|
|
|
|
|
2012-03-19 00:31:04 +01:00
|
|
|
class TORRENT_EXTRA_EXPORT broadcast_socket
|
2007-09-10 01:52:34 +02:00
|
|
|
{
|
|
|
|
public:
|
2015-01-06 09:08:49 +01:00
|
|
|
broadcast_socket(udp::endpoint const& multicast_endpoint);
|
2007-09-15 22:20:07 +02:00
|
|
|
~broadcast_socket() { close(); }
|
2007-09-10 01:52:34 +02:00
|
|
|
|
2015-01-06 09:08:49 +01:00
|
|
|
void open(receive_handler_t const& handler, io_service& ios
|
|
|
|
, error_code& ec, bool loopback = true);
|
2012-10-09 06:16:37 +02:00
|
|
|
|
2011-02-17 07:47:26 +01:00
|
|
|
enum flags_t { broadcast = 1 };
|
|
|
|
void send(char const* buffer, int size, error_code& ec, int flags = 0);
|
|
|
|
|
2007-09-10 01:52:34 +02:00
|
|
|
void close();
|
2015-11-19 01:51:17 +01:00
|
|
|
int num_send_sockets() const { return int(m_unicast_sockets.size()); }
|
2010-03-26 18:45:16 +01:00
|
|
|
void enable_ip_broadcast(bool e);
|
2007-09-10 01:52:34 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
struct socket_entry
|
|
|
|
{
|
2015-06-06 19:49:18 +02:00
|
|
|
socket_entry(boost::shared_ptr<udp::socket> const& s)
|
2016-04-30 06:24:45 +02:00
|
|
|
: socket(s), broadcast(false) { memset(buffer, 0, sizeof(buffer)); }
|
2015-06-06 19:49:18 +02:00
|
|
|
socket_entry(boost::shared_ptr<udp::socket> const& s
|
2016-04-30 06:24:45 +02:00
|
|
|
, address_v4 const& mask): socket(s), netmask(mask), broadcast(false)
|
|
|
|
{ memset(buffer, 0, sizeof(buffer)); }
|
2015-06-06 19:49:18 +02:00
|
|
|
boost::shared_ptr<udp::socket> socket;
|
2011-02-17 07:47:26 +01:00
|
|
|
char buffer[1500];
|
2007-09-10 01:52:34 +02:00
|
|
|
udp::endpoint remote;
|
2010-03-26 18:45:16 +01:00
|
|
|
address_v4 netmask;
|
2011-02-17 07:47:26 +01:00
|
|
|
bool broadcast;
|
2007-12-29 06:14:33 +01:00
|
|
|
void close()
|
|
|
|
{
|
2008-01-03 11:58:16 +01:00
|
|
|
if (!socket) return;
|
2008-05-03 18:05:42 +02:00
|
|
|
error_code ec;
|
2007-12-29 06:14:33 +01:00
|
|
|
socket->close(ec);
|
|
|
|
}
|
2011-02-17 07:47:26 +01:00
|
|
|
bool can_broadcast() const
|
|
|
|
{
|
|
|
|
error_code ec;
|
|
|
|
return broadcast
|
|
|
|
&& netmask != address_v4()
|
|
|
|
&& socket->local_endpoint(ec).address().is_v4();
|
|
|
|
}
|
2010-03-26 18:45:16 +01:00
|
|
|
address_v4 broadcast_address() const
|
|
|
|
{
|
|
|
|
error_code ec;
|
2011-11-13 10:25:50 +01:00
|
|
|
#if BOOST_VERSION < 104700
|
|
|
|
return address_v4(socket->local_endpoint(ec).address().to_v4().to_ulong() | ((~netmask.to_ulong()) & 0xffffffff));
|
|
|
|
#else
|
2010-03-26 18:45:16 +01:00
|
|
|
return address_v4::broadcast(socket->local_endpoint(ec).address().to_v4(), netmask);
|
2011-11-13 10:25:50 +01:00
|
|
|
#endif
|
2010-03-26 18:45:16 +01:00
|
|
|
}
|
2007-09-10 01:52:34 +02:00
|
|
|
};
|
|
|
|
|
2008-05-03 18:05:42 +02:00
|
|
|
void on_receive(socket_entry* s, error_code const& ec
|
2007-09-10 01:52:34 +02:00
|
|
|
, std::size_t bytes_transferred);
|
2010-03-26 18:45:16 +01:00
|
|
|
void open_unicast_socket(io_service& ios, address const& addr
|
|
|
|
, address_v4 const& mask);
|
2008-01-09 19:51:54 +01:00
|
|
|
void open_multicast_socket(io_service& ios, address const& addr
|
2009-11-14 21:35:24 +01:00
|
|
|
, bool loopback, error_code& ec);
|
2007-09-10 01:52:34 +02:00
|
|
|
|
2011-10-25 07:55:32 +02:00
|
|
|
// if we're aborting, destruct the handler and return true
|
|
|
|
bool maybe_abort();
|
|
|
|
|
2007-12-22 18:33:04 +01:00
|
|
|
// these sockets are used to
|
|
|
|
// join the multicast group (on each interface)
|
|
|
|
// and receive multicast messages
|
2007-09-10 01:52:34 +02:00
|
|
|
std::list<socket_entry> m_sockets;
|
2007-12-22 18:33:04 +01:00
|
|
|
// these sockets are not bound to any
|
|
|
|
// specific port and are used to
|
|
|
|
// send messages to the multicast group
|
|
|
|
// and receive unicast responses
|
|
|
|
std::list<socket_entry> m_unicast_sockets;
|
2007-09-10 01:52:34 +02:00
|
|
|
udp::endpoint m_multicast_endpoint;
|
|
|
|
receive_handler_t m_on_receive;
|
2011-10-25 07:55:32 +02:00
|
|
|
|
|
|
|
// the number of outstanding async operations
|
|
|
|
// we have on these sockets. The m_on_receive
|
|
|
|
// handler may not be destructed until this reaches
|
|
|
|
// 0, since it may be holding references to
|
|
|
|
// the broadcast_socket itself.
|
|
|
|
int m_outstanding_operations;
|
|
|
|
// when set to true, we're trying to shut down
|
|
|
|
// don't initiate new operations and once the
|
|
|
|
// outstanding counter reaches 0, destruct
|
|
|
|
// the handler object
|
|
|
|
bool m_abort;
|
2007-09-10 01:52:34 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|