diff --git a/docs/ENVIRONMENT.rst b/docs/ENVIRONMENT.rst index b7f3612..f6d5517 100644 --- a/docs/ENVIRONMENT.rst +++ b/docs/ENVIRONMENT.rst @@ -215,6 +215,7 @@ raise them. functioning Electrum clients by default will send pings roughly every 60 seconds. + Peer Discovery -------------- @@ -264,59 +265,69 @@ some of this. 9150 (Tor browser bundle) and 1080 (socks). -IRC ---- +Server Advertising +------------------ -Use the following environment variables if you want to advertise -connectivity on IRC: - -* **IRC** - - Set to anything non-empty to advertise on IRC - -* **IRC_NICK** - - The nick to use when connecting to IRC. The default is a hash of - **REPORT_HOST**. Either way a prefix will be prepended depending on - **COIN** and **NET**. +These environment variables affect how your server is advertised, both +by peer discovery (if enabled) and IRC (if enabled). * **REPORT_HOST** - The host to advertise. Defaults to **HOST**. + The clearnet host to advertise. If not set, no clearnet host is + advertised. * **REPORT_TCP_PORT** - The TCP port to advertise. Defaults to **TCP_PORT**. '0' disables - publishing the port. + The clearnet TCP port to advertise if **REPORT_HOST** is set. + Defaults to **TCP_PORT**. '0' disables publishing a TCP port. * **REPORT_SSL_PORT** - The SSL port to advertise. Defaults to **SSL_PORT**. '0' disables - publishing the port. + The clearnet SSL port to advertise if **REPORT_HOST** is set. + Defaults to **SSL_PORT**. '0' disables publishing an SSL port. * **REPORT_HOST_TOR** - The tor address to advertise; must end with `.onion`. If set, an - additional connection to IRC happens with '_tor' appended to - **IRC_NICK**. + If you wish run a Tor service, this is the Tor host name to + advertise and must end with `.onion`. * **REPORT_TCP_PORT_TOR** - The TCP port to advertise for Tor. Defaults to **REPORT_TCP_PORT**, - unless it is '0', otherwise **TCP_PORT**. '0' disables publishing - the port. + The Tor TCP port to advertise. The default is the clearnet + **REPORT_TCP_PORT**, unless disabled or it is '0', otherwise + **TCP_PORT**. '0' disables publishing a Tor TCP port. * **REPORT_SSL_PORT_TOR** - The SSL port to advertise for Tor. Defaults to **REPORT_SSL_PORT**, - unless it is '0', otherwise **SSL_PORT**. '0' disables publishing - the port. + The Tor SSL port to advertise. The default is the clearnet + **REPORT_SSL_PORT**, unless disabled or it is '0', otherwise + **SSL_PORT**. '0' disables publishing a Tor SSL port. **NOTE**: Certificate-Authority signed certificates don't work over Tor, so you should set **REPORT_SSL_PORT_TOR** to 0 if yours is not self-signed. +IRC +--- + +Use the following environment variables if you want to advertise +connectivity on IRC: + +* **IRC** + + Set to anything non-empty to advertise on IRC + +* **IRC_NICK** + + The nick to use when connecting to IRC. The default is a hash of + **REPORT_HOST**. Either way a prefix will be prepended depending on + **COIN** and **NET**. + + If **REPORT_HOST_TOR** is set, an additional connection to IRC + happens with '_tor' appended to **IRC_NICK**. + + Cache ----- diff --git a/server/env.py b/server/env.py index e27d1c6..a2bf7b0 100644 --- a/server/env.py +++ b/server/env.py @@ -70,33 +70,11 @@ class Env(LoggedClass): self.irc_nick = self.default('IRC_NICK', None) # Identities - report_host = self.default('REPORT_HOST', self.host) - self.check_report_host(report_host) - main_identity = NetIdentity( - report_host, - self.integer('REPORT_TCP_PORT', self.tcp_port) or None, - self.integer('REPORT_SSL_PORT', self.ssl_port) or None, - '' - ) - if main_identity.tcp_port == main_identity.ssl_port: - raise self.Error('REPORT_TCP_PORT and REPORT_SSL_PORT are both {}' - .format(main_identity.tcp_port)) - - self.identities = [main_identity] - tor_host = self.default('REPORT_HOST_TOR', '') - if tor_host.endswith('.onion'): - self.identities.append(NetIdentity( - tor_host, - self.integer('REPORT_TCP_PORT_TOR', - main_identity.tcp_port - if main_identity.tcp_port else - self.tcp_port) or None, - self.integer('REPORT_SSL_PORT_TOR', - main_identity.ssl_port - if main_identity.ssl_port else - self.ssl_port) or None, - '_tor', - )) + clearnet_identity = self.clearnet_identity() + tor_identity = self.tor_identity(clearnet_identity) + self.identities = [identity + for identity in (clearnet_identity, tor_identity) + if identity is not None] def default(self, envvar, default): return environ.get(envvar, default) @@ -131,7 +109,16 @@ class Env(LoggedClass): .format(env_value, value, nofile_limit)) return value - def check_report_host(self, host): + def obsolete(self, envvars): + bad = [envvar for envvar in envvars if environ.get(envvar)] + if bad: + raise self.Error('remove obsolete environment variables {}' + .format(bad)) + + def clearnet_identity(self): + host = self.default('REPORT_HOST', None) + if host is None: + return None try: ip = ip_address(host) except ValueError: @@ -140,9 +127,43 @@ class Env(LoggedClass): bad = ip.is_multicast or ip.is_unspecified if bad: raise self.Error('"{}" is not a valid REPORT_HOST'.format(host)) + tcp_port = self.integer('REPORT_TCP_PORT', self.tcp_port) or None + ssl_port = self.integer('REPORT_SSL_PORT', self.ssl_port) or None + if tcp_port == ssl_port: + raise self.Error('REPORT_TCP_PORT and REPORT_SSL_PORT ' + 'both resolve to {}'.format(tcp_port)) + return NetIdentity( + host, + tcp_port, + ssl_port, + '' + ) - def obsolete(self, envvars): - bad = [envvar for envvar in envvars if environ.get(envvar)] - if bad: - raise self.Error('remove obsolete environment variables {}' - .format(bad)) + def tor_identity(self, clearnet): + host = self.default('REPORT_HOST_TOR', None) + if host is None: + return None + if not tor_host.endswith('.onion'): + raise self.Error('tor host "{}" must end with ".onion"' + .format(host)) + + def port(port_kind): + '''Returns the clearnet identity port, if any and not zero, + otherwise the listening port.''' + result = 0 + if clearnet: + result = getattr(clearnet, port_kind) + return result or getattr(self, port_kind) + + tcp_port = self.integer('REPORT_TCP_PORT_TOR', port('tcp_port')) or None + ssl_port = self.integer('REPORT_SSL_PORT_TOR', port('ssl_port')) or None + if tcp_port == ssl_port: + raise self.Error('REPORT_TCP_PORT_TOR and REPORT_SSL_PORT_TOR ' + 'both resolve to {}'.format(tcp_port)) + + return NetIdentity( + host, + tcp_port, + ssl_port, + '_tor', + )