From a2ad61755fb01031193bf89421f6bc2c8e706165 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 15 Jan 2010 13:47:43 +0800 Subject: [PATCH 1/3] Add UltraVNC Repeater support in libvncclient [jes: adjusted coding style, made sure port is initialized correctly] Signed-off-by: Vic Lee Signed-off-by: Johannes Schindelin --- libvncclient/rfbproto.c | 45 ++++++++++++++++++++++++++++++++++++++++ libvncclient/vncviewer.c | 27 +++++++++++++++++++++++- rfb/rfbclient.h | 5 +++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 83cfbf9..8aa6348 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -415,6 +415,51 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) return SetNonBlocking(client->sock); } +/* + * ConnectToRFBRepeater. + */ + +rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort) +{ + unsigned int host; + rfbProtocolVersionMsg pv; + int major,minor; + char tmphost[250]; + + if (!StringToIPAddr(repeaterHost, &host)) { + rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost); + return FALSE; + } + + client->sock = ConnectClientToTcpAddr(host, repeaterPort); + + if (client->sock < 0) { + rfbClientLog("Unable to connect to VNC repeater\n"); + return FALSE; + } + + if (!SetNonBlocking(client->sock)) + return FALSE; + + if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) + return FALSE; + pv[sz_rfbProtocolVersionMsg] = 0; + + /* UltraVNC repeater always report version 000.000 to identify itself */ + if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) { + rfbClientLog("Not a valid VNC repeater (%s)\n",pv); + return FALSE; + } + + rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor); + + snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort); + if (!WriteToRFBServer(client, tmphost, sizeof(tmphost))) + return FALSE; + + return TRUE; +} + extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd); extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key); diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 111a7f6..fa150cd 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -119,6 +119,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, client->programName=""; client->serverHost=strdup(""); client->serverPort=5900; + + client->destHost = NULL; + client->destPort = 5900; client->CurrentKeyboardLedState = 0; client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; @@ -202,8 +205,15 @@ static rfbBool rfbInitConnection(rfbClient* client) given VNC server */ if (!client->listenSpecified) { - if (!client->serverHost || !ConnectToRFBServer(client,client->serverHost,client->serverPort)) + if (!client->serverHost) return FALSE; + if (client->destHost) { + if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort)) + return FALSE; + } else { + if (!ConnectToRFBServer(client,client->serverHost,client->serverPort)) + return FALSE; + } } /* Initialise the VNC connection, including reading the password */ @@ -278,6 +288,19 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) { client->appData.scaleSetting = atoi(argv[i+1]); j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) { + char* colon=strchr(argv[i+1],':'); + + if(client->destHost) + free(client->destHost); + client->destPort = 5900; + + client->destHost = strdup(argv[i+1]); + if(colon) { + client->destHost[(int)(colon-argv[i+1])] = '\0'; + client->destPort = atoi(colon+1); + } + j+=2; } else { char* colon=strchr(argv[i],':'); @@ -342,6 +365,8 @@ void rfbClientCleanup(rfbClient* client) { close(client->listenSock); free(client->desktopName); free(client->serverHost); + if (client->destHost) + free(client->destHost); if (client->clientAuthSchemes) free(client->clientAuthSchemes); free(client); diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index a82ea22..bc4ec14 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -309,6 +309,10 @@ typedef struct _rfbClient { /* The 0-terminated security types supported by the client. * Set by function SetClientAuthSchemes() */ uint32_t *clientAuthSchemes; + + /* When the server is a repeater, this specifies the final destination */ + char *destHost; + int destPort; } rfbClient; /* cursor.c */ @@ -326,6 +330,7 @@ extern rfbBool rfbEnableClientLogging; typedef void (*rfbClientLogProc)(const char *format, ...); extern rfbClientLogProc rfbClientLog,rfbClientErr; extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); +extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort); extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size); extern rfbBool InitialiseRFBConnection(rfbClient* client); extern rfbBool SetFormatAndEncodings(rfbClient* client); From d640c94d701d2decac8eeb5d56ed84f73041f85f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 16 Jan 2010 11:29:33 +0100 Subject: [PATCH 2/3] LibVNCClient: make sure that the port is initialized correctly. While at it, adjust coding style. Signed-off-by: Johannes Schindelin --- libvncclient/vncviewer.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index fa150cd..155bb47 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -306,16 +306,17 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { if(client->serverHost) free(client->serverHost); + client->serverPort = 5900; if(colon) { - client->serverHost=strdup(argv[i]); - client->serverHost[(int)(colon-argv[i])]='\0'; - client->serverPort=atoi(colon+1); + client->serverHost = strdup(argv[i]); + client->serverHost[(int)(colon-argv[i])] = '\0'; + client->serverPort = atoi(colon+1); } else { - client->serverHost=strdup(argv[i]); + client->serverHost = strdup(argv[i]); } - if(client->serverPort>=0 && client->serverPort<5900) - client->serverPort+=5900; + if(client->serverPort >= 0 && client->serverPort < 5900) + client->serverPort += 5900; } /* purge arguments */ if (j>i) { From 6b2b3b8213bbe95182c91df419e0562e85f36bc0 Mon Sep 17 00:00:00 2001 From: Christian Beier Date: Fri, 22 Jan 2010 16:22:20 +0100 Subject: [PATCH 3/3] libvncclient/vncviewer.c: don't set serverPort in rfbInitClient(). The serverPort member is already set in rfbGetClient(), if we set it again in rfbInitClient(), this breaks playing of vncrec files (this relies on serverPort set to -1). Signed-off-by: Christian Beier Signed-off-by: Johannes Schindelin --- libvncclient/vncviewer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 155bb47..34de15d 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -306,7 +306,6 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { if(client->serverHost) free(client->serverHost); - client->serverPort = 5900; if(colon) { client->serverHost = strdup(argv[i]);