]> arthur.barton.de Git - bup.git/commitdiff
bup-web: handle 4 item getsockname() result for IPv6 sockets
authorChristian Brabandt <cb@256bit.org>
Tue, 29 Dec 2020 14:19:48 +0000 (15:19 +0100)
committerRob Browning <rlb@defaultvalue.org>
Thu, 31 Dec 2020 20:35:05 +0000 (14:35 -0600)
So bup-web will create a new network socket to listen on for HTTP
connections and it may use either IPv4 or IPv6 (or both) addresses,
depending on the configuration of the system. This is done using the
tornado.netutil.bind_sockets().

Currently, bup-web does not restrict the address family to either
AF_INET/AF_INET6 and according to the documentation of
[tornado](https://www.tornadoweb.org/en/stable/netutil.html?highlight=netutil#tornado.netutil.bind_sockets)
it will use both address families and listen for connections on IPv4 and
IPv6 addresses.

> Family may be set to either socket.AF_INET or socket.AF_INET6 to
> restrict to IPv4 or IPv6 addresses, otherwise both will be used if
> available.

However, when your system has only IPv6 enabled, the print() statement
may fail with:

Traceback (most recent call last):
  File "/opt/bup/lib/bup/cmd/bup-web", line 310, in <module>
    print('Serving HTTP on %s:%d...' % sockets[0].getsockname())
TypeError: not all arguments converted during string formatting

For systems that have IPv4 as well as IPv6 enabled, it may or may not
fail, depending on whether the first returned socket by getsockname() is
for AF_INET6 or AF_INET4

The reason is, getsockname() for a AF_INET6 connections returns a tuple with
4 items: `(host, port, flowinfo, scope_id)`, while for AF_INET4
addresses, it contains only `(host, port)`.

Since we are only interested in the first 2 items, make sure to return
only the first 2 items, which are `host` and `port` for IPv4 (AF_INET)
and IPv6 (AF_INET6).

Signed-off-by: Christian Brabandt <cb@256bit.org>
Reviewed-by: Rob Browning <rlb@defaultvalue.org>
[rlb@defaultvalue.org: adjust commit summary]

lib/cmd/web-cmd.py

index 6ef2fe9578420418f90d2d078d7f309b69dc84c6..77e5de068c96775255009bd6c3cae095283edb2b 100755 (executable)
@@ -308,7 +308,7 @@ io_loop_pending = IOLoop.instance()
 if isinstance(address, InetAddress):
     sockets = tornado.netutil.bind_sockets(address.port, address.host)
     http_server.add_sockets(sockets)
-    print('Serving HTTP on %s:%d...' % sockets[0].getsockname())
+    print('Serving HTTP on %s:%d...' % sockets[0].getsockname()[0:2])
     if opt.browser:
         browser_addr = 'http://' + address[0] + ':' + str(address[1])
         io_loop_pending.add_callback(lambda : webbrowser.open(browser_addr))