Commit 0797e42a authored by Christian Beier's avatar Christian Beier

IP QoS support in libvncclient.

This enables setting the DSCP/Traffic Class field of IP/IPv6 packets
sent by a client. For example starting a client with -qosdscp 184
marks all outgoing traffic for expedited forwarding.

Implementation for Win32 is still a TODO, though. See
http://betelco.blogspot.com/2009/03/dscp-marking-under-windows-at.html
for an overview of the Win32 QoS API mess...
parent c0373e9c
......@@ -14,6 +14,7 @@ java vncviewer doesn't do colour cursors?
make corre work again (libvncclient or libvncserver?)
teach SDLvncviewer about CopyRect...
implement "-record" in libvncclient
implement QoS for Windows in libvncclient
later:
------
......
......@@ -421,6 +421,9 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
return FALSE;
}
if(client->QoS_DSCP && !SetDSCP(client->sock, client->QoS_DSCP))
return FALSE;
return SetNonBlocking(client->sock);
}
......
......@@ -566,6 +566,55 @@ SetNonBlocking(int sock)
}
/*
* SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field
*/
rfbBool
SetDSCP(int sock, int dscp)
{
#ifdef WIN32
rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n");
return TRUE;
#else
int level, cmd;
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
if(getsockname(sock, &addr, &addrlen) != 0) {
rfbClientErr("Setting socket QoS failed while getting socket address: %s\n",strerror(errno));
return FALSE;
}
switch(addr.sa_family)
{
#ifdef LIBVNCSERVER_IPv6
case AF_INET6:
level = IPPROTO_IPV6;
cmd = IPV6_TCLASS;
break;
#endif
case AF_INET:
level = IPPROTO_IP;
cmd = IP_TOS;
break;
default:
rfbClientErr("Setting socket QoS failed: Not bound to IP address");
return FALSE;
}
if(setsockopt(sock, level, cmd, (void*)&dscp, sizeof(dscp)) != 0) {
rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno));
return FALSE;
}
return TRUE;
#endif
}
/*
* StringToIPAddr - convert a host string to an IP address.
*/
......
......@@ -186,6 +186,7 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->Bell = Dummy;
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
client->QoS_DSCP = 0;
client->authScheme = 0;
client->subAuthScheme = 0;
......@@ -288,6 +289,9 @@ 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], "-qosdscp") == 0) {
client->QoS_DSCP = atoi(argv[i+1]);
j+=2;
} else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) {
char* colon=strchr(argv[i+1],':');
......
......@@ -313,6 +313,9 @@ typedef struct _rfbClient {
/* When the server is a repeater, this specifies the final destination */
char *destHost;
int destPort;
/* the QoS IP DSCP for this client */
int QoS_DSCP;
} rfbClient;
/* cursor.c */
......@@ -388,6 +391,7 @@ extern int ConnectClientToTcpAddr6(const char *hostname, int port);
extern int ConnectClientToUnixSock(const char *sockFile);
extern int AcceptTcpConnection(int listenSock);
extern rfbBool SetNonBlocking(int sock);
extern rfbBool SetDSCP(int sock, int dscp);
extern rfbBool StringToIPAddr(const char *str, unsigned int *addr);
extern rfbBool SameMachine(int sock);
......
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