Xpra: Ticket #1312: avoid clipboard loops when running nested / sharing sessions

Related to #41.

Create a UUID for each clipboard helper and add it to a root window property. Clients and servers forward their list of UUIDs to the other end, which then adds those to the root window property. If any duplicates are found, we have a loop.

Another way of dealing with this is to set a random token on startup, prevent this token from ever being sent across, then looking for it at the other end. Any other clipboard synchronization tool will copy it, then we know we have a loop.



Sat, 17 Sep 2016 05:27:26 GMT - Antoine Martin: attachment set

work in progress patch


Wed, 31 Jan 2018 12:08:52 GMT - Antoine Martin: status, description, milestone changed


Wed, 31 Jan 2018 13:31:14 GMT - Antoine Martin:

Done in r18229 (see commit message): we use a token which is never forwarded, then check for its presence at the other end.

Still TODO:


Wed, 31 Jan 2018 15:21:34 GMT - Antoine Martin:

Notifications and more done in r18230.

Keeping this ticket assigned to me as I have seen shadow server hangs in the clipboard code, which may be caused / made worse / related to this.


Fri, 02 Feb 2018 06:12:46 GMT - Antoine Martin: owner, status changed

Crashes and other problems should be gone as of r18248.

@maxmylyn: this ticket should ensure that we can coexist with other clipboard synchronization tools (ie: virtualbox, synergy, etc) and deal with it much more gracefully: disabling the clipboard and showing a notification to the user. Feel free to close.


Fri, 02 Feb 2018 17:04:22 GMT - J. Max Mena: status changed; resolution set

Excellent - noted.

Closing


Fri, 20 Apr 2018 13:21:07 GMT - Antoine Martin: status changed; resolution deleted

Hit a clipboard loop which was not detected: #1814


Wed, 25 Apr 2018 12:34:10 GMT - Antoine Martin: owner, status changed

Finally got a clean reproducer without ssh start:

xpra shadow :1 --bind-tcp=0.0.0.0:10000 --no-daemon -d clipboard

From a win32 client which has clipboard synchronization already active through synergy, this usually works:

xpra attach tcp://192.168.1.8:10000/ -d clipboard

But this usually causes the server to hang:

xpra attach ssh://192.168.1.8/1 -d clipboard

Some of the weird exceptions I hit using these commands, or using a remote start via ssh: xpra start ssh://localhost/1:

Warning: more than 30 clipboard requests per second!
...
Warning: more than 30 clipboard requests per second!
 limit sustained for more than 3 seconds,
 the clipboard is now disabled
do_selection_get(<GtkSelectionData at 0x7fff027517c0>, 0, 45997266) selection=CLIPBOARD
Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/xpra/clipboard/clipboard_base.py", line 332, in _get_clipboard_from_remote_handler
    log("get clipboard from remote handler id=%s", request_id)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 392, in __call__
    self.log(logging.DEBUG, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 388, in log
    global_logging_handler(self.logger.log, level, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 132, in standard_logging
    log(level, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1231, in log
    self._log(level, msg, args, **kwargs)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1285, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1259, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib64/python2.7/logging/__init__.py", line 263, in __init__
    if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
  File "/usr/lib64/python2.7/abc.py", line 132, in __instancecheck__
    if subclass is not None and subclass in cls._abc_cache:
  File "/usr/lib64/python2.7/_weakrefset.py", line 72, in __contains__
    wr = ref(item)
RuntimeError: maximum recursion depth exceeded
remote selection fetch timed out or empty
error running cleanup <function cleanup_tcp_socket at 0x7f41d31ec668>
Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/xpra/scripts/server.py", line 33, in run_cleanups
    c()
  File "/usr/lib64/python2.7/site-packages/xpra/server/socket_util.py", line 129, in cleanup_tcp_socket
    log.info("closing %s socket %s:%s", socktype.lower(), host, iport)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 397, in info
    self.log(logging.INFO, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 388, in log
    global_logging_handler(self.logger.log, level, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/xpra/log.py", line 132, in standard_logging
    log(level, msg, *args, **kwargs)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1231, in log
    self._log(level, msg, args, **kwargs)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1285, in _log
    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
  File "/usr/lib64/python2.7/logging/__init__.py", line 1259, in makeRecord
    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
  File "/usr/lib64/python2.7/logging/__init__.py", line 285, in __init__
    self.threadName = threading.current_thread().name
  File "/usr/lib64/python2.7/threading.py", line 1157, in currentThread
    return _DummyThread()
  File "/usr/lib64/python2.7/threading.py", line 1125, in __init__
    Thread.__init__(self, name=_newname("Dummy-%d"))
  File "/usr/lib64/python2.7/threading.py", line 683, in __init__
    self.__started = Event()
  File "/usr/lib64/python2.7/threading.py", line 553, in Event
    return _Event(*args, **kwargs)
  File "/usr/lib64/python2.7/threading.py", line 565, in __init__
    _Verbose.__init__(self, verbose)
RuntimeError: maximum recursion depth exceeded in __instancecheck__

Thu, 26 Apr 2018 09:21:43 GMT - Antoine Martin: status changed

Another interesting data point is that switching to schedule_emit_token for all owner change events makes things worse.


Thu, 12 Dec 2019 10:57:47 GMT - Antoine Martin: milestone changed

Meh. Now that the clipboard uses native API calls (#812), this no longer causes crashes. I don't think that the loop detection code works properly, so maybe we should just remove it?


Sat, 23 Jan 2021 05:20:49 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1312