Commit 2806dda4 authored by Yang Chi's avatar Yang Chi Committed by Facebook Github Bot

Add an API to AsyncUDPSocket to set DF bit

Summary: Some application requires IP not to fragment the the datagram. Add an API to AsyncUDPSocket to set such option.

Reviewed By: siyengar

Differential Revision: D5421406

fbshipit-source-id: 6cd3ab262f1420e22eb0948e0e2bfef77b7b6e92
parent 2b5eff82
......@@ -132,6 +132,32 @@ void AsyncUDPSocket::bind(const folly::SocketAddress& address) {
}
}
void AsyncUDPSocket::dontFragment(bool df) {
#ifdef IP_MTU_DISCOVER
if (address().getFamily() == AF_INET) {
int v4 = df ? IP_PMTUDISC_DO : IP_PMTUDISC_WANT;
if (fsp::setsockopt(fd_, IPPROTO_IP, IP_MTU_DISCOVER, &v4, sizeof(v4))) {
throw AsyncSocketException(
AsyncSocketException::NOT_OPEN,
"Failed to set DF with IP_MTU_DISCOVER",
errno);
}
}
#endif
#ifdef IPV6_MTU_DISCOVER
if (address().getFamily() == AF_INET6) {
int v6 = df ? IPV6_PMTUDISC_DO : IPV6_PMTUDISC_WANT;
if (fsp::setsockopt(
fd_, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &v6, sizeof(v6))) {
throw AsyncSocketException(
AsyncSocketException::NOT_OPEN,
"Failed to set DF with IPV6_MTU_DISCOVER",
errno);
}
}
#endif
}
void AsyncUDPSocket::setFD(int fd, FDOwnership ownership) {
CHECK_EQ(-1, fd_) << "Already bound to another FD";
......
......@@ -162,6 +162,18 @@ class AsyncUDPSocket : public EventHandler {
return eventBase_;
}
/**
* Enable or disable fragmentation on the socket.
*
* On Linux, this sets IP(V6)_MTU_DISCOVER to IP(V6)_PMTUDISC_DO when enabled,
* and to IP(V6)_PMTUDISC_WANT when disabled. IP(V6)_PMTUDISC_WANT will use
* per-route setting to set DF bit. It may be more desirable to use
* IP(V6)_PMTUDISC_PROBE as opposed to IP(V6)_PMTUDISC_DO for apps that has
* its own PMTU Discovery mechanism.
* Note this doesn't work on Apple.
*/
virtual void dontFragment(bool df);
protected:
virtual ssize_t sendmsg(int socket, const struct msghdr* message, int flags) {
return ::sendmsg(socket, message, flags);
......
......@@ -39,6 +39,7 @@ struct MockAsyncUDPSocket : public AsyncUDPSocket {
MOCK_CONST_METHOD0(getFD, int());
MOCK_METHOD1(setReusePort, void(bool));
MOCK_METHOD1(setReuseAddr, void(bool));
MOCK_METHOD1(dontFragment, void(bool));
};
}}
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