Commit a2ad6175 authored by Vic Lee's avatar Vic Lee Committed by Johannes Schindelin

Add UltraVNC Repeater support in libvncclient

[jes: adjusted coding style, made sure port is initialized correctly]
Signed-off-by: 's avatarVic Lee <llyzs@163.com>
Signed-off-by: 's avatarJohannes Schindelin <johannes.schindelin@gmx.de>
parent 909683fd
...@@ -415,6 +415,51 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) ...@@ -415,6 +415,51 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
return SetNonBlocking(client->sock); 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 rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key); extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
......
...@@ -120,6 +120,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, ...@@ -120,6 +120,9 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->serverHost=strdup(""); client->serverHost=strdup("");
client->serverPort=5900; client->serverPort=5900;
client->destHost = NULL;
client->destPort = 5900;
client->CurrentKeyboardLedState = 0; client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
...@@ -202,8 +205,15 @@ static rfbBool rfbInitConnection(rfbClient* client) ...@@ -202,8 +205,15 @@ static rfbBool rfbInitConnection(rfbClient* client)
given VNC server */ given VNC server */
if (!client->listenSpecified) { 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; return FALSE;
} else {
if (!ConnectToRFBServer(client,client->serverHost,client->serverPort))
return FALSE;
}
} }
/* Initialise the VNC connection, including reading the password */ /* Initialise the VNC connection, including reading the password */
...@@ -278,6 +288,19 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { ...@@ -278,6 +288,19 @@ rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) {
} else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) { } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) {
client->appData.scaleSetting = atoi(argv[i+1]); client->appData.scaleSetting = atoi(argv[i+1]);
j+=2; 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 { } else {
char* colon=strchr(argv[i],':'); char* colon=strchr(argv[i],':');
...@@ -342,6 +365,8 @@ void rfbClientCleanup(rfbClient* client) { ...@@ -342,6 +365,8 @@ void rfbClientCleanup(rfbClient* client) {
close(client->listenSock); close(client->listenSock);
free(client->desktopName); free(client->desktopName);
free(client->serverHost); free(client->serverHost);
if (client->destHost)
free(client->destHost);
if (client->clientAuthSchemes) if (client->clientAuthSchemes)
free(client->clientAuthSchemes); free(client->clientAuthSchemes);
free(client); free(client);
......
...@@ -309,6 +309,10 @@ typedef struct _rfbClient { ...@@ -309,6 +309,10 @@ typedef struct _rfbClient {
/* The 0-terminated security types supported by the client. /* The 0-terminated security types supported by the client.
* Set by function SetClientAuthSchemes() */ * Set by function SetClientAuthSchemes() */
uint32_t *clientAuthSchemes; uint32_t *clientAuthSchemes;
/* When the server is a repeater, this specifies the final destination */
char *destHost;
int destPort;
} rfbClient; } rfbClient;
/* cursor.c */ /* cursor.c */
...@@ -326,6 +330,7 @@ extern rfbBool rfbEnableClientLogging; ...@@ -326,6 +330,7 @@ extern rfbBool rfbEnableClientLogging;
typedef void (*rfbClientLogProc)(const char *format, ...); typedef void (*rfbClientLogProc)(const char *format, ...);
extern rfbClientLogProc rfbClientLog,rfbClientErr; extern rfbClientLogProc rfbClientLog,rfbClientErr;
extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); 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 void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size);
extern rfbBool InitialiseRFBConnection(rfbClient* client); extern rfbBool InitialiseRFBConnection(rfbClient* client);
extern rfbBool SetFormatAndEncodings(rfbClient* client); extern rfbBool SetFormatAndEncodings(rfbClient* client);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment