Skip to content

Commit

Permalink
Added Stefan's UDP fragmentation fix
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@510 e88ac4ed-0b26-0410-9574-a7f39faa03bf
  • Loading branch information
kolla authored and kolla committed Sep 11, 2009
1 parent 0e93182 commit e99882a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
3 changes: 3 additions & 0 deletions radsecproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,9 @@ void createlistener(uint8_t type, char *arg) {
continue;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

disable_DF_bit(s, res);

#ifdef IPV6_V6ONLY
if (res->ai_family == AF_INET6)
setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
Expand Down
25 changes: 25 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,28 @@ int connectport(int type, char *host, char *port) {
}
#endif

/* Disable the "Don't Fragment" bit for UDP sockets. It is set by default, which may cause an "oversized"
RADIUS packet to be discarded on first attempt (due to Path MTU discovery).
*/

void disable_DF_bit(int socket, struct addrinfo *res) {
if ((res->ai_family == AF_INET) && (res->ai_socktype == SOCK_DGRAM)) {
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
/*
* Turn off Path MTU discovery on IPv4/UDP sockets, Linux variant.
*/
int r, action;
debug(DBG_INFO, "disable_DF_bit: disabling DF bit (Linux variant)");
action = IP_PMTUDISC_DONT;
r = setsockopt(socket, IPPROTO_IP, IP_MTU_DISCOVER, &action, sizeof(action));
if (r == -1)
debug(DBG_WARN, "Failed to set IP_MTU_DISCOVER");
#else
debug(DBG_INFO, "Non-Linux platform, unable to unset DF bit for UDP. You should check with tcpdump whether radsecproxy will send its UDP packets with DF bit set!");
#endif
}
}

int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
int s, on = 1;
struct addrinfo *res;
Expand All @@ -149,6 +171,9 @@ int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
debug(DBG_WARN, "bindtoaddr: socket failed");
continue;
}

disable_DF_bit(s,res);

if (reuse)
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
#ifdef IPV6_V6ONLY
Expand Down
1 change: 1 addition & 0 deletions util.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct sockaddr *addr_copy(struct sockaddr *in);
void port_set(struct sockaddr *sa, uint16_t port);

void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len);
void disable_DF_bit(int socket, struct addrinfo *res);
int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);
int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout);

0 comments on commit e99882a

Please sign in to comment.