summaryrefslogtreecommitdiffstats
path: root/libvncserver/sockets.c
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2011-10-04 17:30:36 +0200
committerChristian Beier <dontmind@freeshell.org>2011-10-04 17:30:36 +0200
commitbffd9ee33bd141f5c75304b1430d2ea2725239b3 (patch)
tree0fd8ce48bd28965b623bc03c389847d11a55f3e8 /libvncserver/sockets.c
parent629fe03d617b2a968d30d7ed85c8f8b1e5d6a410 (diff)
parentabec0aa8c3e226682c684c9d8a0dab889815f511 (diff)
downloadlibvncserver-bffd9ee33bd141f5c75304b1430d2ea2725239b3.zip
libvncserver-bffd9ee33bd141f5c75304b1430d2ea2725239b3.tar.gz
Merge branch 'websockets'
Diffstat (limited to 'libvncserver/sockets.c')
-rw-r--r--libvncserver/sockets.c120
1 files changed, 119 insertions, 1 deletions
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index 188a8fd..415f712 100644
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -62,6 +62,10 @@
#include <unistd.h>
#endif
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+#include "rfbssl.h"
+#endif
+
#if defined(__linux__) && defined(NEED_TIMEVAL)
struct timeval
{
@@ -392,6 +396,11 @@ rfbCloseClient(rfbClientPtr cl)
while(cl->screen->maxFd>0
&& !FD_ISSET(cl->screen->maxFd,&(cl->screen->allFds)))
cl->screen->maxFd--;
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->sslctx)
+ rfbssl_destroy(cl);
+ free(cl->wspath);
+#endif
#ifndef __MINGW32__
shutdown(cl->sock,SHUT_RDWR);
#endif
@@ -457,7 +466,17 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
struct timeval tv;
while (len > 0) {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->wsctx) {
+ n = webSocketsDecode(cl, buf, len);
+ } else if (cl->sslctx) {
+ n = rfbssl_read(cl, buf, len);
+ } else {
+ n = read(sock, buf, len);
+ }
+#else
n = read(sock, buf, len);
+#endif
if (n > 0) {
@@ -482,6 +501,12 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
return n;
}
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->sslctx) {
+ if (rfbssl_pending(cl))
+ continue;
+ }
+#endif
FD_ZERO(&fds);
FD_SET(sock, &fds);
tv.tv_sec = timeout / 1000;
@@ -492,6 +517,7 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
return n;
}
if (n == 0) {
+ rfbErr("ReadExact: select timeout\n");
errno = ETIMEDOUT;
return -1;
}
@@ -518,6 +544,82 @@ 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) {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->sslctx)
+ n = rfbssl_peek(cl, buf, len);
+ else
+#endif
+ 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;
+ }
+
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->sslctx) {
+ if (rfbssl_pending(cl))
+ continue;
+ }
+#endif
+ 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("PeekExact: select");
+ return n;
+ }
+ if (n == 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ }
+ }
+#undef DEBUG_READ_EXACT
+#ifdef DEBUG_READ_EXACT
+ rfbLog("PeekExact %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,9 +645,25 @@ rfbWriteExact(rfbClientPtr cl,
fprintf(stderr,"\n");
#endif
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->wsctx) {
+ char *tmp = NULL;
+ if ((len = webSocketsEncode(cl, buf, len, &tmp)) < 0) {
+ rfbErr("WriteExact: WebSockets encode error\n");
+ return -1;
+ }
+ buf = tmp;
+ }
+#endif
+
LOCK(cl->outputMutex);
while (len > 0) {
- n = write(sock, buf, len);
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ if (cl->sslctx)
+ n = rfbssl_write(cl, buf, len);
+ else
+#endif
+ n = write(sock, buf, len);
if (n > 0) {
OpenPOWER on IntegriCloud