Skip to content

Commit

Permalink
Changes to server to allow better control over binding to interfaces (#…
Browse files Browse the repository at this point in the history
…582)

* refactor: remove unused imports

* server: new options to choose certain IP versions

On some setups, IPv6 or IPv4 might be disabled in the OS.
In my case IPv6 is disabled and this causes errors when starting the server.

* server: add options to choose the address to bind to

Sometimes a user might want to bind to localhost only for testing
or have multiple interfaces per IP version and only one must be used.
  • Loading branch information
powerjungle authored Jul 3, 2023
1 parent 884d79b commit 8ba2865
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 14 deletions.
31 changes: 25 additions & 6 deletions syncplay/ep_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@

from syncplay.server import SyncFactory, ConfigurationGetter

class ServerStatus: pass

class ServerStatus:
listening6 = False
listening4 = False


def isListening6(f):
ServerStatus.listening6 = True


def isListening4(f):
ServerStatus.listening4 = True


def failed6(f):
ServerStatus.listening6 = False
print(f.value)
print("IPv6 listening failed.")


def failed4(f):
ServerStatus.listening4 = False
if f.type is CannotListenError and ServerStatus.listening6:
Expand All @@ -27,9 +34,11 @@ def failed4(f):
print(f.value)
print("IPv4 listening failed.")


def main():
argsGetter = ConfigurationGetter()
args = argsGetter.getConfiguration()

factory = SyncFactory(
args.port,
args.password,
Expand All @@ -45,15 +54,25 @@ def main():
args.stats_db_file,
args.tls
)
endpoint6 = TCP6ServerEndpoint(reactor, int(args.port))
endpoint6.listen(factory).addCallbacks(isListening6, failed6)
endpoint4 = TCP4ServerEndpoint(reactor, int(args.port))
endpoint4.listen(factory).addCallbacks(isListening4, failed4)

if args.ipv6_only is True:
endpoint6 = TCP6ServerEndpoint(reactor, int(args.port), interface=args.interface_ipv6)
endpoint6.listen(factory).addCallbacks(isListening6, failed6)
elif args.ipv4_only is True:
endpoint4 = TCP4ServerEndpoint(reactor, int(args.port), interface=args.interface_ipv4)
endpoint4.listen(factory).addCallbacks(isListening4, failed4)
else:
endpoint6 = TCP6ServerEndpoint(reactor, int(args.port), interface=args.interface_ipv6)
endpoint6.listen(factory).addCallbacks(isListening6, failed6)
endpoint4 = TCP4ServerEndpoint(reactor, int(args.port), interface=args.interface_ipv4)
endpoint4.listen(factory).addCallbacks(isListening4, failed4)

if ServerStatus.listening6 or ServerStatus.listening4:
reactor.run()
else:
print("Unable to listen using either IPv4 and IPv6 protocols. Quitting the server now.")
sys.exit()


