Skip to content

Commit

Permalink
Merge pull request #7410 from rgacogne/pmtu-dont
Browse files Browse the repository at this point in the history
Ignore Path MTU Discovery on UDP server socket
  • Loading branch information
rgacogne committed Apr 23, 2019
2 parents 39784fa + b707672 commit aecec57
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 1 deletion.
11 changes: 11 additions & 0 deletions pdns/dnsdist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,17 @@ static void setUpLocalBind(std::unique_ptr<ClientState>& cs)
#endif
}

if (!cs->tcp) {
if (cs->local.isIPv4()) {
try {
setSocketIgnorePMTU(cs->udpFD);
}
catch(const std::exception& e) {
warnlog("Failed to set IP_MTU_DISCOVER on UDP server socket for local address '%s': %s", cs->local.toStringWithPort(), e.what());
}
}
}

const std::string& itf = cs->interface;
if (!itf.empty()) {
#ifdef SO_BINDTODEVICE
Expand Down
21 changes: 21 additions & 0 deletions pdns/iputils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,27 @@ int SSetsockopt(int sockfd, int level, int opname, int value)
return ret;
}

void setSocketIgnorePMTU(int sockfd)
{
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
#ifdef IP_PMTUDISC_OMIT
/* Linux 3.15+ has IP_PMTUDISC_OMIT, which discards PMTU information to prevent
poisoning, but still allows fragmentation if the packet size exceeds the
outgoing interface MTU, which is good.
*/
try {
SSetsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_OMIT);
return;
}
catch(const std::exception& e) {
/* failed, let's try IP_PMTUDISC_DONT instead */
}
#endif /* IP_PMTUDISC_OMIT */

/* IP_PMTUDISC_DONT disables Path MTU discovery */
SSetsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT);
#endif /* defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) */
}

bool HarvestTimestamp(struct msghdr* msgh, struct timeval* tv)
{
Expand Down
1 change: 1 addition & 0 deletions pdns/iputils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,7 @@ int SBind(int sockfd, const ComboAddress& local);
int SAccept(int sockfd, ComboAddress& remote);
int SListen(int sockfd, int limit);
int SSetsockopt(int sockfd, int level, int opname, int value);
void setSocketIgnorePMTU(int sockfd);

#if defined(IP_PKTINFO)
#define GEN_IP_PKTINFO IP_PKTINFO
Expand Down
9 changes: 9 additions & 0 deletions pdns/nameserver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ void UDPNameserver::bindIPv4()
if (!setSocketTimestamps(s))
g_log<<Logger::Warning<<"Unable to enable timestamp reporting for socket"<<endl;

if (locala.isIPv4()) {
try {
setSocketIgnorePMTU(s);
}
catch(const std::exception& e) {
g_log<<Logger::Warning<<"Failed to set IP_MTU_DISCOVER on UDP server socket: "<<e.what()<<endl;
}
}

#ifdef SO_REUSEPORT
if( d_can_reuseport )
if( setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) )
Expand Down
12 changes: 11 additions & 1 deletion pdns/pdns_recursor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2565,7 +2565,17 @@ static void makeUDPServerSockets(deferredAdd_t& deferredAdds)
throw PDNSException("SO_REUSEPORT: "+stringerror());
}
#endif
socklen_t socklen=sin.getSocklen();

if (sin.isIPv4()) {
try {
setSocketIgnorePMTU(fd);
}
catch(const std::exception& e) {
g_log<<Logger::Warning<<"Failed to set IP_MTU_DISCOVER on UDP server socket: "<<e.what()<<endl;
}
}

socklen_t socklen=sin.getSocklen();
if (::bind(fd, (struct sockaddr *)&sin, socklen)<0)
throw PDNSException("Resolver binding to server socket on port "+ std::to_string(st.port) +" for "+ st.host+": "+stringerror());

Expand Down

0 comments on commit aecec57

Please sign in to comment.