diff --git a/include/libtorrent/aux_/bind_to_device.hpp b/include/libtorrent/aux_/bind_to_device.hpp index e141f460e..949f2d85b 100644 --- a/include/libtorrent/aux_/bind_to_device.hpp +++ b/include/libtorrent/aux_/bind_to_device.hpp @@ -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 // for SO_BINDTODEVICE @@ -60,13 +61,19 @@ namespace libtorrent { namespace aux { char const* m_value; }; + template + 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 int level(Protocol const&) const { return IPPROTO_IP; } template @@ -79,6 +86,18 @@ namespace libtorrent { namespace aux { unsigned int m_value; }; + template + 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 + 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 diff --git a/include/libtorrent/enum_net.hpp b/include/libtorrent/enum_net.hpp index 152063550..9d7023419 100644 --- a/include/libtorrent/enum_net.hpp +++ b/include/libtorrent/enum_net.hpp @@ -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 { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 4beda20f8..8a99847f4 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -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()) {