Add IPV6 listen support to svnserve * Makefile.in: Add svncheck6 * subversion/svnserve/main.c (main): Get listen host info first, then use resulting family in the socket creation. Index: Makefile.in =================================================================== --- Makefile.in (revision 13231) +++ Makefile.in (working copy) @@ -381,6 +381,12 @@ svncheck: @$(MAKE) check BASE_URL=svn://localhost +# First, run: +# subversion/svnserve/svnserve --listen-host "::1" -d -r `pwd`/subversion/tests/clients/cmdline + +svncheck6: + @$(MAKE) check BASE_URL=svn://\[::1\] + # First make sure you can ssh to localhost and that "svnserve" is in # the path of the resulting shell. svnsshcheck: Index: subversion/libsvn_ra_svn/client.c =================================================================== --- subversion/libsvn_ra_svn/client.c (revision 13231) +++ subversion/libsvn_ra_svn/client.c (working copy) @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "svn_types.h" @@ -67,22 +68,18 @@ void *edit_baton; } ra_svn_reporter_baton_t; -/* Parse an svn URL's authority section into tunnel, user, host, and - * port components. Return 0 on success, -1 on failure. *tunnel - * and *user may be set to NULL. */ -static int parse_url(const char *url, const char **tunnel, const char **user, - unsigned short *port, const char **hostname, - apr_pool_t *pool) +/* Parse an svn URL's tunnel portion into tunnel, if there is a tunnel + portion. */ + +static void parse_tunnel(const char *url, const char **tunnel, + apr_pool_t *pool) { const char *p; *tunnel = NULL; - *user = NULL; - *port = SVN_RA_SVN_PORT; - *hostname = NULL; if (strncasecmp(url, "svn", 3) != 0) - return -1; + return; url += 3; /* Get the tunnel specification, if any. */ @@ -91,40 +88,11 @@ url++; p = strchr(url, ':'); if (!p) - return -1; + return; *tunnel = apr_pstrmemdup(pool, url, p - url); url = p; } - - if (strncmp(url, "://", 3) != 0) - return -1; - url += 3; - - while (1) - { - p = url + strcspn(url, "@:/"); - if (*p == '@' && !*user) - *user = apr_pstrmemdup(pool, url, p - url); - else if (*p == ':' && !*hostname) - *hostname = apr_pstrmemdup(pool, url, p - url); - else if (*p == '/' || *p == '\0') - { - if (!*hostname) - *hostname = apr_pstrmemdup(pool, url, p - url); - else - *port = atoi(url); - break; - } - else - return -1; - url = p + 1; - } - - /* Decode any escaped characters in the hostname and user. */ - *hostname = svn_path_uri_decode(*hostname, pool); - if (*user) - *user = svn_path_uri_decode(*user, pool); - return 0; + return; } static svn_error_t *make_connection(const char *hostname, unsigned short port, @@ -134,7 +102,7 @@ apr_status_t status; /* Resolve the hostname. */ - status = apr_sockaddr_info_get(&sa, hostname, APR_INET, port, 0, pool); + status = apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, pool); if (status) return svn_error_createf(status, NULL, _("Unknown hostname '%s'"), hostname); @@ -142,9 +110,10 @@ /* Create the socket. */ #ifdef MAX_SECS_TO_LINGER /* ### old APR interface */ - status = apr_socket_create(sock, APR_INET, SOCK_STREAM, pool); + status = apr_socket_create(sock, sa->family, SOCK_STREAM, pool); #else - status = apr_socket_create(sock, APR_INET, SOCK_STREAM, APR_PROTO_TCP, pool); + status = apr_socket_create(sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, + pool); #endif if (status) return svn_error_wrap_apr(status, _("Can't create socket")); @@ -590,10 +559,20 @@ unsigned short port; apr_uint64_t minver, maxver; apr_array_header_t *mechlist, *caplist; - - if (parse_url(url, &tunnel, &user, &port, &hostname, pool) != 0) + apr_uri_t uri; + apr_status_t err; + + err = apr_uri_parse (pool, url, &uri); + + if (err != 0) return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL, _("Illegal svn repository URL '%s'"), url); + + port = uri.port ? uri.port : SVN_RA_SVN_PORT; + hostname = uri.hostname; + user = uri.user; + + parse_tunnel (url, &tunnel, pool); if (tunnel) { Index: subversion/svnserve/main.c =================================================================== --- subversion/svnserve/main.c (revision 13231) +++ subversion/svnserve/main.c (working copy) @@ -392,11 +392,20 @@ exit(0); } + status = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, pool); + if (status) + { + fprintf (stderr, "Can't get address info: %s\n", + apr_strerror(status, errbuf, sizeof(errbuf))); + exit(1); + } + + #ifdef MAX_SECS_TO_LINGER /* ### old APR interface */ - status = apr_socket_create(&sock, APR_INET, SOCK_STREAM, pool); + status = apr_socket_create(&sock, sa->family, SOCK_STREAM, pool); #else - status = apr_socket_create(&sock, APR_INET, SOCK_STREAM, APR_PROTO_TCP, + status = apr_socket_create(&sock, sa->family, SOCK_STREAM, APR_PROTO_TCP, pool); #endif if (status) @@ -410,14 +419,6 @@ * restarted. */ apr_socket_opt_set(sock, APR_SO_REUSEADDR, 1); - status = apr_sockaddr_info_get(&sa, host, APR_INET, port, 0, pool); - if (status) - { - fprintf (stderr, "Can't get address info: %s\n", - apr_strerror(status, errbuf, sizeof(errbuf))); - exit(1); - } - status = apr_socket_bind(sock, sa); if (status) {