]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Disable PMTU discovery for RADIUS packets (sent them without DF)
authorStefan Winter <stefan.winter@restena.lu>
Sun, 23 Aug 2009 18:21:25 +0000 (21:21 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 23 Aug 2009 18:21:25 +0000 (21:21 +0300)
When Linux has Path MTU discovery enabled, it sets by default the DF bit
on all outgoing datagrams, also UDP ones. If a RADIUS message is bigger
than the smallest MTU size to the target, it will be discarded.

This effectively limits RADIUS messages to ~ 1500 Bytes, while they can
be up to 4k according to RFC2865. In practice, this can mean trouble
when doing EAP-TLS with many RADIUS attributes besides the EAP-Message.
[Bug 326]

src/radius/radius_client.c

index 673e97eb7560acc3c0bfe097515a8dc2b24b5a63..31aa743aadf1c48e31f44743b891880213880224 100644 (file)
@@ -917,6 +917,22 @@ static void radius_retry_primary_timer(void *eloop_ctx, void *timeout_ctx)
 }
 
 
+static int radius_client_disable_pmtu_discovery(int s)
+{
+       int r = -1;
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+       /* Turn off Path MTU discovery on IPv4/UDP sockets. */
+       int action = IP_PMTUDISC_DONT;
+       r = setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &action,
+                      sizeof(action));
+       if (r == -1)
+               wpa_printf(MSG_ERROR, "Failed to set IP_MTU_DISCOVER: "
+                          "%s", strerror(errno));
+#endif
+       return r;
+}
+
+
 static int radius_client_init_auth(struct radius_client_data *radius)
 {
        struct hostapd_radius_servers *conf = radius->conf;
@@ -925,8 +941,10 @@ static int radius_client_init_auth(struct radius_client_data *radius)
        radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
        if (radius->auth_serv_sock < 0)
                perror("socket[PF_INET,SOCK_DGRAM]");
-       else
+       else {
+               radius_client_disable_pmtu_discovery(radius->auth_serv_sock);
                ok++;
+       }
 
 #ifdef CONFIG_IPV6
        radius->auth_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0);
@@ -975,8 +993,10 @@ static int radius_client_init_acct(struct radius_client_data *radius)
        radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
        if (radius->acct_serv_sock < 0)
                perror("socket[PF_INET,SOCK_DGRAM]");
-       else
+       else {
+               radius_client_disable_pmtu_discovery(radius->acct_serv_sock);
                ok++;
+       }
 
 #ifdef CONFIG_IPV6
        radius->acct_serv_sock6 = socket(PF_INET6, SOCK_DGRAM, 0);