Blame SOURCES/0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch

9b8edd
From 0a98d629447964f1d5d922d5012ee0c2cbf10694 Mon Sep 17 00:00:00 2001
9b8edd
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
9b8edd
Date: Mon, 11 Jun 2018 23:47:02 +0200
9b8edd
Subject: [PATCH 1/2] libvncserver: Add API to add custom I/O entry points
9b8edd
9b8edd
Add API to make it possible to channel RFB input and output through
9b8edd
another layer, for example TLS. This is done by making it possible to
9b8edd
override the default read/write/peek functions.
9b8edd
---
9b8edd
 libvncserver/rfbserver.c |  4 +++
9b8edd
 libvncserver/sockets.c   | 64 +++++++++++++++++++++++++++++++++++++---
9b8edd
 rfb/rfb.h                | 17 +++++++++++
9b8edd
 3 files changed, 81 insertions(+), 4 deletions(-)
9b8edd
9b8edd
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
9b8edd
index 7af6aed..fbedd9f 100644
9b8edd
--- a/libvncserver/rfbserver.c
9b8edd
+++ b/libvncserver/rfbserver.c
9b8edd
@@ -322,6 +322,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
9b8edd
 
9b8edd
     cl->screen = rfbScreen;
9b8edd
     cl->sock = sock;
9b8edd
+    cl->readFromSocket = rfbDefaultReadFromSocket;
9b8edd
+    cl->peekAtSocket = rfbDefaultPeekAtSocket;
9b8edd
+    cl->hasPendingOnSocket = rfbDefaultHasPendingOnSocket;
9b8edd
+    cl->writeToSocket = rfbDefaultWriteToSocket;
9b8edd
     cl->viewOnly = FALSE;
9b8edd
     /* setup pseudo scaling */
9b8edd
     cl->scaledScreen = rfbScreen;
9b8edd
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
9b8edd
index bbc3d90..27515f2 100644
9b8edd
--- a/libvncserver/sockets.c
9b8edd
+++ b/libvncserver/sockets.c
9b8edd
@@ -589,6 +589,30 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
9b8edd
     return sock;
9b8edd
 }
9b8edd
 
