Situation: we have fragmented TPKT PDU without two last bytes (or one last byte - for fast-path) in network stack. First call to transport_read_pdu() works normally, read available bytes and exit with status 0 - no whole PDU readed. Before second call this missed bytes arrive. Optionally with next PDU. In second call header parsing code unconditionally read this two bytes(one byte) despite this is not header bytes. And increase stream position, so stream now contains whole PDU. This cause (pduLength - Stream_GetPosition(s)) calculation to be 0. So transport_read_layer_bytes()-->transport_read_layer() return 0 and transport_read_pdu() exits with "not enough data is available" status. If next PDU isn't available next calls to transport_read_pdu() give same result. If next PDU arrive - (pduLength - Stream_GetPosition(s)) will be less than 0. Stream position will grow, grow and grow on each call. And transport_read_pdu() never signals that PDU is readed. Caught on Android FreeRDP client with high RDP traffic (several MBytes/s).
1. Don't draw to screen if server sends begin/end paint messages without any real updates. 2. Redraw only summary region that covers really invalidated part of screen.
Keepalive settings are usually (depending on the implementation) only used if the TCP connection is idle. If the network is interrupted/disconnected/... click or keyboard input generates outgoing traffic therefore the connection isn't idle anymore and keepalives might not be used causing the connection to stay open and the client to stall. Linux 2.6.36 added a TCP_USER_TIMEOUT TCP socket option that lets a program specify the maximum time transmitted data may remain unacknowledged before TCP will close the corresponding connection with ETIMEDOUT. Setting TCP_USER_TIMEOUT allows us to detect a network problem (like cable disconnect) even if the connection isn't idle.