[vlc-devel] [PATCH 2/3] access: srt: add rendezvous mode

Justin Kim justin.kim at collabora.com
Fri Apr 6 14:12:26 CEST 2018


'Rendezvous' is a kind of a firewall traversal mode
by one-to-one connection[0].

[0] https://github.com/Haivision/srt/blob/master/docs/stransmit.md#medium-srt

Signed-off-by: Justin Kim <justin.kim at collabora.com>
---
 modules/access/srt.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/modules/access/srt.c b/modules/access/srt.c
index 9f971a0572..ca5adc0d91 100644
--- a/modules/access/srt.c
+++ b/modules/access/srt.c
@@ -56,6 +56,27 @@ static const char *const srt_key_length_names[] = {
     N_("16 bytes"), N_("24 bytes"), N_("32 bytes"),
 };
 
+enum {
+    SRT_MODE_CALLER,
+    SRT_MODE_CLIENT = SRT_MODE_CALLER,
+    SRT_MODE_RENDEZVOUS,
+    SRT_MODE_UNKNOWN,
+};
+
+static const int srt_modes[] = {
+    SRT_MODE_CALLER,
+    SRT_MODE_RENDEZVOUS,
+};
+
+#define SRT_MODE_CALLER_STR     "caller"
+#define SRT_MODE_CLIENT_STR     "client"
+#define SRT_MODE_RENDEZVOUS_STR "rendezvous"
+
+static const char *const srt_mode_names[] = {
+    N_(SRT_MODE_CALLER_STR),
+    N_(SRT_MODE_RENDEZVOUS_STR),
+};
+
 struct stream_sys_t
 {
     SRTSOCKET   sock;
@@ -64,8 +85,26 @@ struct stream_sys_t
     bool        b_interrupted;
     char       *psz_host;
     int         i_port;
+    int         i_mode;
 };
 
+static int srt_get_mode_from_name(const char *psz_mode)
+{
+    int i_mode = SRT_MODE_UNKNOWN;
+
+    if ( !strncmp( psz_mode, SRT_MODE_CALLER_STR, strlen( SRT_MODE_CALLER_STR ) )
+      || !strncmp( psz_mode, SRT_MODE_CLIENT_STR, strlen( SRT_MODE_CLIENT_STR ) ) )
+    {
+        i_mode = SRT_MODE_CALLER;
+    }
+    else if ( !strncmp( psz_mode, SRT_MODE_RENDEZVOUS_STR, strlen( SRT_MODE_RENDEZVOUS_STR ) ) )
+    {
+        i_mode = SRT_MODE_RENDEZVOUS;
+    }
+
+    return i_mode;
+}
+
 static void srt_wait_interrupted(void *p_data)
 {
     stream_t *p_stream = p_data;
@@ -168,6 +207,38 @@ static bool srt_schedule_reconnect(stream_t *p_stream)
     srt_setsockopt( p_sys->sock, 0, SRTO_TSBPDDELAY,
         &i_latency, sizeof( int ) );
 
+    if ( p_sys->i_mode == SRT_MODE_RENDEZVOUS )
+    {
+        struct addrinfo *loc;
+        char *psz_bind = var_InheritString( p_stream, "bind-address" );
+        stat = vlc_getaddrinfo( psz_bind, p_sys->i_port, &hints, &loc );
+        if ( stat )
+        {
+            msg_Err( p_stream, "Cannot resolve [%s]:%d (reason: %s)",
+                     psz_bind,
+                     p_sys->i_port,
+                     gai_strerror( stat ) );
+            failed = true;
+            free( psz_bind );
+            goto out;
+        }
+        free( psz_bind );
+
+        srt_setsockopt( p_sys->sock, 0, SRTO_RENDEZVOUS,
+            &(bool) { true }, sizeof( bool ) );
+
+        if ( srt_bind( p_sys->sock, loc->ai_addr, loc->ai_addrlen ) == SRT_ERROR )
+        {
+            msg_Err( p_stream, "Failed to bind for rendezvous mode (reason: %s)",
+                 srt_getlasterror_str() );
+            failed = true;
+            freeaddrinfo( loc );
+            goto out;
+        }
+
+        freeaddrinfo( loc );
+    }
+
     psz_passphrase = var_InheritString( p_stream, "passphrase" );
     if ( psz_passphrase != NULL && psz_passphrase[0] != '\0')
     {
@@ -318,6 +389,37 @@ static int Open(vlc_object_t *p_this)
         goto failed;
     }
 
+    p_sys->i_mode = var_InheritInteger( p_stream, "mode" );
+    if ( parsed_url.psz_option )
+    {
+        char *p_tmp;
+        for ( const char *psz_option = strtok_r( parsed_url.psz_option, "&", &p_tmp );
+              psz_option != NULL;
+              psz_option = strtok_r( NULL, "&", &p_tmp ) )
+        {
+            const char *psz_value;
+
+            if ( !strncmp( psz_option, "mode=", strlen( "mode=" ) ) )
+            {
+                psz_value = psz_option + strlen( "mode=" );
+                int i_mode = srt_get_mode_from_name( psz_value );
+
+                if ( i_mode == SRT_MODE_UNKNOWN )
+                {
+                    msg_Warn( p_stream, "Ignored invalid mode string(%s)", psz_value );
+                    continue;
+                }
+
+                if ( p_sys->i_mode != i_mode )
+                {
+                    msg_Dbg( p_stream, "Use mode value from URL option (%d -> %d)", p_sys->i_mode, i_mode );
+                    var_SetInteger ( p_stream, "mode", i_mode );
+                    p_sys->i_mode = i_mode;
+                }
+            }
+        }
+    }
+
     p_sys->psz_host = strdup( parsed_url.psz_host );
     p_sys->i_port = parsed_url.i_port;
 
@@ -397,6 +499,9 @@ vlc_module_begin ()
     add_integer( "key-length", SRT_DEFAULT_KEY_LENGTH,
             SRT_KEY_LENGTH_TEXT, SRT_KEY_LENGTH_TEXT, false )
         change_integer_list( srt_key_lengths, srt_key_length_names )
+    add_integer( "mode", SRT_MODE_CALLER, N_( "Mode" ), N_( "SRT connection mode (default=caller)" ), false)
+        change_integer_list( srt_modes, srt_mode_names )
+    add_string( "bind-address", "", N_( "Bind Address" ), N_( "Bind address which is used for rendezvous mode)" ), false)
 
     set_capability( "access", 0 )
     add_shortcut( "srt" )
-- 
2.16.3



More information about the vlc-devel mailing list