[vlc-devel] [PATCH 1/4] vlc_url: parse '@[bindhost]:[bindport]' in '[serveraddr[:serverport]][@[bindaddr]:[bindport]]'

Jean-Paul Saman jpsaman at videolan.org
Thu Oct 27 15:42:24 CEST 2016


---
 include/vlc_url.h |  2 ++
 src/text/url.c    | 80 ++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/include/vlc_url.h b/include/vlc_url.h
index 5a20c27..802227e 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -149,6 +149,8 @@ struct vlc_url_t
     char *psz_password;
     char *psz_host;
     unsigned i_port;
+    char *psz_bind_host;
+    unsigned i_bind_port;
     char *psz_path;
     char *psz_option;
 
diff --git a/src/text/url.c b/src/text/url.c
index 6116893..566d954 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -407,6 +407,8 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
     url->psz_password = NULL;
     url->psz_host = NULL;
     url->i_port = 0;
+    url->psz_bind_host = NULL;
+    url->i_bind_port = 0;
     url->psz_path = NULL;
     url->psz_option = NULL;
     url->psz_buffer = NULL;
@@ -473,27 +475,78 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
         /*else
             url->psz_path = "/";*/
 
-        /* User name */
-        next = strrchr(cur, '@');
-        if (next != NULL)
+        if (url->psz_protocol && (strcmp(url->psz_protocol, "udp") == 0))
         {
-            *(next++) = '\0';
-            url->psz_username = cur;
-            cur = next;
-
-            /* Password (obsolete) */
-            next = strchr(url->psz_username, ':');
+            /*
+             * Parse udp syntax:
+             * [serveraddr[:serverport]][@[bindaddr]:[bindport]]
+             */
+            next = strchr(cur, '@');
+            if (next != NULL)
+            {
+                *(next++) = '\0';
+                char *psz_bindhost = strdup(next);
+                if (*psz_bindhost == '[' && (next = strchr(psz_bindhost, ']')) != NULL)
+                {
+                    /* Try IPv6 numeral within brackets */
+                    *(next++) = '\0';
+                    url->psz_bind_host = strdup(psz_bindhost + 1);
+
+                    if (*next == ':')
+                        next++;
+                    else
+                        next = NULL;
+                }
+                else
+                {
+                    next = strchr(psz_bindhost, ':');
+                    if (next != NULL)
+                        *(next++) = '\0';
+
+                    url->psz_bind_host = vlc_idna_to_ascii(vlc_uri_decode(psz_bindhost));
+                }
+
+                if (url->psz_bind_host == NULL)
+                    ret = -1;
+                else
+                    if (!vlc_uri_host_validate(url->psz_bind_host))
+                    {
+                        free(url->psz_bind_host);
+                        url->psz_bind_host = NULL;
+                        errno = EINVAL;
+                        ret = -1;
+                    }
+                /* Port number */
+                if (next != NULL)
+                    url->i_bind_port = atoi(next);
+
+                free(psz_bindhost);
+            }
+        }
+        else
+        {
+            /* User name */
+            next = strrchr(cur, '@');
             if (next != NULL)
             {
                 *(next++) = '\0';
-                url->psz_password = next;
-                vlc_uri_decode(url->psz_password);
+                url->psz_username = cur;
+                cur = next;
+
+                /* Password (obsolete) */
+                next = strchr(url->psz_username, ':');
+                if (next != NULL)
+                {
+                    *(next++) = '\0';
+                    url->psz_password = next;
+                    vlc_uri_decode(url->psz_password);
+                }
+                vlc_uri_decode(url->psz_username);
             }
-            vlc_uri_decode(url->psz_username);
         }
 
         /* Host name */
-        if (*cur == '[' && (next = strrchr(cur, ']')) != NULL)
+        if (*cur == '[' && (next = strchr(cur, ']')) != NULL)
         {   /* Try IPv6 numeral within brackets */
             *(next++) = '\0';
             url->psz_host = strdup(cur + 1);
@@ -547,6 +600,7 @@ int vlc_UrlParse(vlc_url_t *restrict url, const char *str)
 
 void vlc_UrlClean (vlc_url_t *restrict url)
 {
+    free (url->psz_bind_host);
     free (url->psz_host);
     free (url->psz_buffer);
 }
-- 
2.7.4



More information about the vlc-devel mailing list