summaryrefslogtreecommitdiffstats
path: root/src/radius/radius_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radius/radius_server.c')
-rw-r--r--src/radius/radius_server.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index 1bfb93c..4f399bc 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -117,7 +117,8 @@ wpa_hexdump_ascii(MSG_MSGDUMP, "RADIUS SRV: " args)
static void radius_server_session_timeout(void *eloop_ctx, void *timeout_ctx);
-
+static void radius_server_session_remove_timeout(void *eloop_ctx,
+ void *timeout_ctx);
static struct radius_client *
@@ -179,6 +180,7 @@ static void radius_server_session_free(struct radius_server_data *data,
struct radius_session *sess)
{
eloop_cancel_timeout(radius_server_session_timeout, data, sess);
+ eloop_cancel_timeout(radius_server_session_remove_timeout, data, sess);
eap_server_sm_deinit(sess->eap);
if (sess->last_msg) {
radius_msg_free(sess->last_msg);
@@ -194,9 +196,6 @@ static void radius_server_session_free(struct radius_server_data *data,
}
-static void radius_server_session_remove_timeout(void *eloop_ctx,
- void *timeout_ctx);
-
static void radius_server_session_remove(struct radius_server_data *data,
struct radius_session *sess)
{
@@ -493,6 +492,7 @@ static int radius_server_request(struct radius_server_data *data,
unsigned int state;
struct radius_session *sess;
struct radius_msg *reply;
+ int is_complete = 0;
if (force_sess)
sess = force_sess;
@@ -603,6 +603,9 @@ static int radius_server_request(struct radius_server_data *data,
return -1;
}
+ if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
+ is_complete = 1;
+
reply = radius_server_encapsulate_eap(data, client, sess, msg);
if (reply) {
@@ -644,7 +647,7 @@ static int radius_server_request(struct radius_server_data *data,
client->counters.packets_dropped++;
}
- if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) {
+ if (is_complete) {
RADIUS_DEBUG("Removing completed session 0x%x after timeout",
sess->sess_id);
eloop_cancel_timeout(radius_server_session_remove_timeout,
@@ -663,7 +666,13 @@ static void radius_server_receive_auth(int sock, void *eloop_ctx,
{
struct radius_server_data *data = eloop_ctx;
u8 *buf = NULL;
- struct sockaddr_storage from;
+ union {
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+#ifdef CONFIG_IPV6
+ struct sockaddr_in6 sin6;
+#endif /* CONFIG_IPV6 */
+ } from;
socklen_t fromlen;
int len;
struct radius_client *client = NULL;
@@ -678,7 +687,7 @@ static void radius_server_receive_auth(int sock, void *eloop_ctx,
fromlen = sizeof(from);
len = recvfrom(sock, buf, RADIUS_MAX_MSG_LEN, 0,
- (struct sockaddr *) &from, &fromlen);
+ (struct sockaddr *) &from.ss, &fromlen);
if (len < 0) {
perror("recvfrom[radius_server]");
goto fail;
@@ -686,28 +695,26 @@ static void radius_server_receive_auth(int sock, void *eloop_ctx,
#ifdef CONFIG_IPV6
if (data->ipv6) {
- struct sockaddr_in6 *from6 = (struct sockaddr_in6 *) &from;
- if (inet_ntop(AF_INET6, &from6->sin6_addr, abuf, sizeof(abuf))
- == NULL)
+ if (inet_ntop(AF_INET6, &from.sin6.sin6_addr, abuf,
+ sizeof(abuf)) == NULL)
abuf[0] = '\0';
- from_port = ntohs(from6->sin6_port);
+ from_port = ntohs(from.sin6.sin6_port);
RADIUS_DEBUG("Received %d bytes from %s:%d",
len, abuf, from_port);
client = radius_server_get_client(data,
(struct in_addr *)
- &from6->sin6_addr, 1);
+ &from.sin6.sin6_addr, 1);
}
#endif /* CONFIG_IPV6 */
if (!data->ipv6) {
- struct sockaddr_in *from4 = (struct sockaddr_in *) &from;
- os_strlcpy(abuf, inet_ntoa(from4->sin_addr), sizeof(abuf));
- from_port = ntohs(from4->sin_port);
+ os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf));
+ from_port = ntohs(from.sin.sin_port);
RADIUS_DEBUG("Received %d bytes from %s:%d",
len, abuf, from_port);
- client = radius_server_get_client(data, &from4->sin_addr, 0);
+ client = radius_server_get_client(data, &from.sin.sin_addr, 0);
}
RADIUS_DUMP("Received data", buf, len);
@@ -765,6 +772,22 @@ fail:
}
+static int radius_server_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_server_open_socket(int port)
{
int s;
@@ -776,6 +799,8 @@ static int radius_server_open_socket(int port)
return -1;
}
+ radius_server_disable_pmtu_discovery(s);
+
os_memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
OpenPOWER on IntegriCloud