diff options
-rw-r--r-- | kvmd/apps/__init__.py | 9 | ||||
-rw-r--r-- | kvmd/apps/vnc/__init__.py | 4 | ||||
-rw-r--r-- | kvmd/apps/vnc/server.py | 25 |
3 files changed, 35 insertions, 3 deletions
diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py index a4264faf..64127355 100644 --- a/kvmd/apps/__init__.py +++ b/kvmd/apps/__init__.py @@ -356,6 +356,15 @@ def _get_config_scheme() -> Dict: "host": Option("::", type=valid_ip_or_host), "port": Option(5900, type=valid_port), "max_clients": Option(10, type=valid_int_f1), + + "no_delay": Option(True, type=valid_bool), + "keepalive": { + "enabled": Option(True, type=valid_bool, unpack_as="keepalive_enabled"), + "idle": Option(10, type=(lambda arg: valid_number(arg, min=1, max=3600)), unpack_as="keepalive_idle"), + "interval": Option(3, type=(lambda arg: valid_number(arg, min=1, max=60)), unpack_as="keepalive_interval"), + "count": Option(3, type=(lambda arg: valid_number(arg, min=1, max=10)), unpack_as="keepalive_count"), + }, + "tls": { "ciphers": Option("ALL:@SECLEVEL=0", type=valid_ssl_ciphers), "timeout": Option(5.0, type=valid_float_f01), diff --git a/kvmd/apps/vnc/__init__.py b/kvmd/apps/vnc/__init__.py index aaf67740..923ac39a 100644 --- a/kvmd/apps/vnc/__init__.py +++ b/kvmd/apps/vnc/__init__.py @@ -50,6 +50,8 @@ def main(argv: Optional[List[str]]=None) -> None: port=config.server.port, max_clients=config.server.max_clients, + no_delay=config.server.no_delay, + tls_ciphers=config.server.tls.ciphers, tls_timeout=config.server.tls.timeout, @@ -65,4 +67,6 @@ def main(argv: Optional[List[str]]=None) -> None: **config.streamer._unpack(), ), vnc_auth_manager=VncAuthManager(**config.auth.vncauth._unpack()), + + **config.server.keepalive._unpack(), ).run() diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py index 73c9c148..55ff4e7c 100644 --- a/kvmd/apps/vnc/server.py +++ b/kvmd/apps/vnc/server.py @@ -285,12 +285,18 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes # ===== class VncServer: # pylint: disable=too-many-instance-attributes - def __init__( # pylint: disable=too-many-arguments + def __init__( # pylint: disable=too-many-arguments,too-many-locals self, host: str, port: int, max_clients: int, + no_delay: bool, + keepalive_enabled: bool, + keepalive_idle: int, + keepalive_interval: int, + keepalive_count: int, + tls_ciphers: str, tls_timeout: float, @@ -318,6 +324,19 @@ class VncServer: # pylint: disable=too-many-instance-attributes remote = rfb_format_remote(writer) logger.info("[entry] [%s]: Connected client", remote) try: + sock = writer.get_extra_info("socket") + if no_delay: + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + if keepalive_enabled: + # https://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#setsockopt + # https://blog.cloudflare.com/when-tcp-sockets-refuse-to-die + sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, keepalive_idle) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, keepalive_interval) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, keepalive_count) + timeout = (keepalive_idle + keepalive_interval * keepalive_count) * 1000 # Milliseconds + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_USER_TIMEOUT, timeout) + try: async with kvmd.make_session("", "") as kvmd_session: none_auth_only = await kvmd_session.auth.check() @@ -357,8 +376,8 @@ class VncServer: # pylint: disable=too-many-instance-attributes logger.info("Listening VNC on TCP [%s]:%d ...", self.__host, self.__port) with contextlib.closing(socket.socket(socket.AF_INET6, socket.SOCK_STREAM)) as sock: - sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, False) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) + sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((self.__host, self.__port)) server = loop.run_until_complete(asyncio.start_server( |