summaryrefslogtreecommitdiffstats
path: root/libvncserver/sockets.c
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2011-08-16 14:02:31 +0200
committerJohannes Schindelin <johannes.schindelin@gmx.de>2011-08-17 12:41:23 +0200
commit6fac22a74b5020387a6961e4cc197b5fa4743f96 (patch)
tree9eb15702fbeed2f15fe2de17b54ac92544582509 /libvncserver/sockets.c
parent353b35e86aa7d51d767f4ff66e1179105bbee205 (diff)
downloadlibtdevnc-6fac22a74b5020387a6961e4cc197b5fa4743f96.tar.gz
libtdevnc-6fac22a74b5020387a6961e4cc197b5fa4743f96.zip
websockets: Initial WebSockets support.
Has a bug: WebSocket client disconnects are not detected. rfbSendFramebufferUpdate is doing a MSG_PEEK recv to determine if enough data is available which prevents a disconnect from being detected. Otherwise it's working pretty well. [jes: moved added struct members to the end for binary compatibility with previous LibVNCServer versions, removed an unused variable] Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'libvncserver/sockets.c')
-rw-r--r--libvncserver/sockets.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index 188a8fd..267287d 100644
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -457,7 +457,15 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
struct timeval tv;
while (len > 0) {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->webSockets) {
+ n = webSocketsDecode(cl, buf, len);
+ } else {
+ n = read(sock, buf, len);
+ }
+#else
n = read(sock, buf, len);
+#endif
if (n > 0) {
@@ -518,6 +526,71 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len)
}
/*
+ * PeekExact peeks at an exact number of bytes from a client. Returns 1 if
+ * those bytes have been read, 0 if the other end has closed, or -1 if an
+ * error occurred (errno is set to ETIMEDOUT if it timed out).
+ */
+
+int
+rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
+{
+ int sock = cl->sock;
+ int n;
+ fd_set fds;
+ struct timeval tv;
+
+ while (len > 0) {
+ n = recv(sock, buf, len, MSG_PEEK);
+
+ if (n == len) {
+
+ break;
+
+ } else if (n == 0) {
+
+ return 0;
+
+ } else {
+#ifdef WIN32
+ errno = WSAGetLastError();
+#endif
+ if (errno == EINTR)
+ continue;
+
+#ifdef LIBVNCSERVER_ENOENT_WORKAROUND
+ if (errno != ENOENT)
+#endif
+ if (errno != EWOULDBLOCK && errno != EAGAIN) {
+ return n;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ n = select(sock+1, &fds, NULL, &fds, &tv);
+ if (n < 0) {
+ rfbLogPerror("ReadExact: select");
+ return n;
+ }
+ if (n == 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ }
+#undef DEBUG_READ_EXACT
+#ifdef DEBUG_READ_EXACT
+ rfbLog("ReadExact %d bytes\n",len);
+ for(n=0;n<len;n++)
+ fprintf(stderr,"%02x ",(unsigned char)buf[n]);
+ fprintf(stderr,"\n");
+#endif
+
+ return 1;
+}
+
+/*
* WriteExact writes an exact number of bytes to a client. Returns 1 if
* those bytes have been written, or -1 if an error occurred (errno is set to
* ETIMEDOUT if it timed out).
@@ -543,6 +616,16 @@ rfbWriteExact(rfbClientPtr cl,
fprintf(stderr,"\n");
#endif
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->webSockets) {
+ if ((len = webSocketsEncode(cl, buf, len)) < 0) {
+ rfbErr("WriteExact: WebSockets encode error\n");
+ return -1;
+ }
+ buf = cl->encodeBuf;
+ }
+#endif
+
LOCK(cl->outputMutex);
while (len > 0) {
n = write(sock, buf, len);