Skip to content

Commit

Permalink
remove UDP transport (unmaintained and buggy)
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed May 22, 2021
1 parent c963447 commit 2022238
Show file tree
Hide file tree
Showing 19 changed files with 35 additions and 752 deletions.
1 change: 0 additions & 1 deletion docs/Usage/Logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ The full list of categories can be shown using `xpra -d help`, to see this list
|protocol|packet input and output|
|websocket|WebSocket layer|
|named-pipe|Named pipe|
|udp|UDP|
|crypto|[encryption](../Network/Encryption.md)
|auth|[authentication](./Authentication.md)
|upnp|UPnP|
Expand Down
32 changes: 7 additions & 25 deletions fs/share/man/man1/xpra.1
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,12 @@ the client can find at least one of the directories used by
the unix domain sockets (see \fIbind\fP, \fIsocket-dir\fP and
\fIsocket-dirs\fP).

If the xpra server was given the \fB--bind-tcp\fP, \fB--bind-ssl\fP
\fB--bind-udp\fP=\fI[HOST]:PORT\fP,
\fB--bind-ws\fP, \fB--bind-wss\fP or \fB--bind-vsock\fP option
when started then you can also connect
to it using a display of the form \fBtcp://HOST:PORT[/DISPLAY]\fP,
\fBudp://HOST:PORT[/DISPLAY]\fP, \fBssl://HOST:PORT[/DISPLAY]\fP,
\fBws://HOST:PORT[/DISPLAY]\fP, \fBwss://HOST:PORT[/DISPLAY]\fP or
\fBvsock://HOST:PORT[/DISPLAY]\fP.
If the xpra server was given the \fB--bind-tcp\fP=\fI[HOST]:PORT\fP
(or \fB--bind-ssl\fP, \fB--bind-ws\fP, \fB--bind-wss\fP, \fB--bind-vsock\fP)
option when started then you can also connect to it using a display of
the form \fBtcp://HOST:PORT[/DISPLAY]\fP,
\fBssl://HOST:PORT[/DISPLAY]\fP, \fBws://HOST:PORT[/DISPLAY]\fP,
\fBwss://HOST:PORT[/DISPLAY]\fP or \fBvsock://HOST:PORT[/DISPLAY]\fP.
.\" --------------------------------------------------------------------
.SH SUBCOMMANDS
.SS xpra start
Expand Down Expand Up @@ -661,7 +659,7 @@ use a dialog.
.TP

\fB--min-port\fP=\fIPORT\fP
The minimum port number allowed when creating UDP and TCP sockets.
The minimum port number allowed when creating TCP sockets.
You can use a lower value to allow unprivileged users to bind to
privileged ports when starting sessions via the system wide proxy server.
The default value is 1024 which is the standard value for privileged ports.
Expand Down Expand Up @@ -736,19 +734,7 @@ if the \fBhtml\fP switch is enabled.
TCP sockets may also be upgraded to SSL sockets if the
\fBssl\fP switch is enabled.
.TP
\fB--bind-udp\fP=\fI[HOST]:PORT[,PROPERTIES]\fP
Create a UDP socket for each \fB--bind-udp\fP option specified.
If the host portion is omitted, then 127.0.0.1 (localhost) will be
used. If you wish to accept connections on all interfaces, pass
0.0.0.0 for the host portion.

