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