[SIP SIMPLE client] MSRP might just not be the right choice for tunneling RFB

Willem Toorop willem at ahk.nl
Thu Jan 22 13:06:08 CET 2009

Hi Adrian, Michiel, Ruud, Denis et al.

After I putted the pieces together as described earlier, I kept getting this

Traceback (most recent call last):
  File "./21_sip_offer_desktop", line 85, in <module>
  File "./21_sip_offer_desktop", line 76, in main
  File "/home/willem/sip/21/vncserver.py", line 42, in vncserver
    sock2sock(x11sock, clientsock)
  File "/home/willem/sip/21/vncserver.py", line 36, in sock2sock
    data = data[sock2.send(data):]
  File "/home/willem/sip/21/sockint4msrp.py", line 24, in send
    msrp.send_message(data, content_type)
  File "/usr/lib/python2.5/site-packages/msrplib/transport.py", line 448, in
  File "/usr/lib/python2.5/site-packages/msrplib/transport.py", line 364, in
  File "/usr/lib/python2.5/site-packages/msrplib/transport.py", line 220, in
  File "/usr/lib/python2.5/site-packages/msrplib/transport.py", line 216, in
    return self.transport.write(data)
  File "/usr/lib/python2.5/site-packages/twisted/internet/abstract.py", line
182, in write
line 43, in pauseProducing
line 110, in reset
    assert self._result is not NOT_USED, 'Trying to re-reset() a fresh
AssertionError: Trying to re-reset() a fresh event.

Looking at twisted/internet/abstract.py I saw that everything written is
buffered and that the producer is paused when the buffer is full. The
producer is in our case the process reading from the vncserver and writing
to the msrp transport. Only nothing was actually paused. The send_message
method, always returns immediatly.
I've tried several things (like testing for the buffersize, and then waiting
for a while until the buffer would shrink again), but I finaly concluded

The write method of class MSRPTransport in file msrplib/transport.py

    def write(self, data):
        if self.traffic_logger:
            self.traffic_logger.report_out(data, self.transport)
        return self.transport.write(data)

should be altered to:

    def write(self, data):
        if self.traffic_logger:
            self.traffic_logger.report_out(data, self.transport)
        GreenTransportBase.write(self, data)

as the baseclass GreenTransportBase, *does* implement a mechanism in which
it can be paused by twisted calling the pauseProducing function. Also the
write method of the transport object, currently a FileDescriptor class from
twisted/internet/abstract.py, doesn't return anything, so I don't understand
why the MSRPTransport class returns the returned value from the method.

After making the proposed alteration, the vncserver and client connected
succesfully, but after a while, garbage is written the the viewer. In the
vncserver log it mentions the creation of a xdamage object, and shortly
afterward mentions the resetting of the connection by the client.
I suspect that the messages from the vncserver to the client might not
arrive in the right order. I think the MSRP-relay just tries to sent out all
messages it receives as quickly as possible. A short messages could arrive
earlier then a big messages, even if the short message was sent after the
big message. I should investigate this further to be sure... but how?.
Increasing the message size of the server does work (maybe because all the
related RFB messages then are more likely to stick together), but the
performance in the viewer is then extremely poor. Screen updates take tens
of seconds.

When using MSRPTransport.deliver_message in stead of send_message, the
performance is much better! Small updates take only 3 seconds or less, but
big update still take tens of seconds. I'm under the impression that smaller
message sizes perform better with deliver_message then big message sizes,
but it doesn't differ much. It is still unusably slow.
I understand (from reading the source) that deliver_message only checks the
first hop, and doesn't actually guarantee that the message are actually
delivered. Perhaps waiting for this answer just slows down the process so
much, so that messages are able to arrive in the right order.

It is also interesting to see how x11vnc adjust its estimated link rate.
Only with deliver_message it estimates it to slower than LAN speed. Maybe
x11vnc adjusts its update alogrithm to the link speed.

I think ideally with RFB over MSRP we would like to use send_message, in
stead of deliver_message. We do not need to be confirmed of the message
being deliverd at the MSRP-Relay. We do however like te be able to process
the next message only as the previous one is sent out over the tcp
connection. Even with the altered write method, send_message still doesn't
allow this. The transport object (from twisted) seems to use a buffering
mechanism with a seperate threat actually sending out all the messages.

I understand that the usage of those twisted classes will give better
performance at an instant-messaging-user-interface. The control is directly
returned to the process displaying and inputting messages, without waiting
for the old message being sent out, but for a regular tcp session this is
not ideal.

I see another problem with TCP sessions over MSRP in general. With regular
TCP an answer to a message can be returned with the confirmation of the
reception of the message. With MSRP this is not possible. MSRP acts as two
unidirectional streams which are guaranteed to be delivered, but the
connection between the reception of a message and the response is not there
anymore. This is no problem with streams that have a 'command, reply'
structure (such as smtp, pop, http etc), but it is a problem when there is a
stream of messages and a answer should be able to be sent back with the
acknowlegment of a specific message from that stream. Such a message, when
tunneling over MSRP, could be received at a much later time.
I'm not under the impression that this is a problem with the RFB protocol,
but I can imagine that a better update mechanism could be chosen by the
vncserver when it has a realistic idea of how quickly its messages are
received by the client. At the moment it seems to estimate this on the basis
of the time it takes to actually sent out a message (which we can't because
of twisted buffering). An implementation using a TURN server would also have
this problem: The vncserver would then estimate its speed as the speed it
takes for the TURN server to receive the messages.

The scripts I have been testing with are attached in

I'm beginning to feel that we should drop trying to tunnel RFB over MSRP,
and in stead should try to set it up as a regular TCP session between
end-points as described in
End-points could be using a STUN or TURN server to travese the NAT if
neccesary, based on procedures described in

For the moment I think I would like to investigate a VNC server which let
you pick an application window to share (in stead of the whole desktop (as
with SharedAppVNC <http://shared-app-vnc.sourceforge.net/>) ). I would also
like to try to get sipsimpleclient running on MS-Windows.
It would be nice to try the attached scripts with an
MSRPTransport.send_message that returns when the message is actually sent
over TCP. Would any of you be able to implement such a function?
After that, I should start on writing the report, as time is running out.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ag-projects.com/pipermail/sipbeyondvoip/attachments/20090122/f7f24880/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sip_desktop_sharing.tgz
Type: application/x-gzip
Size: 25519 bytes
Desc: not available
URL: <http://lists.ag-projects.com/pipermail/sipbeyondvoip/attachments/20090122/f7f24880/attachment-0014.bin>

More information about the SIPBeyondVoIP mailing list