if __name__ == "__main__":
main()
main()
4 changes: 4 additions & 0 deletions syncplay/messages_de.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@
"server-startTLS-argument": "Erlaube TLS-Verbindungen mit den Zertifikatdateien im Angegebenen Pfad",
"server-messed-up-motd-unescaped-placeholders": "Die Nachricht des Tages hat unmaskierte Platzhalter. Alle $-Zeichen sollten verdoppelt werden ($$).",
"server-messed-up-motd-too-long": "Die Nachricht des Tages ist zu lang - Maximal {} Zeichen, aktuell {}.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Unbekannter Befehl {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_en.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@
"server-startTLS-argument": "Enable TLS connections using the certificate files in the path provided",
"server-messed-up-motd-unescaped-placeholders": "Message of the Day has unescaped placeholders. All $ signs should be doubled ($$).",
"server-messed-up-motd-too-long": "Message of the Day is too long - maximum of {} chars, {} given.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Unknown command {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_eo.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,10 @@
"server-startTLS-argument": "Ŝalti TLS-konektojn per la atestilaj dosieroj en la donita vojo",
"server-messed-up-motd-unescaped-placeholders": "Mesaĝo de tago havas neŝirmitajn anstataŭiĝojn. Ĉiuj dolarsignoj devus aperi duoble ($$).",
"server-messed-up-motd-too-long": "Mesaĝo de tago estas tro longa – maksimuma kvanto estas {} signoj, sed {} estas donitaj.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Nekonata ordono {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_es.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@
"server-startTLS-argument": "Habilitar conexiones TLS usando los archivos de certificado en la ruta provista",
"server-messed-up-motd-unescaped-placeholders": "El mensaje del dia contiene marcadores de posición sin escapar. Todos los signos $ deberían ser dobles ($$).",
"server-messed-up-motd-too-long": "El mensaje del día es muy largo - máximo de {} caracteres, se recibieron {}.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Comando desconocido {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_fr.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@
"server-startTLS-argument": "Activer les connexions TLS à l'aide des fichiers de certificat dans le chemin fourni",
"server-messed-up-motd-unescaped-placeholders": "Le message du jour a des espaces réservés non échappés. Tous les signes $ doivent être doublés ($$).",
"server-messed-up-motd-too-long": "Le message du jour est trop long: {}caractères maximum, {} donnés.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Commande inconnue {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@
"server-startTLS-argument": "Abilita il protocollo TLS usando i certificati contenuti nel percorso indicato",
"server-messed-up-motd-unescaped-placeholders": "Il messaggio del giorno ha dei caratteri non 'escaped'. Tutti i simboli $ devono essere doppi ($$).",
"server-messed-up-motd-too-long": "Il messaggio del giorno è troppo lungo - numero massimo di caratteri è {}, {} trovati.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Comando non riconosciuto {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_pt_BR.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@
"server-startTLS-argument": "Habilita conexões TLS usando os arquivos de certificado no caminho fornecido",
"server-messed-up-motd-unescaped-placeholders": "A Mensagem do Dia possui placeholders não escapados. Todos os sinais de $ devem ser dobrados (como em $$).",
"server-messed-up-motd-too-long": "A Mensagem do Dia é muito longa - máximo de {} caracteres, {} foram dados.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Comando desconhecido: {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_pt_PT.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@
"server-startTLS-argument": "Habilita conexões TLS usando os arquivos de certificado no caminho fornecido",
"server-messed-up-motd-unescaped-placeholders": "A Mensagem do Dia possui placeholders não escapados. Todos os sinais de $ devem ser dobrados (como em $$).",
"server-messed-up-motd-too-long": "A Mensagem do Dia é muito longa - máximo de {} caracteres, {} foram dados.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Comando desconhecido: {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_ru.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@
"server-startTLS-argument": "Включить TLS-соединения используя файлы сертификатов в указанном пути",
"server-messed-up-motd-unescaped-placeholders": "MOTD-сообщение содержит неэкранированные спецсимволы. Все знаки $ должны быть продублированы ($$).",
"server-messed-up-motd-too-long": "MOTD-сообщение слишком длинное: максимальная длина - {} символ(ов), текущая длина - {} символ(ов).",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Неизвестная команда: {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_tr.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@
"server-startTLS-argument": "Dosya yolundaki sertifika dosyalarını kullanarak TLS bağlantılarını etkinleştirin",
"server-messed-up-motd-unescaped-placeholders": "Günün Mesajında çıkış karaktersiz yer tutucular var. Tüm $ işaretleri iki katına çıkarılmalıdır ($$).",
"server-messed-up-motd-too-long": "Günün Mesajı çok uzun - maksimum {} karakter olmalı, {} verildi.",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "Bilinmeyen komut {}", # message
Expand Down
4 changes: 4 additions & 0 deletions syncplay/messages_zh_CN.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@
"server-startTLS-argument": "使用提供的路径中的证书文件启用TLS连接",
"server-messed-up-motd-unescaped-placeholders": "每日信息中有未转义的占位符。所有 $ 字符应当重复两遍 ($$).",
"server-messed-up-motd-too-long": "每日信息过长 - 最大{}个chars, 给出的长度{}",
"server-listen-only-on-ipv4": "Listen only on IPv4 when starting the server.",
"server-listen-only-on-ipv6": "Listen only on IPv6 when starting the server.",
"server-interface-ipv4": "The IP address to bind to for IPv4. Leaving it empty defaults to using all.",
"server-interface-ipv6": "The IP address to bind to for IPv6. Leaving it empty defaults to using all.",

# Server errors
"unknown-command-server-error": "未知命令 {}", # message
Expand Down
16 changes: 9 additions & 7 deletions syncplay/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import codecs
import hashlib
import os
import random
import time
import json
from string import Template

from twisted.enterprise import adbapi
Expand Down Expand Up @@ -292,18 +290,18 @@ class StatsRecorder(object):
def __init__(self, dbHandle, roomManager):
self._dbHandle = dbHandle
self._roomManagerHandle = roomManager

def startRecorder(self, delay):
try:
self._dbHandle.connect()
reactor.callLater(delay, self._scheduleClientSnapshot)
except:
print("--- Error in initializing the stats database. Server Stats not enabled. ---")

def _scheduleClientSnapshot(self):
self._clientSnapshotTimer = task.LoopingCall(self._runClientSnapshot)
self._clientSnapshotTimer.start(constants.SERVER_STATS_SNAPSHOT_INTERVAL)
self._clientSnapshotTimer.start(constants.SERVER_STATS_SNAPSHOT_INTERVAL)

def _runClientSnapshot(self):
try:
snapshotTime = int(time.time())
Expand Down Expand Up @@ -499,7 +497,7 @@ def findFreeUsername(self, username, maxUsernameLength=constants.MAX_USERNAME_LE
while username.lower() in allnames:
username += '_'
return username

def exportRooms(self):
return self._rooms

Expand Down Expand Up @@ -891,3 +889,7 @@ def _prepareArgParser(self):
self._argparser.add_argument('--max-username-length', metavar='maxUsernameLength', type=int, nargs='?', help=getMessage("server-maxusernamelength-argument").format(constants.MAX_USERNAME_LENGTH))
self._argparser.add_argument('--stats-db-file', metavar='file', type=str, nargs='?', help=getMessage("server-stats-db-file-argument"))
self._argparser.add_argument('--tls', metavar='path', type=str, nargs='?', help=getMessage("server-startTLS-argument"))
self._argparser.add_argument('--ipv4-only', action='store_true', help=getMessage("server-listen-only-on-ipv4"))
self._argparser.add_argument('--ipv6-only', action='store_true', help=getMessage("server-listen-only-on-ipv6"))
self._argparser.add_argument('--interface-ipv4', metavar='interfaceIPv4', type=str, nargs='?', help=getMessage("server-interface-ipv4"), default='')
self._argparser.add_argument('--interface-ipv6', metavar='interfaceIPv6', type=str, nargs='?', help=getMessage("server-interface-ipv6"), default='')
1 change: 0 additions & 1 deletion syncplay/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import sys
import time
import traceback
import unicodedata
import urllib.error
import urllib.parse
import urllib.request
Expand Down

0 comments on commit 8ba2865

Please sign in to comment.