make sure attempting to bind to an unknown device fails (on MacOS/BSD)

This commit is contained in:
Arvid Norberg 2020-03-31 02:21:32 +02:00 committed by Arvid Norberg
parent 9ac4e6eed8
commit e9a30a34f2
3 changed files with 30 additions and 5 deletions

View File

@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/error_code.hpp"
#if TORRENT_USE_IFCONF || TORRENT_USE_NETLINK || TORRENT_USE_SYSCTL
#include <sys/socket.h> // for SO_BINDTODEVICE
@ -60,13 +61,19 @@ namespace libtorrent { namespace aux {
char const* m_value;
};
template <typename T>
void bind_device(T& sock, char const* device, error_code& ec)
{
sock.set_option(bind_to_device(device), ec);
}
#define TORRENT_HAS_BINDTODEVICE 1
#elif defined IP_BOUND_IF
struct bind_to_device
{
explicit bind_to_device(char const* device): m_value(if_nametoindex(device)) {}
explicit bind_to_device(unsigned int idx): m_value(idx) {}
template<class Protocol>
int level(Protocol const&) const { return IPPROTO_IP; }
template<class Protocol>
@ -79,6 +86,18 @@ namespace libtorrent { namespace aux {
unsigned int m_value;
};
template <typename T>
void bind_device(T& sock, char const* device, error_code& ec)
{
unsigned int const if_idx = if_nametoindex(device);
if (if_idx == 0)
{
ec.assign(errno, system_category());
return;
}
sock.set_option(bind_to_device(if_idx), ec);
}
#define TORRENT_HAS_BINDTODEVICE 1
#elif defined IP_FORCE_OUT_IFP
@ -98,6 +117,12 @@ namespace libtorrent { namespace aux {
char const* m_value;
};
template <typename T>
void bind_device(T& sock, char const* device, error_code& ec)
{
sock.set_option(bind_to_device(device), ec);
}
#define TORRENT_HAS_BINDTODEVICE 1
#else

View File

@ -140,7 +140,7 @@ namespace libtorrent {
#if TORRENT_HAS_BINDTODEVICE
// try to use SO_BINDTODEVICE here, if that exists. If it fails,
// fall back to the mechanism we have below
sock.set_option(aux::bind_to_device(device_name), ec);
aux::bind_device(sock, device_name, ec);
if (ec)
#endif
{

View File

@ -1479,7 +1479,7 @@ namespace {
// we have an actual device we're interested in listening on, if we
// have SO_BINDTODEVICE functionality, use it now.
#if TORRENT_HAS_BINDTODEVICE
ret->sock->set_option(bind_to_device(lep.device.c_str()), ec);
bind_device(*ret->sock, lep.device.c_str(), ec);
#ifndef TORRENT_DISABLE_LOGGING
if (ec && should_log())
{
@ -1488,7 +1488,7 @@ namespace {
}
#endif // TORRENT_DISABLE_LOGGING
ec.clear();
#endif
#endif // TORRENT_HAS_BINDTODEVICE
}
ret->sock->bind(bind_ep, ec);
@ -1621,7 +1621,7 @@ namespace {
#if TORRENT_HAS_BINDTODEVICE
if (!lep.device.empty())
{
ret->udp_sock->sock.set_option(bind_to_device(lep.device.c_str()), ec);
bind_device(ret->udp_sock->sock, lep.device.c_str(), ec);
#ifndef TORRENT_DISABLE_LOGGING
if (ec && should_log())
{