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

Add support for AsyncSocket connect bind to device

Summary:
Add support for AsyncSocket connect bind to device

(Note: this ignores all push blocking failures!)

Reviewed By: danobi

Differential Revision: D27784176

fbshipit-source-id: d7efe3ef59b26aa69552d5f8109f89457ee5fe66
parent fc32eee3
...@@ -721,9 +721,17 @@ void AsyncSSLSocket::connect( ...@@ -721,9 +721,17 @@ void AsyncSSLSocket::connect(
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout, int timeout,
const SocketOptionMap& options, const SocketOptionMap& options,
const folly::SocketAddress& bindAddr) noexcept { const folly::SocketAddress& bindAddr,
const std::string& ifName) noexcept {
auto timeoutChrono = std::chrono::milliseconds(timeout); auto timeoutChrono = std::chrono::milliseconds(timeout);
connect(callback, address, timeoutChrono, timeoutChrono, options, bindAddr); connect(
callback,
address,
timeoutChrono,
timeoutChrono,
options,
bindAddr,
ifName);
} }
void AsyncSSLSocket::connect( void AsyncSSLSocket::connect(
...@@ -732,7 +740,8 @@ void AsyncSSLSocket::connect( ...@@ -732,7 +740,8 @@ void AsyncSSLSocket::connect(
std::chrono::milliseconds connectTimeout, std::chrono::milliseconds connectTimeout,
std::chrono::milliseconds totalConnectTimeout, std::chrono::milliseconds totalConnectTimeout,
const SocketOptionMap& options, const SocketOptionMap& options,
const folly::SocketAddress& bindAddr) noexcept { const folly::SocketAddress& bindAddr,
const std::string& ifName) noexcept {
assert(!server_); assert(!server_);
assert(state_ == StateEnum::UNINIT); assert(state_ == StateEnum::UNINIT);
assert(sslState_ == STATE_UNINIT || sslState_ == STATE_UNENCRYPTED); assert(sslState_ == STATE_UNINIT || sslState_ == STATE_UNENCRYPTED);
...@@ -744,7 +753,12 @@ void AsyncSSLSocket::connect( ...@@ -744,7 +753,12 @@ void AsyncSSLSocket::connect(
callback = allocatedConnectCallback_; callback = allocatedConnectCallback_;
} }
AsyncSocket::connect( AsyncSocket::connect(
callback, address, int(connectTimeout.count()), options, bindAddr); callback,
address,
int(connectTimeout.count()),
options,
bindAddr,
ifName);
} }
void AsyncSSLSocket::cancelConnect() { void AsyncSSLSocket::cancelConnect() {
......
...@@ -432,7 +432,8 @@ class AsyncSSLSocket : public AsyncSocket { ...@@ -432,7 +432,8 @@ class AsyncSSLSocket : public AsyncSocket {
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout = 0, int timeout = 0,
const SocketOptionMap& options = emptySocketOptionMap, const SocketOptionMap& options = emptySocketOptionMap,
const folly::SocketAddress& bindAddr = anyAddress()) noexcept override; const folly::SocketAddress& bindAddr = anyAddress(),
const std::string& ifName = "") noexcept override;
/** /**
* A variant of connect that allows the caller to specify * A variant of connect that allows the caller to specify
...@@ -455,7 +456,8 @@ class AsyncSSLSocket : public AsyncSocket { ...@@ -455,7 +456,8 @@ class AsyncSSLSocket : public AsyncSocket {
std::chrono::milliseconds connectTimeout, std::chrono::milliseconds connectTimeout,
std::chrono::milliseconds totalConnectTimeout, std::chrono::milliseconds totalConnectTimeout,
const SocketOptionMap& options = emptySocketOptionMap, const SocketOptionMap& options = emptySocketOptionMap,
const folly::SocketAddress& bindAddr = anyAddress()) noexcept; const folly::SocketAddress& bindAddr = anyAddress(),
const std::string& ifName = "") noexcept;
using AsyncSocket::connect; using AsyncSocket::connect;
......
...@@ -715,7 +715,8 @@ void AsyncSocket::connect( ...@@ -715,7 +715,8 @@ void AsyncSocket::connect(
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout, int timeout,
const SocketOptionMap& options, const SocketOptionMap& options,
const folly::SocketAddress& bindAddr) noexcept { const folly::SocketAddress& bindAddr,
const std::string& ifName) noexcept {
DestructorGuard dg(this); DestructorGuard dg(this);
eventBase_->dcheckIsInEventBaseThread(); eventBase_->dcheckIsInEventBaseThread();
...@@ -798,6 +799,26 @@ void AsyncSocket::connect( ...@@ -798,6 +799,26 @@ void AsyncSocket::connect(
VLOG(5) << "AsyncSocket::connect(this=" << this << ", evb=" << eventBase_ VLOG(5) << "AsyncSocket::connect(this=" << this << ", evb=" << eventBase_
<< ", fd=" << fd_ << ", host=" << address.describe().c_str(); << ", fd=" << fd_ << ", host=" << address.describe().c_str();
// bind the socket to the interface
#if defined(__linux__)
if (!ifName.empty() &&
netops_->setsockopt(
fd_,
SOL_SOCKET,
SO_BINDTODEVICE,
ifName.c_str(),
ifName.length())) {
auto errnoCopy = errno;
doClose();
throw AsyncSocketException(
AsyncSocketException::NOT_OPEN,
"failed to bind to device: " + ifName,
errnoCopy);
}
#else
(void)ifName;
#endif
// bind the socket // bind the socket
if (bindAddr != anyAddress()) { if (bindAddr != anyAddress()) {
int one = 1; int one = 1;
......
...@@ -491,7 +491,8 @@ class AsyncSocket : public AsyncTransport { ...@@ -491,7 +491,8 @@ class AsyncSocket : public AsyncTransport {
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout = 0, int timeout = 0,
const SocketOptionMap& options = emptySocketOptionMap, const SocketOptionMap& options = emptySocketOptionMap,
const folly::SocketAddress& bindAddr = anyAddress()) noexcept; const folly::SocketAddress& bindAddr = anyAddress(),
const std::string& ifName = "") noexcept;
void connect( void connect(
ConnectCallback* callback, ConnectCallback* callback,
......
...@@ -30,21 +30,23 @@ class MockAsyncSSLSocket : public AsyncSSLSocket { ...@@ -30,21 +30,23 @@ class MockAsyncSSLSocket : public AsyncSSLSocket {
bool deferSecurityNegotiation = false) bool deferSecurityNegotiation = false)
: AsyncSSLSocket(ctx, base, deferSecurityNegotiation) {} : AsyncSSLSocket(ctx, base, deferSecurityNegotiation) {}
MOCK_METHOD5( MOCK_METHOD6(
connect_, connect_,
void( void(
AsyncSocket::ConnectCallback*, AsyncSocket::ConnectCallback*,
const folly::SocketAddress&, const folly::SocketAddress&,
int, int,
const folly::SocketOptionMap&, const folly::SocketOptionMap&,
const folly::SocketAddress&)); const folly::SocketAddress&,
const std::string&));
void connect( void connect(
AsyncSocket::ConnectCallback* callback, AsyncSocket::ConnectCallback* callback,
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout, int timeout,
const folly::SocketOptionMap& options, const folly::SocketOptionMap& options,
const folly::SocketAddress& bindAddr) noexcept override { const folly::SocketAddress& bindAddr,
connect_(callback, address, timeout, options, bindAddr); const std::string& ifName) noexcept override {
connect_(callback, address, timeout, options, bindAddr, ifName);
} }
MOCK_CONST_METHOD1(getLocalAddress, void(folly::SocketAddress*)); MOCK_CONST_METHOD1(getLocalAddress, void(folly::SocketAddress*));
......
...@@ -30,21 +30,23 @@ class MockAsyncSocket : public AsyncSocket { ...@@ -30,21 +30,23 @@ class MockAsyncSocket : public AsyncSocket {
explicit MockAsyncSocket(EventBase* base) : AsyncSocket(base) {} explicit MockAsyncSocket(EventBase* base) : AsyncSocket(base) {}
MOCK_METHOD5( MOCK_METHOD6(
connect_, connect_,
void( void(
AsyncSocket::ConnectCallback*, AsyncSocket::ConnectCallback*,
const folly::SocketAddress&, const folly::SocketAddress&,
int, int,
const folly::SocketOptionMap&, const folly::SocketOptionMap&,
const folly::SocketAddress&)); const folly::SocketAddress&,
const std::string&));
void connect( void connect(
AsyncSocket::ConnectCallback* callback, AsyncSocket::ConnectCallback* callback,
const folly::SocketAddress& address, const folly::SocketAddress& address,
int timeout, int timeout,
const folly::SocketOptionMap& options, const folly::SocketOptionMap& options,
const folly::SocketAddress& bindAddr) noexcept override { const folly::SocketAddress& bindAddr,
connect_(callback, address, timeout, options, bindAddr); const std::string& ifName) noexcept override {
connect_(callback, address, timeout, options, bindAddr, ifName);
} }
MOCK_CONST_METHOD1(getPeerAddress, void(folly::SocketAddress*)); MOCK_CONST_METHOD1(getPeerAddress, void(folly::SocketAddress*));
......
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