Commit b0a01afc authored by Dan Melnic's avatar Dan Melnic Committed by Facebook GitHub Bot

Add support for AsyncUDPSocket SO_BINDTODEVICE

Summary: Add support for AsyncUDPSocket SO_BINDTODEVICE

Reviewed By: danobi

Differential Revision: D28100917

fbshipit-source-id: bcc66d943342cbd40b634ef095eccf3e599fcb65
parent 4e7efffd
......@@ -116,7 +116,8 @@ class AsyncUDPServerSocket : private AsyncUDPSocket::ReadCallback,
void bind(
const folly::SocketAddress& addy,
const SocketOptionMap& options = emptySocketOptionMap) {
const SocketOptionMap& options = emptySocketOptionMap,
const std::string& ifName = "") {
CHECK(!socket_);
socket_ = std::make_shared<AsyncUDPSocket>(evb_);
......@@ -126,7 +127,14 @@ class AsyncUDPServerSocket : private AsyncUDPSocket::ReadCallback,
validateSocketOptions(
options, addy.getFamily(), SocketOptionKey::ApplyPos::PRE_BIND),
SocketOptionKey::ApplyPos::PRE_BIND);
#ifdef FOLLY_HAVE_BIND_OPTIONS_IFNAME
AsyncUDPSocket::BindOptions bindOptions;
bindOptions.ifName = ifName;
socket_->bind(addy, bindOptions);
#else
(void)ifName;
socket_->bind(addy);
#endif
socket_->applyOptions(
validateSocketOptions(
options, addy.getFamily(), SocketOptionKey::ApplyPos::POST_BIND),
......
......@@ -207,6 +207,23 @@ void AsyncUDPSocket::bind(
const folly::SocketAddress& address, BindOptions bindOptions) {
init(address.getFamily(), bindOptions);
// bind the socket to the interface
#ifdef FOLLY_HAVE_BIND_OPTIONS_IFNAME
if (!bindOptions.ifName.empty() &&
netops::setsockopt(
fd_,
SOL_SOCKET,
SO_BINDTODEVICE,
bindOptions.ifName.c_str(),
bindOptions.ifName.length())) {
auto errnoCopy = errno;
throw AsyncSocketException(
AsyncSocketException::NOT_OPEN,
"failed to bind to device: " + bindOptions.ifName,
errnoCopy);
}
#endif
// bind to the address
sockaddr_storage addrStorage;
address.getAddress(&addrStorage);
......
......@@ -30,6 +30,10 @@
#include <folly/net/NetOps.h>
#include <folly/net/NetworkSocket.h>
#if defined(__linux__) && !FOLLY_MOBILE
#define FOLLY_HAVE_BIND_OPTIONS_IFNAME
#endif
namespace folly {
/**
......@@ -170,9 +174,12 @@ class AsyncUDPSocket : public EventHandler {
* Contains options to pass to bind.
*/
struct BindOptions {
constexpr BindOptions() noexcept {}
BindOptions() noexcept {}
// Whether IPV6_ONLY should be set on the socket.
bool bindV6Only{true};
#ifdef FOLLY_HAVE_BIND_OPTIONS_IFNAME
std::string ifName;
#endif
};
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment