Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stream_index #674

Merged
merged 16 commits into from
Jan 12, 2024
17 changes: 17 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_debug_logging
enable_steam_index
enable_openssl
enable_nss
with_openssl_dir
Expand Down Expand Up @@ -5326,6 +5327,22 @@ fi
$as_echo "$enable_debug_logging" >&6; }


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable stream index" >&5
$as_echo_n "checking whether to enable stream index... " >&6; }
# Check whether --enable-stream-index was given.
if test "${enable-stream-index+set}" = set; then :
enableval=$enable_stream_index;
else
enable_stream_index=no
fi

if test "$enable_stream_index" = "yes"; then

$as_echo "#define ENABLE_STREAM_INDEX 1" >>confdefs.h

fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_steam_index" >&5
$as_echo "$enable_steam_index" >&6; }



Expand Down
4 changes: 4 additions & 0 deletions include/srtp_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ typedef struct srtp_stream_ctx_t_ srtp_stream_ctx_t;
typedef srtp_stream_ctx_t *srtp_stream_t;
typedef struct srtp_stream_list_ctx_t_ *srtp_stream_list_t;

#ifdef ENABLE_STREAM_INDEX
typedef struct srtp_stream_index_ *srtp_stream_index;
#endif

/*
* the following declarations are libSRTP internal functions
*/
Expand Down
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ if get_option('debug-logging')
cdata.set('ENABLE_DEBUG_LOGGING', true)
endif

if get_option('stream-index')
cdata.set('ENABLE_STREAM_INDEX', true)
endif

