<div dir="ltr"><div dir="ltr">From 12dc89d8bbed8bdd9c768785596e6a60785e9862 Mon Sep 17 00:00:00 2001<br>From: Aaron Boxer <<a href="mailto:aaron.boxer@collabora.com">aaron.boxer@collabora.com</a>><br>Date: Tue, 5 Mar 2019 15:25:31 -0500<br>Subject: [PATCH 2/2] srt: parse SRT parameters from incoming URL<br><br>---<br> modules/access/srt.c | 115 ++++++++++++++++++++++++++++++++++++++++---<br> 1 file changed, 108 insertions(+), 7 deletions(-)<br><br>diff --git a/modules/access/srt.c b/modules/access/srt.c<br>index d8d8cbe659..c36d8a2dc7 100644<br>--- a/modules/access/srt.c<br>+++ b/modules/access/srt.c<br>@@ -37,6 +37,9 @@<br> <br> #include <srt/srt.h><br> <br>+const char* SRT_PARAM_PASSPHRASE     = "passphrase";<br>+const char* SRT_PARAM_LATENCY         = "latency";<br>+<br> /* libsrt defines default packet size as 1316 internally<br>  * so srt module takes same value. */<br> #define SRT_DEFAULT_CHUNK_SIZE 1316<br>@@ -70,6 +73,79 @@ typedef struct<br>     int         i_chunks; /* Number of chunks to allocate in the next read */<br> } stream_sys_t;<br> <br>+<br>+<br>+struct parsed_param {<br>+    char *key;<br>+    char *val;<br>+};<br>+<br>+static inline char *<br>+find(char *str, char find)<br>+{<br>+    str = strchr(str, find);<br>+    return str != NULL ? str + 1 : NULL;<br>+}<br>+<br>+/**<br>+ * Parse a query string into an array of key/value structs.<br>+ *<br>+ * The query string should be a null terminated string of parameters separated by<br>+ * a delimiter. Each parameter are checked for the equal sign character. If it<br>+ * appears in the parameter, it will be used as a null terminator and the part<br>+ * that comes after it will be the value of the parameter.<br>+ *<br>+ *<br>+ * param: query:         the query string to parse. The string will be modified.<br>+ * param: delimiter:      the character that separates the key/value pairs from each other.<br>+ * param: params:       an array of parsed_param structs to hold the result.<br>+ * param: max_params:     maximum number of parameters to parse.<br>+ *<br>+ * Return:                the number of parsed items. -1 if there was an error.<br>+ */<br>+static int<br>+srt_url_parse_query(char *query, const char* delimiter, struct parsed_param *params, int max_params)<br>+{<br>+    int i = 0;<br>+    char *token = NULL;<br>+<br>+    if (!query ||  *query == '\0')<br>+    {<br>+        return -1;<br>+    }<br>+    if (!params || max_params  == 0)<br>+    {<br>+        return 0;<br>+    }<br>+<br>+    token = strtok(query, delimiter);<br>+    while (token != NULL && i < max_params)<br>+    {<br>+        params[i].key = token;<br>+        params[i].val = NULL;<br>+        if ((params[i].val = strchr(params[i].key, '=')) != NULL)<br>+        {<br>+            size_t val_len = strlen(params[i].val);<br>+<br>+            /* make key into a zero-delimited string */<br>+            *(params[i].val) = '\0';<br>+<br>+            /* make sure val is not empty */<br>+            if (val_len > 1)<br>+            {<br>+                params[i].val++;<br>+<br>+                /* make sure key is not empty */<br>+                if (params[i].key[0])<br>+                    i++;<br>+            };<br>+        }<br>+        token = strtok(NULL, delimiter);<br>+    }<br>+    return i;<br>+}<br>+<br>+<br> static void srt_wait_interrupted(void *p_data)<br> {<br>     stream_t *p_stream = p_data;<br>@@ -115,9 +191,10 @@ static int Control(stream_t *p_stream, int i_query, va_list args)<br> <br> static bool srt_schedule_reconnect(stream_t *p_stream)<br> {<br>-    int         i_latency;<br>+    int         i_latency=-1;<br>     int         stat;<br>     char        *psz_passphrase = NULL;<br>+    char        *url = NULL;<br> <br>     struct addrinfo hints = {<br>         .ai_socktype = SOCK_DGRAM,<br>@@ -153,6 +230,29 @@ static bool srt_schedule_reconnect(stream_t *p_stream)<br>         goto out;<br>     }<br> <br>+    /* Parse URL parameters */<br>+    if (p_stream->psz_url)<br>+    {<br>+        char* query = NULL;<br>+        struct parsed_param params[32];<br>+        int num_params = 0;<br>+        int i=0;<br>+        url = strdup((const char*)p_stream->psz_url );<br>+           query = find(url,'?');<br>+        if (query)<br>+        {<br>+            num_params = srt_url_parse_query(query,"&", params, sizeof(params)/sizeof(struct parsed_param) );<br>+            if (num_params > 0) {<br>+                for (i = 0; i < num_params; ++i)<br>+                {<br>+                    if (strcmp(params[i].key, SRT_PARAM_LATENCY) == 0 && params[i].val)<br>+                        i_latency = atoi(params[i].val);<br>+                }<br>+            }<br>+        }<br>+    }<br>+<br>+<br>     /* Make SRT non-blocking */<br>     srt_setsockopt( p_sys->sock, 0, SRTO_SNDSYN,<br>         &(bool) { false }, sizeof( bool ) );<br>@@ -168,11 +268,12 @@ static bool srt_schedule_reconnect(stream_t *p_stream)<br>         &(int) { 0 }, sizeof( int ) );<br> <br>     /* Set latency */<br>-    i_latency = var_InheritInteger( p_stream, "latency" );<br>+    if (i_latency == -1)<br>+        i_latency = var_InheritInteger( p_stream, SRT_PARAM_LATENCY );<br>     srt_setsockopt( p_sys->sock, 0, SRTO_TSBPDDELAY,<br>-        &i_latency, sizeof( int ) );<br>+        &i_latency, sizeof( i_latency ) );<br> <br>-    psz_passphrase = var_InheritString( p_stream, "passphrase" );<br>+       psz_passphrase = var_InheritString( p_stream, SRT_PARAM_PASSPHRASE );<br>     if ( psz_passphrase != NULL && psz_passphrase[0] != '\0')<br>     {<br>         int i_key_length = var_InheritInteger( p_stream, "key-length" );<br>@@ -211,7 +312,7 @@ out:<br>     }<br> <br>     freeaddrinfo( res );<br>-    free( psz_passphrase );<br>+       free(url);<br> <br>     return !failed;<br> }<br>@@ -422,8 +523,8 @@ vlc_module_begin ()<br>             N_("SRT chunk size (bytes)"), NULL, true )<br>     add_integer( "poll-timeout", SRT_DEFAULT_POLL_TIMEOUT,<br>             N_("Return poll wait after timeout milliseconds (-1 = infinite)"), NULL, true )<br>-    add_integer( "latency", SRT_DEFAULT_LATENCY, N_("SRT latency (ms)"), NULL, true )<br>-    add_password("passphrase", "", N_("Password for stream encryption"), NULL)<br>+    add_integer( SRT_PARAM_LATENCY, SRT_DEFAULT_LATENCY, N_("SRT latency (ms)"), NULL, true )<br>+    add_password(SRT_PARAM_PASSPHRASE, "", N_("Password for stream encryption"), NULL)<br>     add_integer( "key-length", SRT_DEFAULT_KEY_LENGTH,<br>             SRT_KEY_LENGTH_TEXT, SRT_KEY_LENGTH_TEXT, false )<br>         change_integer_list( srt_key_lengths, srt_key_length_names )<br>-- <br>2.17.1<br><br></div></div>