diff --git a/common/network/Udp.cxx b/common/network/Udp.cxx index e59d0f1..9fd4dfa 100644 --- a/common/network/Udp.cxx +++ b/common/network/Udp.cxx @@ -40,7 +40,7 @@ using namespace network; static rfb::LogWriter vlog("WebUdp"); static WuHost *host = NULL; -rfb::IntParameter udpSize("udpSize", "UDP packet data size", 1300, 500, 1400); +rfb::IntParameter udpSize("udpSize", "UDP packet data size", 1296, 500, 1400); extern settings_t settings; @@ -95,10 +95,11 @@ void *udpserver(void *nport) { } // Send one packet, split into N UDP-sized pieces -static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint32_t *id) { +static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint32_t *id, + const uint32_t *frame) { const uint32_t DATA_MAX = udpSize; - uint8_t buf[1400 + sizeof(uint32_t) * 4]; + uint8_t buf[1400 + sizeof(uint32_t) * 5]; const uint32_t pieces = (len / DATA_MAX) + ((len % DATA_MAX) ? 1 : 0); uint32_t i; @@ -111,12 +112,13 @@ static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint memcpy(&buf[4], &i, sizeof(uint32_t)); memcpy(&buf[8], &pieces, sizeof(uint32_t)); memcpy(&buf[12], &hash, sizeof(uint32_t)); + memcpy(&buf[16], frame, sizeof(uint32_t)); - memcpy(&buf[16], data, curlen); + memcpy(&buf[20], data, curlen); data += curlen; len -= curlen; - if (WuHostSendBinary(host, client, buf, curlen + sizeof(uint32_t) * 4) < 0) + if (WuHostSendBinary(host, client, buf, curlen + sizeof(uint32_t) * 5) < 0) return 1; } @@ -125,7 +127,8 @@ static uint8_t udpsend(WuClient *client, const uint8_t *data, unsigned len, uint return 0; } -UdpStream::UdpStream(): OutStream(), client(NULL), total_len(0), id(0), failed(false) { +UdpStream::UdpStream(): OutStream(), client(NULL), total_len(0), id(0), failed(false), + frame(0) { ptr = data; end = data + UDPSTREAM_BUFSIZE; @@ -137,7 +140,7 @@ void UdpStream::flush() { total_len += len; if (client) { - if (udpsend(client, data, len, &id)) { + if (udpsend(client, data, len, &id, &frame)) { vlog.error("Error sending udp, client gone?"); failed = true; } diff --git a/common/network/Udp.h b/common/network/Udp.h index 0bdeb22..38c9f46 100644 --- a/common/network/Udp.h +++ b/common/network/Udp.h @@ -40,6 +40,10 @@ namespace network { client = cli; } + void setFrameNumber(const unsigned in) { + frame = in; + } + bool isFailed() const; void clearFailed(); private: @@ -48,6 +52,7 @@ namespace network { size_t total_len; uint32_t id; bool failed; + uint32_t frame; }; } diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx index cc6f571..b6fa6af 100644 --- a/common/rfb/EncodeManager.cxx +++ b/common/rfb/EncodeManager.cxx @@ -363,6 +363,9 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_, unsigned screenArea; updates++; + if (conn->cp.supportsUdp) + ((network::UdpStream *) conn->getOutStream(conn->cp.supportsUdp))->setFrameNumber(updates); + // The video resolution may have changed, check it if (conn->cp.kasmPassed[ConnParams::KASM_MAX_VIDEO_RESOLUTION]) diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx index aba2cdd..11c59c7 100644 --- a/common/rfb/SMsgWriter.cxx +++ b/common/rfb/SMsgWriter.cxx @@ -39,7 +39,7 @@ static LogWriter vlog("SMsgWriter"); SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_, rdr::OutStream* udps_) : cp(cp_), os(os_), udps(udps_), - nRectsInUpdate(0), nRectsInHeader(0), + nRectsInUpdate(0), dataRectsInUpdate(0), nRectsInHeader(0), needSetDesktopSize(false), needExtendedDesktopSize(false), needSetDesktopName(false), needSetCursor(false), needSetXCursor(false), needSetCursorWithAlpha(false), @@ -340,7 +340,7 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects) os->writeU16(nRects); - nRectsInUpdate = 0; + nRectsInUpdate = dataRectsInUpdate = 0; if (nRects == 0xFFFF) nRectsInHeader = 0; else @@ -365,7 +365,7 @@ void SMsgWriter::writeFramebufferUpdateEnd() // Send an UDP flip marker, if needed if (cp->supportsUdp) { - udps->writeS16(0); + udps->writeS16(dataRectsInUpdate); udps->writeS16(0); udps->writeU16(0); udps->writeU16(0); @@ -394,6 +394,7 @@ void SMsgWriter::startRect(const Rect& r, int encoding) { if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader) throw Exception("SMsgWriter::startRect: nRects out of sync"); + ++dataRectsInUpdate; if (cp->supportsUdp) { udps->writeS16(r.tl.x); diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h index f16b03b..ba07c62 100644 --- a/common/rfb/SMsgWriter.h +++ b/common/rfb/SMsgWriter.h @@ -165,6 +165,7 @@ namespace rfb { rdr::OutStream* udps; int nRectsInUpdate; + int dataRectsInUpdate; int nRectsInHeader; bool needSetDesktopSize;