diff --git a/synapse/app/_base.py b/synapse/app/_base.py
index 9477737759..0f9a57bd4c 100644
--- a/synapse/app/_base.py
+++ b/synapse/app/_base.py
@@ -25,7 +25,7 @@ except Exception:
from daemonize import Daemonize
from synapse.util import PreserveLoggingContext
from synapse.util.rlimit import change_resource_limit
-from twisted.internet import reactor
+from twisted.internet import error, reactor
def start_worker_reactor(appname, config):
@@ -120,3 +120,58 @@ def quit_with_error(error_string):
sys.stderr.write(" %s\n" % (line.rstrip(),))
sys.stderr.write("*" * line_length + '\n')
sys.exit(1)
+
+
+def listen_tcp(logger, bind_addresses, port, factory, backlog=50):
+ """
+ Create a TCP socket for a port and several addresses
+ """
+ for address in bind_addresses:
+ try:
+ reactor.listenTCP(
+ port,
+ factory,
+ backlog,
+ address
+ )
+ except error.CannotListenError as e:
+ check_bind_error(logger, e, address, bind_addresses)
+
+
+def listen_ssl(logger, bind_addresses, port, factory, context_factory, backlog=50):
+ """
+ Create an SSL socket for a port and several addresses
+ """
+ for address in bind_addresses:
+ try:
+ reactor.listenSSL(
+ port,
+ factory,
+ context_factory,
+ backlog,
+ address
+ )
+ except error.CannotListenError as e:
+ check_bind_error(logger, e, address, bind_addresses)
+
+
+def check_bind_error(logger, e, address, bind_addresses):
+ """
+ This method checks an exception occurred while binding on 0.0.0.0.
+ If :: is specified in the bind addresses a warning is shown.
+ The exception is still raised otherwise.
+
+ Binding on both 0.0.0.0 and :: causes an exception on Linux and macOS
+ because :: binds on both IPv4 and IPv6 (as per RFC 3493).
+ When binding on 0.0.0.0 after :: this can safely be ignored.
+
+ Args:
+ logger (Logger): Logger used to log the warning.
+ e (Exception): Exception that was caught.
+ address (str): Address on which binding was attempted.
+ bind_addresses (list): Addresses on which the service listens.
+ """
+ if address == '0.0.0.0' and '::' in bind_addresses:
+ logger.warn('Failed to listen on 0.0.0.0, continuing because listening on [::]')
+ else:
+ raise e
diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py
index 82a4e18c67..66f206a89d 100755
--- a/synapse/app/homeserver.py
+++ b/synapse/app/homeserver.py
@@ -131,37 +131,31 @@ class SynapseHomeServer(HomeServer):
root_resource = create_resource_tree(resources, root_resource)
if tls:
- for address in bind_addresses:
- try:
- reactor.listenSSL(
- port,
- SynapseSite(
- "synapse.access.https.%s" % (site_tag,),
- site_tag,
- listener_config,
- root_resource,
- ),
- self.tls_server_context_factory,
- interface=address
- )
- except error.CannotListenError as e:
- check_bind_error(e, address, bind_addresses)
+ _base.listen_ssl(
+ logger,
+ bind_addresses,
+ port,
+ SynapseSite(
+ "synapse.access.https.%s" % (site_tag,),
+ site_tag,
+ listener_config,
+ root_resource,
+ ),
+ self.tls_server_context_factory,
+ )
else:
- for address in bind_addresses:
- try:
- reactor.listenTCP(
- port,
- SynapseSite(
- "synapse.access.http.%s" % (site_tag,),
- site_tag,
- listener_config,
- root_resource,
- ),
- interface=address
- )
- except error.CannotListenError as e:
- check_bind_error(e, address, bind_addresses)
+ _base.listen_tcp(
+ logger,
+ bind_addresses,
+ port,
+ SynapseSite(
+ "synapse.access.http.%s" % (site_tag,),
+ site_tag,
+ listener_config,
+ root_resource,
+ )
+ )
logger.info("Synapse now listening on port %d", port)
def _configure_named_resource(self, name, compress=False):
@@ -239,19 +233,16 @@ class SynapseHomeServer(HomeServer):
elif listener["type"] == "manhole":
bind_addresses = listener["bind_addresses"]
- for address in bind_addresses:
- try:
- reactor.listenTCP(
- listener["port"],
- manhole(
- username="matrix",
- password="rabbithole",
- globals={"hs": self},
- ),
- interface=address
- )
- except error.CannotListenError as e:
- check_bind_error(e, address, bind_addresses)
+ _base.listen_tcp(
+ logger,
+ bind_addresses,
+ listener["port"],
+ manhole(
+ username="matrix",
+ password="rabbithole",
+ globals={"hs": self},
+ )
+ )
elif listener["type"] == "replication":
bind_addresses = listener["bind_addresses"]
for address in bind_addresses:
@@ -264,7 +255,7 @@ class SynapseHomeServer(HomeServer):
"before", "shutdown", server_listener.stopListening,
)
except error.CannotListenError as e:
- check_bind_error(e, address, bind_addresses)
+ _base.check_bind_error(logger, e, address, bind_addresses)
else:
logger.warn("Unrecognized listener type: %s", listener["type"])
@@ -298,13 +289,6 @@ class SynapseHomeServer(HomeServer):
return db_conn
-def check_bind_error(e, address, bind_addresses):
- if address == '0.0.0.0' and '::' in bind_addresses:
- logger.warn('Failed to listen on 0.0.0.0, continuing because listening on [::]')
- else:
- raise e
-
-
def setup(config_options):
"""
Args:
|