use_openssl = false
use_nss = false
use_mbedtls = false
Expand Down
2 changes: 2 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ option('crypto-library', type: 'combo', choices : ['none', 'openssl', 'nss', 'mb
description : 'What external crypto library to leverage, if any (OpenSSL, NSS, or mbedtls)')
option('crypto-library-kdf', type : 'feature', value : 'auto',
description : 'Use the external crypto library for Key Derivation Function support')
option('stream-index', type : 'boolean', value : 'false',
description : 'Enable stream index for fast stream retrieval')
option('fuzzer', type : 'feature', value : 'disabled',
description : 'Build libsrtp2 fuzzer (requires build with clang)')
option('tests', type : 'feature', value : 'auto', yield : true,
Expand Down
144 changes: 144 additions & 0 deletions srtp/srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4841,8 +4841,125 @@ srtp_err_status_t srtp_get_stream_roc(srtp_t session,

#ifndef SRTP_NO_STREAM_LIST

#ifdef ENABLE_STREAM_INDEX

#define INITIAL_STREAM_INDEX_SIZE 2

typedef struct stream_index_entry {
uint32_t ssrc;
srtp_stream_t stream;
} stream_index_entry;

typedef struct srtp_stream_index_ {
stream_index_entry *entries;
size_t size;
size_t available;
} srtp_stream_index_;

srtp_err_status_t srtp_stream_index_alloc(srtp_stream_index *stream_index_ptr)
{
srtp_stream_index stream_index =
srtp_crypto_alloc(sizeof(srtp_stream_index_));
if (stream_index == NULL) {
return srtp_err_status_alloc_fail;
}

stream_index->entries = srtp_crypto_alloc(sizeof(stream_index_entry) *
INITIAL_STREAM_INDEX_SIZE);
if (stream_index->entries == NULL) {
return srtp_err_status_alloc_fail;
jmillan marked this conversation as resolved.
Show resolved Hide resolved
}

*stream_index_ptr = stream_index;

return srtp_err_status_ok;
}

srtp_err_status_t srtp_stream_index_dealloc(srtp_stream_index stream_index)
{
srtp_crypto_free(stream_index->entries);
srtp_crypto_free(stream_index);

return srtp_err_status_ok;
}

srtp_err_status_t srtp_stream_index_insert(srtp_stream_index stream_index,
srtp_stream_t stream)
{
// there is no available index entry, duplicate number of entries
if (stream_index->available == 0) {
size_t new_size = stream_index->size * 2;
stream_index_entry *new_entries =
srtp_crypto_alloc(sizeof(stream_index_entry) * new_size);
if (new_entries == NULL) {
return srtp_err_status_alloc_fail;
}

// copy previous entries into the new ones
memcpy(new_entries, stream_index->entries,
sizeof(stream_index_entry) * stream_index->size);
// release previous entries
srtp_crypto_free(stream_index->entries);
// assign new entries to the index
stream_index->entries = new_entries;
// update index info
stream_index->size = new_size;
stream_index->available = new_size / 2;
}

// fill the first available entry
size_t next_index = stream_index->size - stream_index->available;
stream_index->entries[next_index].ssrc = stream->ssrc;
stream_index->entries[next_index].stream = stream;

// update available value
stream_index->available--;

return srtp_err_status_ok;
}

void srtp_stream_index_remove(srtp_stream_index stream_index, uint32_t ssrc)
{
unsigned int i = 0;
jmillan marked this conversation as resolved.
Show resolved Hide resolved
unsigned int end = stream_index->size - stream_index->available;

for (; i < end; i++) {
if (stream_index->entries[i].ssrc == ssrc) {
size_t entries_to_move =
stream_index->size - stream_index->available - i - 1;
memmove(&stream_index->entries[i], &stream_index->entries[i + 1],
entries_to_move * sizeof(stream_index_entry));
stream_index->available++;

break;
}
}
}

srtp_stream_t srtp_stream_index_get(srtp_stream_index stream_index,
uint32_t ssrc)
{
unsigned int i = 0;
jmillan marked this conversation as resolved.
Show resolved Hide resolved
unsigned int end = stream_index->size - stream_index->available;

stream_index_entry *entries = stream_index->entries;

for (; i < end; i++) {
if (entries[i].ssrc == ssrc) {
return entries[i].stream;
}
}

return NULL;
}

#endif

/* in the default implementation, we have an intrusive doubly-linked list */
typedef struct srtp_stream_list_ctx_t_ {
#ifdef ENABLE_STREAM_INDEX
srtp_stream_index index;
#endif
/* a stub stream that just holds pointers to the beginning and end of the
* list */
srtp_stream_ctx_t data;
Expand All @@ -4856,6 +4973,16 @@ srtp_err_status_t srtp_stream_list_alloc(srtp_stream_list_t *list_ptr)
return srtp_err_status_alloc_fail;
}

#ifdef ENABLE_STREAM_INDEX
srtp_err_status_t stat = srtp_stream_index_alloc(&list->index);
if (stat) {
return stat;
}

list->index->size = INITIAL_STREAM_INDEX_SIZE;
list->index->available = INITIAL_STREAM_INDEX_SIZE;
#endif

list->data.next = NULL;
list->data.prev = NULL;

Expand All @@ -4869,6 +4996,9 @@ srtp_err_status_t srtp_stream_list_dealloc(srtp_stream_list_t list)
if (list->data.next) {
return srtp_err_status_fail;
}
#ifdef ENABLE_STREAM_INDEX
srtp_stream_index_dealloc(list->index);
#endif
srtp_crypto_free(list);
return srtp_err_status_ok;
}
Expand All @@ -4884,11 +5014,21 @@ srtp_err_status_t srtp_stream_list_insert(srtp_stream_list_t list,
list->data.next = stream;
stream->prev = &(list->data);

#ifdef ENABLE_STREAM_INDEX
srtp_err_status_t stat = srtp_stream_index_insert(list->index, stream);
if (stat) {
return stat;
}
#endif

return srtp_err_status_ok;
}

srtp_stream_t srtp_stream_list_get(srtp_stream_list_t list, uint32_t ssrc)
{
#ifdef ENABLE_STREAM_INDEX
return srtp_stream_index_get(list->index, ssrc);
#else
/* walk down list until ssrc is found */
srtp_stream_t stream = list->data.next;
while (stream != NULL) {
Expand All @@ -4900,6 +5040,7 @@ srtp_stream_t srtp_stream_list_get(srtp_stream_list_t list, uint32_t ssrc)

/* we haven't found our ssrc, so return a null */
return NULL;
#endif
}

void srtp_stream_list_remove(srtp_stream_list_t list,
Expand All @@ -4911,6 +5052,9 @@ void srtp_stream_list_remove(srtp_stream_list_t list,
if (stream_to_remove->next != NULL) {
stream_to_remove->next->prev = stream_to_remove->prev;
}
#ifdef ENABLE_STREAM_INDEX
srtp_stream_index_remove(list->index, stream_to_remove->ssrc);
#endif
}

void srtp_stream_list_for_each(srtp_stream_list_t list,
Expand Down
Loading