Using this switch without using the \fIudp-auth\fP option is not recommended,
and is a major security risk (especially when passing 0.0.0.0)!
Anyone at all may connect to this port and access your session.
UDP sessions are trivial to hijack for anyone able to sniff
even just a single packet, it should only be used in very specific
use-cases, and never over unsecured networks.
.TP
\fB--bind-ws\fP=\fI[HOST]:PORT[,PROPERTIES]\fP
Create an HTTP / Websocket listener.
See \fBbind-tcp\fP for host restrictions,
Expand Down Expand Up @@ -889,10 +875,6 @@ using the python \fIldap3\fP library.
Just like the \fBauth\fP switch, except this one only applies
to TCP sockets (sockets defined using the \fBbind-tcp\fP switch).
.TP
\fB--udp-auth\fP=\fIMODULE\fP
Just like the \fBtcp-auth\fP switch, except this one only applies
to UDP sockets (sockets defined using the \fBbind-udp\fP switch).
.TP
\fB--ws-auth\fP=\fIMODULE\fP
Just like the \fBauth\fP switch, except this one only applies
to ws sockets: sockets defined using the \fBbind-ws\fP switch,
Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/unit/client/mixins/remotelogging_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MixinsTest(ClientMixinTest):

def test_remotelogging(self):
from xpra.log import Logger, is_debug_enabled
for x in ("network", "crypto", "udp"):
for x in ("network", "crypto"):
if is_debug_enabled(x):
#remote logging will be disabled,
#so we have to skip this test
Expand Down
5 changes: 1 addition & 4 deletions tests/unittests/unit/scripts/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def e(s):
e("tcp://host:0/")
e("tcp://host:65536/")
t("tcp://username@host/", {"username" : "username", "password" : None})
for socktype in ("tcp", "udp", "ws", "wss", "ssl", "ssh"):
for socktype in ("tcp", "ws", "wss", "ssl", "ssh"):
#e(socktype+"://a/b/c/d")
t(socktype+"://username:password@host:10000/DISPLAY?key1=value1", {
"type" : socktype,
Expand Down Expand Up @@ -225,9 +225,6 @@ def fd(d):
"port" : 100000,
"strict-host-check" : False,
})
#udp never fails when opening the connection:
conn = connect_to({"type" : "udp", "host" : "localhost", "port" : 20000, "display_name" : ":200"}, AdHocStruct())
conn.close()


def _test_subcommand(self, args, timeout=60, **kwargs):
Expand Down
7 changes: 0 additions & 7 deletions xpra/client/client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,6 @@ def get_scheduler(self):

def setup_connection(self, conn):
netlog("setup_connection(%s) timeout=%s, socktype=%s", conn, conn.timeout, conn.socktype)
if conn.socktype=="udp":
self.add_packet_handler("udp-control", self._process_udp_control, False)
protocol_class = get_client_protocol_class(conn.socktype)
protocol = protocol_class(self.get_scheduler(), conn, self.process_packet, self.next_packet)
self._protocol = protocol
Expand All @@ -358,11 +356,6 @@ def setup_connection(self, conn):
netlog("setup_connection(%s) protocol=%s", conn, protocol)
return protocol

def _process_udp_control(self, packet):
#send it back to the protocol object:
self._protocol.process_control(*packet[1:])


def init_aliases(self):
i = 1
for key in PACKET_TYPES:
Expand Down
2 changes: 0 additions & 2 deletions xpra/client/mixins/network_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ def __init__(self):
def init(self, opts):
def err(msg):
raise InitException(msg)
#don't listen on udp sockets for now:
opts.bind_udp = ()
self.sockets = create_sockets(opts, err)
if opts.bind:
try:
Expand Down
2 changes: 1 addition & 1 deletion xpra/client/mixins/remote_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def parse_server_capabilities(self, c : typedict) -> bool:
c.boolget("remote-logging") or c.boolget("remote-logging.receive")):
#check for debug:
from xpra.log import is_debug_enabled
conflict = tuple(v for v in ("network", "crypto", "udp", "websocket") if is_debug_enabled(v))
conflict = tuple(v for v in ("network", "crypto", "websocket") if is_debug_enabled(v))
if conflict:
log.warn("Warning: cannot enable remote logging")
log.warn(" because debug logging is enabled for: %s", csv(conflict))
Expand Down
1 change: 0 additions & 1 deletion xpra/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ def enable_format(format_string):
"protocol" : "Packet input and output (formatting, parsing, sending and receiving)",
"websocket" : "WebSocket layer",
"named-pipe" : "Named pipe",
"udp" : "UDP",
"crypto" : "Encryption",
"auth" : "Authentication",
"upnp" : "UPnP",
Expand Down
1 change: 0 additions & 1 deletion xpra/net/bytestreams.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ def close(self):
i = s
log("%s.close() for socket=%s", self, i)
Connection.close(self)
#meaningless for udp:
try:
s.settimeout(0)
except IOError:
Expand Down
5 changes: 2 additions & 3 deletions xpra/net/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class ConnectionClosedException(Exception):
MAX_PACKET_SIZE = envint("XPRA_MAX_PACKET_SIZE", 16*1024*1024)
FLUSH_HEADER = envbool("XPRA_FLUSH_HEADER", True)

