Use IPv6 localhost when family is 'ipv6

This fixes Bug#34193

* src/process.c (Fmake_network_process): Explicitly use ::1 when
using IPv6 with 'local.  Update docstring.

* test/lisp/net/network-stream-tests.el
(make-ipv6-tcp-server-with-unspecified-port):
(make-ipv6-tcp-server-with-specified-port): Test creating ipv6
local server.
(make-server): Add optional family argument, default ipv4
(echo-server-with-local-ipv4): Test connecting to 'local ipv4
(echo-server-with-local-ipv6): Test connecting to 'local ipv6

* doc/lispref/processes.texi (Network Processes): Describe
behavior when using 'local.

* etc/NEWS: Document new 'make-network-process' behavior when
connecting to 'local with ipv6.
This commit is contained in:
Robert Pluim 2019-01-31 14:20:32 +01:00
parent 4633b0ef3f
commit 49f6243027
4 changed files with 79 additions and 5 deletions

View file

@ -2640,7 +2640,9 @@ Specify the host to connect to. @var{host} should be a host name or
Internet address, as a string, or the symbol @code{local} to specify
the local host. If you specify @var{host} for a server, it must
specify a valid address for the local host, and only clients
connecting to that address will be accepted.
connecting to that address will be accepted. When using @code{local},
by default IPv4 will be used, specify a @var{family} of @code{ipv6} to
override this.
@item :service @var{service}
@var{service} specifies a port number to connect to; or, for a server,

View file

@ -324,6 +324,11 @@ write alists of variables to ".dir-locals.el". This is the same
syntax that you can see in the example of a ".dir-locals.el" file in
the node "(emacs) Directory Variables" of the user manual.
+++
** Network connections using 'local can now use IPv6.
'make-network-process' now uses the correct loopback address when
asked to use :host 'local and :family 'ipv6.
* Changes in Specialized Modes and Packages in Emacs 27.1

View file

@ -3733,6 +3733,8 @@ also nil, meaning that this process is not associated with any buffer.
address. The symbol `local' specifies the local host. If specified
for a server process, it must be a valid name or address for the local
host, and only clients connecting to that address will be accepted.
`local' will use IPv4 by default, use a FAMILY of 'ipv6 to override
this.
:service SERVICE -- SERVICE is name of the service desired, or an
integer specifying a port number to connect to. If SERVICE is t,
@ -3983,14 +3985,24 @@ usage: (make-network-process &rest ARGS) */)
#ifdef HAVE_LOCAL_SOCKETS
if (family != AF_LOCAL)
#endif
host = build_string ("127.0.0.1");
{
if (family == AF_INET6)
host = build_string ("::1");
else
host = build_string ("127.0.0.1");
}
}
else
{
if (EQ (host, Qlocal))
{
/* Depending on setup, "localhost" may map to different IPv4 and/or
IPv6 addresses, so it's better to be explicit (Bug#6781). */
host = build_string ("127.0.0.1");
if (family == AF_INET6)
host = build_string ("::1");
else
host = build_string ("127.0.0.1");
}
CHECK_STRING (host);
}

View file

@ -71,12 +71,39 @@
(= (aref (process-contact server :local) 4) 57869)))
(delete-process server)))
(defun make-server (host)
(ert-deftest make-ipv6-tcp-server-with-unspecified-port ()
(let ((server
(make-network-process
:name "server"
:server t
:noquery t
:family 'ipv6
:service t
:host 'local)))
(should (and (arrayp (process-contact server :local))
(numberp (aref (process-contact server :local) 8))
(> (aref (process-contact server :local) 8) 0)))
(delete-process server)))
(ert-deftest make-ipv6-tcp-server-with-specified-port ()
(let ((server
(make-network-process
:name "server"
:server t
:noquery t
:family 'ipv6
:service 57870
:host 'local)))
(should (and (arrayp (process-contact server :local))
(= (aref (process-contact server :local) 8) 57870)))
(delete-process server)))
(defun make-server (host &optional family)
(make-network-process
:name "server"
:server t
:noquery t
:family 'ipv4
:family (or family 'ipv4)
:coding 'raw-text-unix
:buffer (get-buffer-create "*server*")
:service t
@ -129,6 +156,34 @@
(should (equal (buffer-string) "foo\n")))
(delete-process server)))
(ert-deftest echo-server-with-local-ipv4 ()
(let* ((server (make-server 'local 'ipv4))
(port (aref (process-contact server :local) 4))
(proc (make-network-process :name "foo"
:buffer (generate-new-buffer "*foo*")
:host 'local
:family 'ipv4
:service port)))
(with-current-buffer (process-buffer proc)
(process-send-string proc "echo foo")
(sleep-for 0.1)
(should (equal (buffer-string) "foo\n")))
(delete-process server)))
(ert-deftest echo-server-with-local-ipv6 ()
(let* ((server (make-server 'local 'ipv6))
(port (aref (process-contact server :local) 8))
(proc (make-network-process :name "foo"
:buffer (generate-new-buffer "*foo*")
:host 'local
:family 'ipv6
:service port)))
(with-current-buffer (process-buffer proc)
(process-send-string proc "echo foo")
(sleep-for 0.1)
(should (equal (buffer-string) "foo\n")))
(delete-process server)))
(ert-deftest echo-server-with-ip ()
(let* ((server (make-server 'local))
(port (aref (process-contact server :local) 4))