9b8edd
+int
9b8edd
+rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len)
9b8edd
+{
9b8edd
+    return read(cl->sock, buf, len);
9b8edd
+}
9b8edd
+
9b8edd
+static int
9b8edd
+rfbReadFromSocket(rfbClientPtr cl, char *buf, int len)
9b8edd
+{
9b8edd
+    return cl->readFromSocket(cl, buf, len);
9b8edd
+}
9b8edd
+
9b8edd
+rfbBool
9b8edd
+rfbDefaultHasPendingOnSocket(rfbClientPtr cl)
9b8edd
+{
9b8edd
+    return FALSE;
9b8edd
+}
9b8edd
+
9b8edd
+static rfbBool
9b8edd
+rfbHasPendingOnSocket(rfbClientPtr cl)
9b8edd
+{
9b8edd
+    cl->hasPendingOnSocket(cl);
9b8edd
+}
9b8edd
+
9b8edd
 /*
9b8edd
  * ReadExact reads an exact number of bytes from a client.  Returns 1 if
9b8edd
  * those bytes have been read, 0 if the other end has closed, or -1 if an error
9b8edd
@@ -610,10 +634,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
9b8edd
         } else if (cl->sslctx) {
9b8edd
 	    n = rfbssl_read(cl, buf, len);
9b8edd
 	} else {
9b8edd
-            n = read(sock, buf, len);
9b8edd
+            n = rfbReadFromSocket(cl, buf, len);
9b8edd
         }
9b8edd
 #else
9b8edd
-        n = read(sock, buf, len);
9b8edd
+        n = rfbReadFromSocket(cl, buf, len);
9b8edd
 #endif
9b8edd
 
9b8edd
         if (n > 0) {
9b8edd
@@ -645,6 +669,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
9b8edd
 		    continue;
9b8edd
 	    }
9b8edd
 #endif
9b8edd
+
9b8edd
+            if (rfbHasPendingOnSocket(cl))
9b8edd
+                continue;
9b8edd
+
9b8edd
             FD_ZERO(&fds);
9b8edd
             FD_SET(sock, &fds);
9b8edd
             tv.tv_sec = timeout / 1000;
9b8edd
@@ -681,6 +709,18 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len)
9b8edd
     return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait));
9b8edd
 }
9b8edd
 
9b8edd
+int
9b8edd
+rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len)
9b8edd
+{
9b8edd
+    return recv(cl->sock, buf, len, MSG_PEEK);
9b8edd
+}
9b8edd
+
9b8edd
+int
9b8edd
+rfbPeekAtSocket(rfbClientPtr cl, char *buf, int len)
9b8edd
+{
9b8edd
+    cl->peekAtSocket(cl, buf, len);
9b8edd
+}
9b8edd
+
9b8edd
 /*
9b8edd
  * PeekExact peeks at an exact number of bytes from a client.  Returns 1 if
9b8edd
  * those bytes have been read, 0 if the other end has closed, or -1 if an
9b8edd
@@ -701,7 +741,7 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
9b8edd
 	    n = rfbssl_peek(cl, buf, len);
9b8edd
 	else
9b8edd
 #endif
9b8edd
-	    n = recv(sock, buf, len, MSG_PEEK);
9b8edd
+            n = rfbPeekAtSocket(cl, buf, len);
9b8edd
 
9b8edd
         if (n == len) {
9b8edd
 
9b8edd
@@ -757,6 +797,22 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
9b8edd
     return 1;
9b8edd
 }
9b8edd
 
9b8edd
+int
9b8edd
+rfbDefaultWriteToSocket(rfbClientPtr cl,
9b8edd
+			const char *buf,
9b8edd
+			int len)
9b8edd
+{
9b8edd
+    return write(cl->sock, buf, len);
9b8edd
+}
9b8edd
+
9b8edd
+static int
9b8edd
+rfbWriteToSocket(rfbClientPtr cl,
9b8edd
+		 const char *buf,
9b8edd
+		 int len)
9b8edd
+{
9b8edd
+    return cl->writeToSocket(cl, buf, len);
9b8edd
+}
9b8edd
+
9b8edd
 /*
9b8edd
  * WriteExact writes an exact number of bytes to a client.  Returns 1 if
9b8edd
  * those bytes have been written, or -1 if an error occurred (errno is set to
9b8edd
@@ -801,7 +857,7 @@ rfbWriteExact(rfbClientPtr cl,
9b8edd
 	    n = rfbssl_write(cl, buf, len);
9b8edd
 	else
9b8edd
 #endif
9b8edd
-	    n = write(sock, buf, len);
9b8edd
+	    n = rfbWriteToSocket(cl, buf, len);
9b8edd
 
9b8edd
         if (n > 0) {
9b8edd
 
9b8edd
diff --git a/rfb/rfb.h b/rfb/rfb.h
9b8edd
index f982b40..ba9e898 100644
9b8edd
--- a/rfb/rfb.h
9b8edd
+++ b/rfb/rfb.h
9b8edd
@@ -415,6 +415,14 @@ typedef struct sraRegion* sraRegionPtr;
9b8edd
 
9b8edd
 typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
9b8edd
 
9b8edd
+typedef int (*ClientReadFromSocket)(struct _rfbClientRec* cl,
9b8edd
+                                    char *buf, int len);
9b8edd
+typedef int (*ClientPeekAtSocket)(struct _rfbClientRec* cl,
9b8edd
+                                  char *buf, int len);
9b8edd
+typedef rfbBool (*ClientHasPendingOnSocket)(struct _rfbClientRec* cl);
9b8edd
+typedef int (*ClientWriteToSocket)(struct _rfbClientRec* cl,
9b8edd
+                                   const char *buf, int len);
9b8edd
+
9b8edd
 typedef struct _rfbFileTransferData {
9b8edd
   int fd;
9b8edd
   int compressionEnabled;
9b8edd
@@ -696,6 +704,11 @@ typedef struct _rfbClientRec {
9b8edd
     wsCtx     *wsctx;
9b8edd
     char *wspath;                          /* Requests path component */
9b8edd
 #endif
9b8edd
+
9b8edd
+    ClientReadFromSocket readFromSocket;         /* Read data from socket */
9b8edd
+    ClientPeekAtSocket peekAtSocket;             /* Peek at data from socket */
9b8edd
+    ClientHasPendingOnSocket hasPendingOnSocket; /* Peek at data from socket */
9b8edd
+    ClientWriteToSocket writeToSocket;           /* Write data to socket */
9b8edd
 } rfbClientRec, *rfbClientPtr;
9b8edd
 
9b8edd
 /**
9b8edd
@@ -748,8 +761,12 @@ extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
9b8edd
 extern void rfbCloseClient(rfbClientPtr cl);
9b8edd
 extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
9b8edd
 extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
9b8edd
+extern int rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len);
9b8edd
 extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
9b8edd
+extern int rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len);
9b8edd
+extern rfbBool rfbDefaultHasPendingOnSocket(rfbClientPtr cl);
9b8edd
 extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
9b8edd
+extern int rfbDefaultWriteToSocket(rfbClientPtr cl, const char *buf, int len);
9b8edd
 extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
9b8edd
 extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
9b8edd
 extern int rfbConnectToTcpAddr(char* host, int port);
9b8edd
-- 
9b8edd
2.17.1
9b8edd