SOCKET_TYPES = ("tcp", "ws", "wss", "ssl", "ssh", "rfb", "vsock", "udp")
SOCKET_TYPES = ("tcp", "ws", "wss", "ssl", "ssh", "rfb", "vsock")

IP_SOCKTYPES = ("tcp", "ssl", "ws", "wss", "ssh", "udp")
IP_SOCKTYPES = ("tcp", "ssl", "ws", "wss", "ssh")
TCP_SOCKTYPES = ("tcp", "ssl", "ws", "wss", "ssh")


Expand All @@ -43,7 +43,6 @@ class ConnectionClosedException(Exception):
"notify_show", "notify_close",
"rpc-reply", "startup-complete", "setting-change", "control",
"encodings",
"udp-control",
]

def get_log_packets(exclude=False):
Expand Down
6 changes: 0 additions & 6 deletions xpra/net/protocol_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,13 @@
# later version. See the file COPYING for details.

def get_client_protocol_class(socktype):
if socktype=="udp":
from xpra.net.udp_protocol import UDPClientProtocol
return UDPClientProtocol
if socktype in ("ws", "wss"):
from xpra.net.websockets.protocol import WebSocketProtocol
return WebSocketProtocol
from xpra.net.protocol import Protocol
return Protocol

def get_server_protocol_class(socktype):
if socktype=="udp":
from xpra.net.udp_protocol import UDPServerProtocol
return UDPServerProtocol
if socktype in ("ws", "wss"):
from xpra.net.websockets.protocol import WebSocketProtocol
return WebSocketProtocol
Expand Down
69 changes: 10 additions & 59 deletions xpra/net/socket_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ def hosts(host_str):
return ["0.0.0.0", "::"]
return [host_str]

