mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
Store the SNI host name with its object
TLSX_SNI_New() allocated the object and then the host name it points at, so every server name costs two allocations and two frees. Put the name in a flexible array at the end of the object instead. A union cannot hold one, so the single member data union goes and the name is sni->host_name. The host name is the only SNI type there is, so the switch that picked the allocation to make becomes an early return for any other type, which is what the default case did anyway.
This commit is contained in:
committed by
Tobias Frauenschläger
parent
b56c027267
commit
0a23c155de
56
src/tls.c
56
src/tls.c
@@ -2277,37 +2277,27 @@ int TLSX_ALPN_GetRequest(TLSX* extensions, void** data, word16 *dataSz)
|
||||
/** Creates a new SNI object. */
|
||||
static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
|
||||
{
|
||||
SNI* sni = (SNI*)XMALLOC(sizeof(SNI), heap, DYNAMIC_TYPE_TLSX);
|
||||
SNI* sni;
|
||||
|
||||
(void)heap;
|
||||
|
||||
if (sni) {
|
||||
sni->type = type;
|
||||
sni->next = NULL;
|
||||
if (type != WOLFSSL_SNI_HOST_NAME) /* invalid type */
|
||||
return NULL;
|
||||
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
sni->options = 0;
|
||||
sni->status = WOLFSSL_SNI_NO_MATCH;
|
||||
#endif
|
||||
sni = (SNI*)XMALLOC(sizeof(SNI) + size + 1, heap, DYNAMIC_TYPE_TLSX);
|
||||
if (sni == NULL)
|
||||
return NULL;
|
||||
|
||||
switch (sni->type) {
|
||||
case WOLFSSL_SNI_HOST_NAME:
|
||||
sni->data.host_name = (char*)XMALLOC(size + 1, heap,
|
||||
DYNAMIC_TYPE_TLSX);
|
||||
if (sni->data.host_name) {
|
||||
XSTRNCPY(sni->data.host_name, (const char*)data, size);
|
||||
sni->data.host_name[size] = '\0';
|
||||
} else {
|
||||
XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
|
||||
sni = NULL;
|
||||
}
|
||||
break;
|
||||
sni->type = type;
|
||||
sni->next = NULL;
|
||||
|
||||
default: /* invalid type */
|
||||
XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
|
||||
sni = NULL;
|
||||
}
|
||||
}
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
sni->options = 0;
|
||||
sni->status = WOLFSSL_SNI_NO_MATCH;
|
||||
#endif
|
||||
|
||||
XSTRNCPY(sni->host_name, (const char*)data, size);
|
||||
sni->host_name[size] = '\0';
|
||||
|
||||
return sni;
|
||||
}
|
||||
@@ -2316,12 +2306,6 @@ static SNI* TLSX_SNI_New(byte type, const void* data, word16 size, void* heap)
|
||||
static void TLSX_SNI_Free(SNI* sni, void* heap)
|
||||
{
|
||||
if (sni) {
|
||||
switch (sni->type) {
|
||||
case WOLFSSL_SNI_HOST_NAME:
|
||||
XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
|
||||
break;
|
||||
}
|
||||
|
||||
XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
|
||||
}
|
||||
(void)heap;
|
||||
@@ -2351,7 +2335,7 @@ WOLFSSL_TEST_VIS word16 TLSX_SNI_GetSize(SNI* list)
|
||||
|
||||
switch (sni->type) {
|
||||
case WOLFSSL_SNI_HOST_NAME:
|
||||
length += (word32)XSTRLEN((char*)sni->data.host_name);
|
||||
length += (word32)XSTRLEN((char*)sni->host_name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2377,12 +2361,12 @@ static word16 TLSX_SNI_Write(SNI* list, byte* output)
|
||||
|
||||
switch (sni->type) {
|
||||
case WOLFSSL_SNI_HOST_NAME:
|
||||
length = (word16)XSTRLEN((char*)sni->data.host_name);
|
||||
length = (word16)XSTRLEN((char*)sni->host_name);
|
||||
|
||||
c16toa(length, output + offset); /* sni length */
|
||||
offset += OPAQUE16_LEN;
|
||||
|
||||
XMEMCPY(output + offset, sni->data.host_name, length);
|
||||
XMEMCPY(output + offset, sni->host_name, length);
|
||||
|
||||
offset += length;
|
||||
break;
|
||||
@@ -2579,7 +2563,7 @@ static int TLSX_SNI_Parse(WOLFSSL* ssl, const byte* input, word16 length,
|
||||
#endif
|
||||
{
|
||||
const char* hostName;
|
||||
hostName = (sni != NULL) ? sni->data.host_name : NULL;
|
||||
hostName = (sni != NULL) ? sni->host_name : NULL;
|
||||
matched = cacheOnly || (hostName != NULL &&
|
||||
XSTRLEN(hostName) == size &&
|
||||
XSTRNCMP(hostName, (const char*)input + offset, size) == 0);
|
||||
@@ -2756,7 +2740,7 @@ word16 TLSX_SNI_GetRequest(TLSX* extensions, byte type, void** data,
|
||||
switch (sni->type) {
|
||||
case WOLFSSL_SNI_HOST_NAME:
|
||||
if (data) {
|
||||
*data = sni->data.host_name;
|
||||
*data = sni->host_name;
|
||||
return (word16)XSTRLEN((char*)*data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2371,17 +2371,12 @@ int test_TLSX_SNI_GetSize_overflow(void)
|
||||
|
||||
/* Append many SNI nodes to force overflow in the size calculation */
|
||||
for (i = 1; EXPECT_SUCCESS() && i < num_sni; i++) {
|
||||
sni = (SNI*)XMALLOC(sizeof(SNI), NULL, DYNAMIC_TYPE_TLSX);
|
||||
sni = (SNI*)XMALLOC(sizeof(SNI) + 2, NULL, DYNAMIC_TYPE_TLSX);
|
||||
ExpectNotNull(sni);
|
||||
if (sni != NULL) {
|
||||
XMEMSET(sni, 0, sizeof(SNI));
|
||||
XMEMSET(sni, 0, sizeof(SNI) + 2);
|
||||
sni->type = WOLFSSL_SNI_HOST_NAME;
|
||||
sni->data.host_name = (char*)XMALLOC(2, NULL, DYNAMIC_TYPE_TLSX);
|
||||
ExpectNotNull(sni->data.host_name);
|
||||
if (sni->data.host_name != NULL) {
|
||||
sni->data.host_name[0] = 'a';
|
||||
sni->data.host_name[1] = '\0';
|
||||
}
|
||||
sni->host_name[0] = 'a';
|
||||
sni->next = head->next;
|
||||
head->next = sni;
|
||||
}
|
||||
|
||||
@@ -44,9 +44,8 @@
|
||||
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) && \
|
||||
defined(HAVE_TLS_EXTENSIONS)
|
||||
|
||||
/* TLSX_SNI_Free() is file-static in src/tls.c. A test that detaches an SNI
|
||||
* list from its extension has to release it the same way: the host name, then
|
||||
* the node. */
|
||||
/* TLSX_SNI_Free() is file-static in src/tls.c. Each SNI node is one
|
||||
* allocation that also holds the host name. */
|
||||
#ifdef HAVE_SNI
|
||||
TEST_TLS_MSGTYPE_UNUSED
|
||||
static void test_tls_msgtype_free_sni(void* p, void* heap)
|
||||
@@ -56,8 +55,6 @@ static void test_tls_msgtype_free_sni(void* p, void* heap)
|
||||
while (sni != NULL) {
|
||||
SNI* next = sni->next;
|
||||
|
||||
if (sni->type == WOLFSSL_SNI_HOST_NAME)
|
||||
XFREE(sni->data.host_name, heap, DYNAMIC_TYPE_TLSX);
|
||||
XFREE(sni, heap, DYNAMIC_TYPE_TLSX);
|
||||
sni = next;
|
||||
}
|
||||
|
||||
@@ -3678,12 +3678,17 @@ WOLFSSL_LOCAL int TLSX_Append(TLSX** list, TLSX_Type type,
|
||||
|
||||
typedef struct SNI {
|
||||
byte type; /* SNI Type */
|
||||
union { char* host_name; } data; /* SNI Data */
|
||||
struct SNI* next; /* List Behavior */
|
||||
byte status; /* Matching result */
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
byte options; /* Behavior options */
|
||||
#endif
|
||||
/* Ignore "nonstandard extension used : zero-sized array in struct/union"
|
||||
* MSVC warning */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4200)
|
||||
#endif
|
||||
char host_name[WC_FLEXIBLE_ARRAY_SIZE]; /* SNI Data */
|
||||
} SNI;
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseSNI(TLSX** extensions, byte type, const void* data,
|
||||
|
||||
Reference in New Issue
Block a user