Browse Source

wpabuf: Get rid of separate ext_data pointer

Use an explicit pointer to the beginning of the buffer and a flag
to indicate whether that is to external data or not. This avoids
a branch whenever accessing the buffer and helps some static
analyzers to understand the wpabuf memory uses better.

Signed-hostap: Jouni Malinen <j@w1.fi>
Jouni Malinen 12 years ago
parent
commit
1871f7116e
2 changed files with 22 additions and 17 deletions
  1. 12 7
      src/utils/wpabuf.c
  2. 10 10
      src/utils/wpabuf.h

+ 12 - 7
src/utils/wpabuf.c

@@ -1,6 +1,6 @@
 /*
  * Dynamic data buffer
- * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -68,12 +68,12 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
 
 	if (buf->used + add_len > buf->size) {
 		unsigned char *nbuf;
-		if (buf->ext_data) {
-			nbuf = os_realloc(buf->ext_data, buf->used + add_len);
+		if (buf->flags & WPABUF_FLAG_EXT_DATA) {
+			nbuf = os_realloc(buf->buf, buf->used + add_len);
 			if (nbuf == NULL)
 				return -1;
 			os_memset(nbuf + buf->used, 0, add_len);
-			buf->ext_data = nbuf;
+			buf->buf = nbuf;
 		} else {
 #ifdef WPA_TRACE
 			nbuf = os_realloc(trace, sizeof(struct wpabuf_trace) +
@@ -95,6 +95,7 @@ int wpabuf_resize(struct wpabuf **_buf, size_t add_len)
 			os_memset(nbuf + sizeof(struct wpabuf) + buf->used, 0,
 				  add_len);
 #endif /* WPA_TRACE */
+			buf->buf = (u8 *) (buf + 1);
 			*_buf = buf;
 		}
 		buf->size = buf->used + add_len;
@@ -126,6 +127,7 @@ struct wpabuf * wpabuf_alloc(size_t len)
 #endif /* WPA_TRACE */
 
 	buf->size = len;
+	buf->buf = (u8 *) (buf + 1);
 	return buf;
 }
 
@@ -148,7 +150,8 @@ struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len)
 
 	buf->size = len;
 	buf->used = len;
-	buf->ext_data = data;
+	buf->buf = data;
+	buf->flags |= WPABUF_FLAG_EXT_DATA;
 
 	return buf;
 }
@@ -189,12 +192,14 @@ void wpabuf_free(struct wpabuf *buf)
 		wpa_trace_show("wpabuf_free magic mismatch");
 		abort();
 	}
-	os_free(buf->ext_data);
+	if (buf->flags & WPABUF_FLAG_EXT_DATA)
+		os_free(buf->buf);
 	os_free(trace);
 #else /* WPA_TRACE */
 	if (buf == NULL)
 		return;
-	os_free(buf->ext_data);
+	if (buf->flags & WPABUF_FLAG_EXT_DATA)
+		os_free(buf->buf);
 	os_free(buf);
 #endif /* WPA_TRACE */
 }

+ 10 - 10
src/utils/wpabuf.h

@@ -1,6 +1,6 @@
 /*
  * Dynamic data buffer
- * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -9,6 +9,9 @@
 #ifndef WPABUF_H
 #define WPABUF_H
 
+/* wpabuf::buf is a pointer to external data */
+#define WPABUF_FLAG_EXT_DATA BIT(0)
+
 /*
  * Internal data structure for wpabuf. Please do not touch this directly from
  * elsewhere. This is only defined in header file to allow inline functions
@@ -17,8 +20,8 @@
 struct wpabuf {
 	size_t size; /* total size of the allocated buffer */
 	size_t used; /* length of data in the buffer */
-	u8 *ext_data; /* pointer to external data; NULL if data follows
-		       * struct wpabuf */
+	u8 *buf; /* pointer to the head of the buffer */
+	unsigned int flags;
 	/* optionally followed by the allocated buffer */
 };
 
@@ -72,9 +75,7 @@ static inline size_t wpabuf_tailroom(const struct wpabuf *buf)
  */
 static inline const void * wpabuf_head(const struct wpabuf *buf)
 {
-	if (buf->ext_data)
-		return buf->ext_data;
-	return buf + 1;
+	return buf->buf;
 }
 
 static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf)
@@ -89,9 +90,7 @@ static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf)
  */
 static inline void * wpabuf_mhead(struct wpabuf *buf)
 {
-	if (buf->ext_data)
-		return buf->ext_data;
-	return buf + 1;
+	return buf->buf;
 }
 
 static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf)
@@ -150,7 +149,8 @@ static inline void wpabuf_put_buf(struct wpabuf *dst,
 
 static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len)
 {
-	buf->ext_data = (u8 *) data;
+	buf->buf = (u8 *) data;
+	buf->flags = WPABUF_FLAG_EXT_DATA;
 	buf->size = buf->used = len;
 }