def add_listen_socket(socktype, sock, info, new_connection_cb, new_udp_connection_cb=None, options=None):
def add_listen_socket(socktype, sock, info, new_connection_cb, options=None):
log = get_network_logger()
log("add_listen_socket(%s, %s, %s, %s, %s, %s)",
socktype, sock, info, new_connection_cb, new_udp_connection_cb, options)
socktype, sock, info, new_connection_cb, options)
try:
#ugly that we have different ways of starting sockets,
#TODO: abstract this into the socket class
Expand All @@ -134,19 +134,15 @@ def add_listen_socket(socktype, sock, info, new_connection_cb, new_udp_connectio
sock.start()
return None
sources = []
if socktype=="udp":
assert new_udp_connection_cb, "UDP sockets cannot be handled here"
new_udp_connection_cb(sock)
else:
from gi.repository import GLib
sock.listen(5)
def io_in_cb(sock, flags):
log("io_in_cb(%s, %s)", sock, flags)
return new_connection_cb(socktype, sock)
source = GLib.io_add_watch(sock, GLib.PRIORITY_DEFAULT, GLib.IO_IN, io_in_cb)
sources.append(source)
from gi.repository import GLib
sock.listen(5)
def io_in_cb(sock, flags):
log("io_in_cb(%s, %s)", sock, flags)
return new_connection_cb(socktype, sock)
source = GLib.io_add_watch(sock, GLib.PRIORITY_DEFAULT, GLib.IO_IN, io_in_cb)
sources.append(source)
upnp_cleanup = []
if socktype in ("udp", "tcp", "ws", "wss", "ssh", "ssl"):
if socktype in ("tcp", "ws", "wss", "ssh", "ssl"):
upnp = (options or {}).get("upnp", "no")
if upnp.lower() in TRUE_OPTIONS:
from xpra.net.upnp import upnp_add
Expand Down Expand Up @@ -298,7 +294,6 @@ def guess_packet_type(data):

def create_sockets(opts, error_cb):
bind_tcp = parse_bind_ip(opts.bind_tcp)
bind_udp = parse_bind_ip(opts.bind_udp)
bind_ssl = parse_bind_ip(opts.bind_ssl, 443)
bind_ssh = parse_bind_ip(opts.bind_ssh, 22)
bind_ws = parse_bind_ip(opts.bind_ws, 80)
Expand All @@ -316,13 +311,6 @@ def add_tcp_socket(socktype, host_str, iport, options):
sock = setup_tcp_socket(host, iport, socktype)
host, iport = sock[2]
sockets[sock] = options
def add_udp_socket(socktype, host_str, iport, options):
if iport!=0 and iport<min_port:
error_cb("invalid %s port number %i (minimum value is %i)" % (socktype, iport, min_port))
for host in hosts(host_str):
sock = setup_udp_socket(host, iport, socktype)
host, iport = sock[2]
sockets[sock] = options
# Initialize the TCP sockets before the display,
# That way, errors won't make us kill the Xvfb
# (which may not be ours to kill at that point)
Expand Down Expand Up @@ -352,9 +340,6 @@ def add_udp_socket(socktype, host_str, iport, options):
log("setting up %s sockets: %s", socktype, csv(defs.items()))
for (host, iport), options in defs.items():
add_tcp_socket(socktype, host, iport, options)
log("setting up UDP sockets: %s", csv(bind_udp.items()))
for (host, iport), options in bind_udp.items():
add_udp_socket("udp", host, iport, options)
log("setting up vsock sockets: %s", csv(bind_vsock.items()))
for (cid, iport), options in bind_vsock.items():
sock = setup_vsock_socket(cid, iport)
Expand Down Expand Up @@ -414,40 +399,6 @@ def cleanup_tcp_socket():
log.info("created %s socket '%s:%s'", socktype, host, iport)
return socktype, tcp_socket, (host, iport), cleanup_tcp_socket

def create_udp_socket(host, iport):
if host.find(":")<0:
listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sockaddr = (host, iport)
else:
assert socket.has_ipv6, "specified an IPv6 address but this is not supported"
res = socket.getaddrinfo(host, iport, socket.AF_INET6, socket.SOCK_DGRAM)
listener = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sockaddr = res[0][-1]
listener.bind(sockaddr)
return listener

def setup_udp_socket(host, iport, socktype="udp"):
log = get_network_logger()
try:
udp_socket = create_udp_socket(host, iport)
except Exception as e:
log("create_udp_socket%s", (host, iport), exc_info=True)
raise InitExit(EXIT_SOCKET_CREATION_ERROR,
"failed to setup %s socket on %s:%s %s" % (socktype, host, iport, e)) from None
def cleanup_udp_socket():
log.info("closing %s socket %s:%s", socktype, host, iport)
try:
udp_socket.close()
except OSError:
pass
if iport==0:
iport = udp_socket.getsockname()[1]
log.info("allocated UDP port %i for %s", iport, host)
log("%s: %s:%s : %s", socktype, host, iport, socket)
log.info("created UDP socket %s:%s", host, iport)
return socktype, udp_socket, (host, iport), cleanup_udp_socket


def parse_bind_ip(bind_ip, default_port=DEFAULT_PORT):
ip_sockets = {}
if bind_ip:
Expand Down
Loading

0 comments on commit 2022238

Please sign in to comment.