Commit f9eaa745 authored by Dan Melnic's avatar Dan Melnic Committed by Facebook Github Bot

Add IP_BIND_ADDRESS_NO_PORT AsyncSocket support. Add the ability to set the...

Add IP_BIND_ADDRESS_NO_PORT AsyncSocket support. Add the ability to set the socket options pre and post bind()

Summary:
Add IP_BIND_ADDRESS_NO_PORT AsyncSocket support. Add the ability to set the socket options pre and post bind()

(Note: this ignores all push blocking failures!)

Reviewed By: danobi

Differential Revision: D19315183

fbshipit-source-id: a8dc330c1f585766a00ba7724dcd9f7a6e64bbfb
parent 3289d2ed
......@@ -528,6 +528,9 @@ void AsyncSocket::connect(
setZeroCopy(zeroCopyVal_);
}
// Apply the additional PRE_BIND options if any.
applyOptions(options, OptionKey::ApplyPos::PRE_BIND);
VLOG(5) << "AsyncSocket::connect(this=" << this << ", evb=" << eventBase_
<< ", fd=" << fd_ << ", host=" << address.describe().c_str();
......@@ -556,17 +559,8 @@ void AsyncSocket::connect(
}
}
// Apply the additional options if any.
for (const auto& opt : options) {
rv = opt.first.apply(fd_, opt.second);
if (rv != 0) {
auto errnoCopy = errno;
throw AsyncSocketException(
AsyncSocketException::INTERNAL_ERROR,
withAddr("failed to set socket option"),
errnoCopy);
}
}
// Apply the additional POST_BIND options if any.
applyOptions(options, OptionKey::ApplyPos::POST_BIND);
// Call preConnect hook if any.
if (connectCallback_) {
......@@ -1602,6 +1596,23 @@ void AsyncSocket::cachePeerAddress() const {
}
}
void AsyncSocket::applyOptions(
const OptionMap& options,
OptionKey::ApplyPos pos) {
for (const auto& opt : options) {
if (opt.first.applyPos_ == pos) {
auto rv = opt.first.apply(fd_, opt.second);
if (rv != 0) {
auto errnoCopy = errno;
throw AsyncSocketException(
AsyncSocketException::INTERNAL_ERROR,
withAddr("failed to set socket option"),
errnoCopy);
}
}
}
}
bool AsyncSocket::isZeroCopyWriteInProgress() const noexcept {
eventBase_->dcheckIsInEventBaseThread();
return (!idZeroCopyBufPtrMap_.empty());
......
......@@ -386,6 +386,7 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
*/
class OptionKey {
public:
enum class ApplyPos { POST_BIND = 0, PRE_BIND = 1 };
bool operator<(const OptionKey& other) const {
if (level == other.level) {
return optname < other.optname;
......@@ -397,6 +398,7 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
}
int level;
int optname;
ApplyPos applyPos_{ApplyPos::POST_BIND};
};
// Maps from a socket option key to its value
......@@ -1253,6 +1255,8 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
void cacheLocalAddress() const;
void cachePeerAddress() const;
void applyOptions(const OptionMap& options, OptionKey::ApplyPos pos);
bool isZeroCopyRequest(WriteFlags flags);
bool isZeroCopyMsg(const cmsghdr& cmsg) const;
......
......@@ -79,6 +79,10 @@ struct mmsghdr {
};
#endif
#ifndef IP_BIND_ADDRESS_NO_PORT
#define IP_BIND_ADDRESS_NO_PORT 24
#endif
#else
#include <WS2tcpip.h> // @manual
......@@ -91,6 +95,7 @@ using sa_family_t = ADDRESS_FAMILY;
#define MSG_ZEROCOPY 0x0
#define SOL_UDP 0x0
#define UDP_SEGMENT 0x0
#define IP_BIND_ADDRESS_NO_PORT 0
// We don't actually support either of these flags
// currently.
......
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