Return wpabuf from radius_msg_get_eap()
authorJouni Malinen <j@w1.fi>
Tue, 7 Aug 2012 15:14:42 +0000 (18:14 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 7 Aug 2012 15:14:42 +0000 (18:14 +0300)
This simplifies the implementation by using the buffer type to which the
returned data will be converted anyway. This avoids one memory
allocation for each processed RADIUS message.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/ap/ieee802_1x.c
src/radius/radius.c
src/radius/radius.h
src/radius/radius_server.c
wpa_supplicant/eapol_test.c

index 25b5065..e7009a7 100644 (file)
@@ -1039,9 +1039,8 @@ void ieee802_1x_free_station(struct sta_info *sta)
 static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
                                          struct sta_info *sta)
 {
-       u8 *eap;
-       size_t len;
-       struct eap_hdr *hdr;
+       struct wpabuf *eap;
+       const struct eap_hdr *hdr;
        int eap_type = -1;
        char buf[64];
        struct radius_msg *msg;
@@ -1055,7 +1054,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
 
        msg = sm->last_recv_radius;
 
-       eap = radius_msg_get_eap(msg, &len);
+       eap = radius_msg_get_eap(msg);
        if (eap == NULL) {
                /* RFC 3579, Chap. 2.6.3:
                 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
@@ -1067,19 +1066,19 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
                return;
        }
 
-       if (len < sizeof(*hdr)) {
+       if (wpabuf_len(eap) < sizeof(*hdr)) {
                hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
                               HOSTAPD_LEVEL_WARNING, "too short EAP packet "
                               "received from authentication server");
-               os_free(eap);
+               wpabuf_free(eap);
                sm->eap_if->aaaEapNoReq = TRUE;
                return;
        }
 
-       if (len > sizeof(*hdr))
-               eap_type = eap[sizeof(*hdr)];
+       if (wpabuf_len(eap) > sizeof(*hdr))
+               eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
 
-       hdr = (struct eap_hdr *) eap;
+       hdr = wpabuf_head(eap);
        switch (hdr->code) {
        case EAP_CODE_REQUEST:
                if (eap_type >= 0)
@@ -1114,7 +1113,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
        sm->eap_if->aaaEapReq = TRUE;
 
        wpabuf_free(sm->eap_if->aaaEapReqData);
-       sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len);
+       sm->eap_if->aaaEapReqData = eap;
 }
 
 
index 2b9cbca..ba5f979 100644 (file)
@@ -707,9 +707,9 @@ int radius_msg_add_eap(struct radius_msg *msg, const u8 *data, size_t data_len)
 }
 
 
-u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *eap_len)
+struct wpabuf * radius_msg_get_eap(struct radius_msg *msg)
 {
-       u8 *eap, *pos;
+       struct wpabuf *eap;
        size_t len, i;
        struct radius_attr_hdr *attr;
 
@@ -726,23 +726,18 @@ u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *eap_len)
        if (len == 0)
                return NULL;
 
-       eap = os_malloc(len);
+       eap = wpabuf_alloc(len);
        if (eap == NULL)
                return NULL;
 
-       pos = eap;
        for (i = 0; i < msg->attr_used; i++) {
                attr = radius_get_attr_hdr(msg, i);
                if (attr->type == RADIUS_ATTR_EAP_MESSAGE) {
                        int flen = attr->length - sizeof(*attr);
-                       os_memcpy(pos, attr + 1, flen);
-                       pos += flen;
+                       wpabuf_put_data(eap, attr + 1, flen);
                }
        }
 
-       if (eap_len)
-               *eap_len = len;
-
        return eap;
 }
 
index 2d059df..fcbb275 100644 (file)
@@ -213,7 +213,7 @@ struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
 struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
 int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
                       size_t data_len);
-u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len);
+struct wpabuf * radius_msg_get_eap(struct radius_msg *msg);
 int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
                      size_t secret_len, struct radius_msg *sent_msg,
                      int auth);
index 123c59b..5b2d711 100644 (file)
@@ -689,8 +689,7 @@ static int radius_server_request(struct radius_server_data *data,
                                 const char *from_addr, int from_port,
                                 struct radius_session *force_sess)
 {
-       u8 *eap = NULL;
-       size_t eap_len;
+       struct wpabuf *eap = NULL;
        int res, state_included = 0;
        u8 statebuf[4];
        unsigned int state;
@@ -754,7 +753,7 @@ static int radius_server_request(struct radius_server_data *data,
                return -1;
        }
                      
-       eap = radius_msg_get_eap(msg, &eap_len);
+       eap = radius_msg_get_eap(msg);
        if (eap == NULL) {
                RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
                             from_addr);
@@ -763,7 +762,7 @@ static int radius_server_request(struct radius_server_data *data,
                return -1;
        }
 
-       RADIUS_DUMP("Received EAP data", eap, eap_len);
+       RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap));
 
        /* FIX: if Code is Request, Success, or Failure, send Access-Reject;
         * RFC3579 Sect. 2.6.2.
@@ -773,10 +772,7 @@ static int radius_server_request(struct radius_server_data *data,
         * Or is this already done by the EAP state machine? */
 
        wpabuf_free(sess->eap_if->eapRespData);
-       sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len);
-       if (sess->eap_if->eapRespData == NULL)
-               os_free(eap);
-       eap = NULL;
+       sess->eap_if->eapRespData = eap;
        sess->eap_if->eapResp = TRUE;
        eap_server_sm_step(sess->eap);
 
index 825e2b9..7d63c1b 100644 (file)
@@ -56,9 +56,8 @@ struct eapol_test_data {
        struct radius_client_data *radius;
        struct hostapd_radius_servers *radius_conf;
 
-       u8 *last_eap_radius; /* last received EAP Response from Authentication
-                             * Server */
-       size_t last_eap_radius_len;
+        /* last received EAP Response from Authentication Server */
+       struct wpabuf *last_eap_radius;
 
        u8 authenticator_pmk[PMK_LEN];
        size_t authenticator_pmk_len;
@@ -489,7 +488,7 @@ static void test_eapol_clean(struct eapol_test_data *e,
        struct extra_radius_attr *p, *prev;
 
        radius_client_deinit(e->radius);
-       os_free(e->last_eap_radius);
+       wpabuf_free(e->last_eap_radius);
        radius_msg_free(e->last_recv_radius);
        e->last_recv_radius = NULL;
        os_free(e->eap_identity);
@@ -579,9 +578,8 @@ static char *eap_type_text(u8 type)
 
 static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
 {
-       u8 *eap;
-       size_t len;
-       struct eap_hdr *hdr;
+       struct wpabuf *eap;
+       const struct eap_hdr *hdr;
        int eap_type = -1;
        char buf[64];
        struct radius_msg *msg;
@@ -591,30 +589,29 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
 
        msg = e->last_recv_radius;
 
-       eap = radius_msg_get_eap(msg, &len);
+       eap = radius_msg_get_eap(msg);
        if (eap == NULL) {
                /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
                 * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
                 * attribute */
                wpa_printf(MSG_DEBUG, "could not extract "
                               "EAP-Message from RADIUS message");
-               os_free(e->last_eap_radius);
+               wpabuf_free(e->last_eap_radius);
                e->last_eap_radius = NULL;
-               e->last_eap_radius_len = 0;
                return;
        }
 
-       if (len < sizeof(*hdr)) {
+       if (wpabuf_len(eap) < sizeof(*hdr)) {
                wpa_printf(MSG_DEBUG, "too short EAP packet "
                               "received from authentication server");
-               os_free(eap);
+               wpabuf_free(eap);
                return;
        }
 
-       if (len > sizeof(*hdr))
-               eap_type = eap[sizeof(*hdr)];
+       if (wpabuf_len(eap) > sizeof(*hdr))
+               eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
 
-       hdr = (struct eap_hdr *) eap;
+       hdr = wpabuf_head(eap);
        switch (hdr->code) {
        case EAP_CODE_REQUEST:
                os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
@@ -637,7 +634,7 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
                break;
        default:
                os_strlcpy(buf, "unknown EAP code", sizeof(buf));
-               wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len);
+               wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap);
                break;
        }
        wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
@@ -646,20 +643,21 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
 
        /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */
 
-       os_free(e->last_eap_radius);
+       wpabuf_free(e->last_eap_radius);
        e->last_eap_radius = eap;
-       e->last_eap_radius_len = len;
 
        {
                struct ieee802_1x_hdr *dot1x;
-               dot1x = os_malloc(sizeof(*dot1x) + len);
+               dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap));
                assert(dot1x != NULL);
                dot1x->version = EAPOL_VERSION;
                dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
-               dot1x->length = htons(len);
-               os_memcpy((u8 *) (dot1x + 1), eap, len);
+               dot1x->length = htons(wpabuf_len(eap));
+               os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap),
+                         wpabuf_len(eap));
                eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
-                                 (u8 *) dot1x, sizeof(*dot1x) + len);
+                                 (u8 *) dot1x,
+                                 sizeof(*dot1x) + wpabuf_len(eap));
                os_free(dot1x);
        }
 }