aboutsummaryrefslogtreecommitdiffstats
path: root/unix/xserver
diff options
context:
space:
mode:
authorTim Waugh <twaugh@redhat.com>2015-03-11 13:12:07 +0000
committerTim Waugh <twaugh@redhat.com>2015-03-13 16:19:50 +0000
commit892d10a705077083489f0ed4861af123433ff811 (patch)
tree45a19cc088a7603eb51f1d9917efd087e0458eda /unix/xserver
parenta85363daa80697bda35c789b9ffca53dc7c3c71b (diff)
downloadtigervnc-892d10a705077083489f0ed4861af123433ff811.tar.gz
tigervnc-892d10a705077083489f0ed4861af123433ff811.zip
Fixed IPv6 support.
The TcpListener constructor now takes a 'struct sockaddr*' instead of a string, and the createTcpListeners function creates TcpListener instances for an address based on the results from getaddrinfo(). The XserverDesktop class now takes a list of TcpListener instances for each of the RFB and HTTP sockets. The TcpListener::closeFd member variable is not used and has been removed.
Diffstat (limited to 'unix/xserver')
-rw-r--r--unix/xserver/hw/vnc/RFBGlue.cc5
-rw-r--r--unix/xserver/hw/vnc/XserverDesktop.cc44
-rw-r--r--unix/xserver/hw/vnc/XserverDesktop.h9
-rw-r--r--unix/xserver/hw/vnc/vncExtInit.cc35
4 files changed, 58 insertions, 35 deletions
diff --git a/unix/xserver/hw/vnc/RFBGlue.cc b/unix/xserver/hw/vnc/RFBGlue.cc
index 53d5bdb0..19338fc7 100644
--- a/unix/xserver/hw/vnc/RFBGlue.cc
+++ b/unix/xserver/hw/vnc/RFBGlue.cc
@@ -187,7 +187,10 @@ int vncGetSocketPort(int fd)
int vncIsTCPPortUsed(int port)
{
try {
- network::TcpListener l(NULL, port);
+ // Attempt to create TCPListeners on that port.
+ // They go out of scope immediately and are destroyed.
+ std::list<network::TcpListener> dummy;
+ network::createTcpListeners (&dummy, 0, port);
} catch (rdr::Exception& e) {
return 0;
}
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index 54e09cb5..165afbb6 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -91,14 +91,14 @@ public:
XserverDesktop::XserverDesktop(int screenIndex_,
- network::TcpListener* listener_,
- network::TcpListener* httpListener_,
+ std::list<network::TcpListener> listeners_,
+ std::list<network::TcpListener> httpListeners_,
const char* name, const rfb::PixelFormat &pf,
int width, int height,
void* fbptr, int stride)
: screenIndex(screenIndex_),
server(0), httpServer(0),
- listener(listener_), httpListener(httpListener_),
+ listeners(listeners_), httpListeners(httpListeners_),
deferredUpdateTimerSet(false), directFbptr(true),
queryConnectId(0)
{
@@ -108,7 +108,7 @@ XserverDesktop::XserverDesktop(int screenIndex_,
setFramebuffer(width, height, fbptr, stride);
server->setQueryConnectionHandler(this);
- if (httpListener)
+ if (!httpListeners.empty ())
httpServer = new FileHTTPServer(this);
}
@@ -222,7 +222,7 @@ char* XserverDesktop::substitute(const char* varName)
}
if (strcmp(varName, "$PORT") == 0) {
char* str = new char[10];
- sprintf(str, "%d", listener ? listener->getMyPort() : 0);
+ sprintf(str, "%d", listeners.empty () ? 0 : (*listeners.begin ()).getMyPort());
return str;
}
if (strcmp(varName, "$WIDTH") == 0) {
@@ -393,14 +393,18 @@ void XserverDesktop::readBlockHandler(fd_set* fds, struct timeval ** timeout)
// Add all sockets we want read events for, after purging
// any closed sockets.
- if (listener)
- FD_SET(listener->getFd(), fds);
- if (httpListener)
- FD_SET(httpListener->getFd(), fds);
+ for (std::list<network::TcpListener>::iterator i = listeners.begin();
+ i != listeners.end();
+ i++)
+ FD_SET((*i).getFd(), fds);
+ for (std::list<network::TcpListener>::iterator i = httpListeners.begin();
+ i != httpListeners.end();
+ i++)
+ FD_SET((*i).getFd(), fds);
std::list<Socket*> sockets;
- server->getSockets(&sockets);
std::list<Socket*>::iterator i;
+ server->getSockets(&sockets);
for (i = sockets.begin(); i != sockets.end(); i++) {
int fd = (*i)->getFd();
if ((*i)->isShutdown()) {
@@ -452,20 +456,24 @@ void XserverDesktop::readWakeupHandler(fd_set* fds, int nfds)
// First check for file descriptors with something to do
if (nfds >= 1) {
- if (listener) {
- if (FD_ISSET(listener->getFd(), fds)) {
- FD_CLR(listener->getFd(), fds);
- Socket* sock = listener->accept();
+ for (std::list<network::TcpListener>::iterator i = listeners.begin();
+ i != listeners.end();
+ i++) {
+ if (FD_ISSET((*i).getFd(), fds)) {
+ FD_CLR((*i).getFd(), fds);
+ Socket* sock = (*i).accept();
sock->outStream().setBlocking(false);
server->addSocket(sock);
vlog.debug("new client, sock %d",sock->getFd());
}
}
- if (httpListener) {
- if (FD_ISSET(httpListener->getFd(), fds)) {
- FD_CLR(httpListener->getFd(), fds);
- Socket* sock = httpListener->accept();
+ for (std::list<network::TcpListener>::iterator i = httpListeners.begin();
+ i != httpListeners.end();
+ i++) {
+ if (FD_ISSET((*i).getFd(), fds)) {
+ FD_CLR((*i).getFd(), fds);
+ Socket* sock = (*i).accept();
sock->outStream().setBlocking(false);
httpServer->addSocket(sock);
vlog.debug("new http client, sock %d",sock->getFd());
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
index 7dcaa29e..6909a766 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -50,8 +50,9 @@ class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
public rfb::VNCServerST::QueryConnectionHandler {
public:
- XserverDesktop(int screenIndex, network::TcpListener* listener,
- network::TcpListener* httpListener_,
+ XserverDesktop(int screenIndex,
+ std::list<network::TcpListener> listeners_,
+ std::list<network::TcpListener> httpListeners_,
const char* name, const rfb::PixelFormat &pf,
int width, int height, void* fbptr, int stride);
virtual ~XserverDesktop();
@@ -112,8 +113,8 @@ private:
int screenIndex;
rfb::VNCServerST* server;
rfb::HTTPServer* httpServer;
- network::TcpListener* listener;
- network::TcpListener* httpListener;
+ std::list<network::TcpListener> listeners;
+ std::list<network::TcpListener> httpListeners;
bool deferredUpdateTimerSet;
bool directFbptr;
struct timeval dixTimeout;
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
index 22777839..e307e319 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -134,33 +134,44 @@ void vncExtensionInit(void)
for (int scr = 0; scr < vncGetScreenCount(); scr++) {
if (!desktop[scr]) {
- network::TcpListener* listener = 0;
- network::TcpListener* httpListener = 0;
+ std::list<network::TcpListener> listeners;
+ std::list<network::TcpListener> httpListeners;
if (scr == 0 && vncInetdSock != -1) {
if (network::TcpSocket::isSocket(vncInetdSock) &&
!network::TcpSocket::isConnected(vncInetdSock))
{
- listener = new network::TcpListener(NULL, 0, 0, vncInetdSock, true);
+ listeners.push_back (network::TcpListener(vncInetdSock));
vlog.info("inetd wait");
}
} else {
+ const char *addr = interface;
int port = rfbport;
if (port == 0) port = 5900 + atoi(vncGetDisplay());
port += 1000 * scr;
- if (strcasecmp(interface, "all") == 0)
- listener = new network::TcpListener(NULL, port, localhostOnly);
+ if (strcasecmp(addr, "all") == 0)
+ addr = 0;
+ if (localhostOnly)
+ network::createLocalTcpListeners(&listeners, port);
else
- listener = new network::TcpListener(interface, port, localhostOnly);
+ network::createTcpListeners(&listeners, addr, port);
+
vlog.info("Listening for VNC connections on %s interface(s), port %d",
- (const char*)interface, port);
+ localhostOnly ? "local" : (const char*)interface,
+ port);
+
CharArray httpDirStr(httpDir.getData());
if (httpDirStr.buf[0]) {
port = httpPort;
if (port == 0) port = 5800 + atoi(vncGetDisplay());
port += 1000 * scr;
- httpListener = new network::TcpListener(interface, port, localhostOnly);
+ if (localhostOnly)
+ network::createLocalTcpListeners(&httpListeners, port);
+ else
+ network::createTcpListeners(&httpListeners, addr, port);
+
vlog.info("Listening for HTTP connections on %s interface(s), port %d",
- (const char*)interface, port);
+ localhostOnly ? "local" : (const char*)interface,
+ port);
}
}
@@ -168,8 +179,8 @@ void vncExtensionInit(void)
PixelFormat pf = vncGetPixelFormat(scr);
desktop[scr] = new XserverDesktop(scr,
- listener,
- httpListener,
+ listeners,
+ httpListeners,
desktopNameStr.buf,
pf,
vncGetScreenWidth(scr),
@@ -178,7 +189,7 @@ void vncExtensionInit(void)
vncFbstride[scr]);
vlog.info("created VNC server for screen %d", scr);
- if (scr == 0 && vncInetdSock != -1 && !listener) {
+ if (scr == 0 && vncInetdSock != -1 && listeners.empty()) {
network::Socket* sock = new network::TcpSocket(vncInetdSock);
desktop[scr]->addClient(sock, false);
vlog.info("added inetd sock");