Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
tigervnc.5211
U_tigervnc-fixed-ipv6-support.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_tigervnc-fixed-ipv6-support.patch of Package tigervnc.5211
Author: Tim Waugh <twaugh@redhat.com> Subject: Fixed IPv6 support. Patch-Mainline: Upstream Git-commit: 892d10a705077083489f0ed4861af123433ff811 Referenes: bnc#952057 Signed-off-by: Michal Srb <msrb@suse.com> Index: tigervnc-1.4.3/common/network/TcpSocket.cxx =================================================================== --- tigervnc-1.4.3.orig/common/network/TcpSocket.cxx +++ tigervnc-1.4.3/common/network/TcpSocket.cxx @@ -35,7 +35,6 @@ #include <netinet/in.h> #include <netinet/tcp.h> #include <netdb.h> -#include <unistd.h> #include <errno.h> #include <string.h> #include <signal.h> @@ -43,6 +42,7 @@ #endif #include <stdlib.h> +#include <unistd.h> #include <network/TcpSocket.h> #include <rfb/util.h> #include <rfb/LogWriter.h> @@ -248,16 +248,17 @@ char* TcpSocket::getPeerAddress() { return rfb::strDup(""); } -#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_PTON) +#if defined(HAVE_GETADDRINFO) if (sa.u.sa.sa_family == AF_INET6) { char buffer[INET6_ADDRSTRLEN + 2]; - const char *name; + int ret; buffer[0] = '['; - name = inet_ntop(sa.u.sa.sa_family, &sa.u.sin6.sin6_addr, - buffer + 1, sizeof(buffer) - 2); - if (name == NULL) { + ret = getnameinfo(&sa.u.sa, sizeof(sa.u.sin6), + buffer + 1, sizeof(buffer) - 2, NULL, 0, + NI_NUMERICHOST); + if (ret != 0) { vlog.error("unable to convert peer name to a string"); return rfb::strDup(""); } @@ -400,136 +401,77 @@ int TcpSocket::getSockPort(int sock) } } +TcpListener::TcpListener(int sock) +{ + fd = sock; +} + +TcpListener::TcpListener(const TcpListener& other) +{ + fd = dup (other.fd); + // Hope TcpListener::shutdown(other) doesn't get called... +} -TcpListener::TcpListener(const char *listenaddr, int port, bool localhostOnly, - int sock, bool close_) : closeFd(close_) +TcpListener& TcpListener::operator= (const TcpListener& other) { - if (sock != -1) { - fd = sock; - return; + if (this != &other) + { + closesocket (fd); + fd = dup (other.fd); + // Hope TcpListener::shutdown(other) doesn't get called... } + return *this; +} - bool use_ipv6; - int af; -#ifdef HAVE_GETADDRINFO - use_ipv6 = true; - af = AF_INET6; -#else - use_ipv6 = false; - af = AF_INET; -#endif +TcpListener::TcpListener(const struct sockaddr *listenaddr, + socklen_t listenaddrlen) +{ + int one = 1; + vnc_sockaddr_t sa; + int sock; initSockets(); - if ((fd = socket(af, SOCK_STREAM, 0)) < 0) { - // - Socket creation failed - if (use_ipv6) { - // - Trying to make an IPv6-capable socket failed - try again, IPv4-only - use_ipv6 = false; - af = AF_INET; - fd = socket(af, SOCK_STREAM, 0); - } - if (fd < 0) - throw SocketException("unable to create listening socket", errorNumber); - } else { - // - Socket creation succeeded - if (use_ipv6) { + + if ((sock = socket (listenaddr->sa_family, SOCK_STREAM, 0)) < 0) + throw SocketException("unable to create listening socket", errorNumber); + + memcpy (&sa, listenaddr, listenaddrlen); #ifdef IPV6_V6ONLY - // - We made an IPv6-capable socket, and we need it to do IPv4 too - int opt = 0; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); -#else - vlog.error("IPV6_V6ONLY support is missing. " - "IPv4 clients may not be able to connect."); -#endif - } + if (listenaddr->sa_family == AF_INET6) { + if (setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&one, sizeof(one))) + throw SocketException("unable to set IPV6_V6ONLY", errorNumber); + } +#endif /* defined(IPV6_V6ONLY) */ + + if (bind(sock, &sa.u.sa, listenaddrlen) == -1) { + closesocket(sock); + throw SocketException("failed to bind socket", errorNumber); } #ifndef WIN32 // - By default, close the socket on exec() - fcntl(fd, F_SETFD, FD_CLOEXEC); + fcntl(sock, F_SETFD, FD_CLOEXEC); - int one = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char *)&one, sizeof(one)) < 0) { + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (char *)&one, sizeof(one)) < 0) { int e = errorNumber; - closesocket(fd); + closesocket(sock); throw SocketException("unable to create listening socket", e); } #endif - // - Bind it to the desired port - struct sockaddr_in addr; -#ifdef HAVE_GETADDRINFO - struct sockaddr_in6 addr6; -#endif - struct sockaddr *sa; - int sa_len; - -#ifdef HAVE_GETADDRINFO - if (use_ipv6) { - memset(&addr6, 0, (sa_len = sizeof(addr6))); - addr6.sin6_family = af; - addr6.sin6_port = htons(port); - - if (localhostOnly) - addr6.sin6_addr = in6addr_loopback; - else if (listenaddr != NULL) { -#ifdef HAVE_INET_PTON - if (inet_pton(AF_INET6, listenaddr, &addr6.sin6_addr) != 1) - use_ipv6 = false; -#else - // Unable to parse without inet_pton - use_ipv6 = false; -#endif - } - - if (use_ipv6) - sa = (struct sockaddr *)&addr6; - } -#endif - - if (!use_ipv6) { - memset(&addr, 0, (sa_len = sizeof(addr))); - addr.sin_family = af; - addr.sin_port = htons(port); - - if (localhostOnly) { - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - } else if (listenaddr != NULL) { -#ifdef HAVE_INET_ATON - if (inet_aton(listenaddr, &addr.sin_addr) == 0) -#else - /* Some systems (e.g. Windows) do not have inet_aton, sigh */ - if ((addr.sin_addr.s_addr = inet_addr(listenaddr)) == INADDR_NONE) -#endif - { - closesocket(fd); - throw Exception("invalid network interface address: %s", listenaddr); - } - } else - /* Bind to 0.0.0.0 by default. */ - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - sa = (struct sockaddr *)&addr; - } - - addr.sin_port = htons(port); - if (bind(fd, sa, sa_len) < 0) { - int e = errorNumber; - closesocket(fd); - throw SocketException("unable to bind listening socket", e); - } - // - Set it to be a listening socket - if (listen(fd, 5) < 0) { + if (listen(sock, 5) < 0) { int e = errorNumber; - closesocket(fd); + closesocket(sock); throw SocketException("unable to set socket to listening mode", e); } + + fd = sock; } TcpListener::~TcpListener() { - if (closeFd) closesocket(fd); + closesocket(fd); } void TcpListener::shutdown() @@ -567,50 +509,141 @@ TcpListener::accept() { return s; } -void TcpListener::getMyAddresses(std::list<char*>* result) { -#if defined(HAVE_GETADDRINFO) && defined(HAVE_INET_PTON) +int TcpListener::getMyPort() { + return TcpSocket::getSockPort(getFd()); +} + + +void network::createLocalTcpListeners(std::list<TcpListener> *listeners, + int port) +{ + std::list<TcpListener> new_listeners; vnc_sockaddr_t sa; +#ifdef HAVE_GETADDRINFO + sa.u.sin6.sin6_family = AF_INET6; + sa.u.sin6.sin6_port = htons (port); + sa.u.sin6.sin6_addr = in6addr_loopback; + try { + new_listeners.push_back (TcpListener (&sa.u.sa, sizeof (sa.u.sin6))); + } catch (SocketException& e) { + // Ignore this if it is due to lack of address family support on + // the interface or on the system + if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) + // Otherwise, report the error + throw; + } +#endif /* HAVE_GETADDRINFO */ + sa.u.sin.sin_family = AF_INET; + sa.u.sin.sin_port = htons (port); + sa.u.sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + try { + new_listeners.push_back (TcpListener (&sa.u.sa, sizeof (sa.u.sin))); + } catch (SocketException& e) { + // Ignore this if it is due to lack of address family support on + // the interface or on the system + if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) + // Otherwise, report the error + throw; + } + + if (new_listeners.empty ()) + throw SocketException("createLocalTcpListeners: no addresses available", + EADDRNOTAVAIL); + + listeners->splice (listeners->end(), new_listeners); +} + +void network::createTcpListeners(std::list<TcpListener> *listeners, + const char *addr, + int port) +{ + std::list<TcpListener> new_listeners; + +#ifdef HAVE_GETADDRINFO struct addrinfo *ai, *current, hints; + char service[16]; memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; - if ((getaddrinfo(NULL, NULL, &hints, &ai)) != 0) - return; - - for (current= ai; current != NULL; current = current->ai_next) { - if (current->ai_family != AF_INET && current->ai_family != AF_INET6) - continue; + snprintf (service, sizeof (service) - 1, "%d", port); + service[sizeof (service) - 1] = '\0'; + if ((getaddrinfo(addr, service, &hints, &ai)) != 0) + throw rdr::SystemException("getaddrinfo", errorNumber); - char *addr = new char[INET6_ADDRSTRLEN]; - inet_ntop(current->ai_family, current->ai_addr, addr, INET6_ADDRSTRLEN); - result->push_back(addr); + for (current = ai; current != NULL; current = current->ai_next) { + try { + new_listeners.push_back(TcpListener (current->ai_addr, + current->ai_addrlen)); + } catch (SocketException& e) { + // Ignore this if it is due to lack of address family support on + // the interface or on the system + if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) { + // Otherwise, report the error + freeaddrinfo(ai); + throw; + } + } } freeaddrinfo(ai); #else - char hostname[HOST_NAME_MAX]; - if (gethostname(hostname, HOST_NAME_MAX) < 0) - throw rdr::SystemException("gethostname", errorNumber); - const hostent* addrs = gethostbyname(hostname); - if (addrs == 0) - throw rdr::SystemException("gethostbyname", errorNumber); - if (addrs->h_addrtype != AF_INET) - throw rdr::Exception("getMyAddresses: bad family"); - for (int i=0; addrs->h_addr_list[i] != 0; i++) { - const char* addrC = inet_ntoa(*((struct in_addr*)addrs->h_addr_list[i])); - char* addr = new char[strlen(addrC)+1]; - strcpy(addr, addrC); - result->push_back(addr); + const hostent* addrs; + if (addr) { + /* Bind to specific address */ + addrs = gethostbyname(addr); + if (addrs == 0) + throw rdr::SystemException("gethostbyname", errorNumber); + if (addrs->h_addrtype != AF_INET) + throw rdr::Exception("createTcpListeners: bad family"); + for (int i=0; addrs->h_addr_list[i] != 0; i++) { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + memcpy (&addr.sin_addr, addrs->h_addr_list[i], addrs->h_length); + addr.sin_port = htons(port); + try { + new_listeners.push_back(TcpListener ((struct sockaddr*)&addr, + addrs->h_length)); + } catch (SocketException& e) { + // Ignore this if it is due to lack of address family support + // on the interface or on the system + if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) { + // Otherwise, report the error + freeaddrinfo(ai); + throw; + } + } + } + } else { + /* Bind to any address */ + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + try { + new_listeners.push_back(TcpListener ((struct sockaddr*)&addr, + sizeof (struct sockaddr_in))); + } catch (SocketException& e) { + // Ignore this if it is due to lack of address family support on + // the interface or on the system + if (e.err != EADDRNOTAVAIL && e.err != EAFNOSUPPORT) { + // Otherwise, report the error + freeaddrinfo(ai); + throw; + } + } } -#endif /* defined(HAVE_GETADDRINFO) && defined(HAVE_INET_PTON) */ -} +#endif /* defined(HAVE_GETADDRINFO) */ -int TcpListener::getMyPort() { - return TcpSocket::getSockPort(getFd()); + if (new_listeners.empty ()) + throw SocketException("createTcpListeners: no addresses available", + EADDRNOTAVAIL); + + listeners->splice (listeners->end(), new_listeners); } Index: tigervnc-1.4.3/common/network/TcpSocket.h =================================================================== --- tigervnc-1.4.3.orig/common/network/TcpSocket.h +++ tigervnc-1.4.3/common/network/TcpSocket.h @@ -29,6 +29,7 @@ #define __NETWORK_TCP_SOCKET_H__ #include <network/Socket.h> +#include <sys/socket.h> #include <list> @@ -66,18 +67,16 @@ namespace network { class TcpListener : public SocketListener { public: - TcpListener(const char *listenaddr, int port, bool localhostOnly=false, - int sock=-1, bool close=true); + TcpListener(const struct sockaddr *listenaddr, socklen_t listenaddrlen); + TcpListener(int sock); + TcpListener(const TcpListener& other); + TcpListener& operator= (const TcpListener& other); virtual ~TcpListener(); virtual void shutdown(); virtual Socket* accept(); - void getMyAddresses(std::list<char*>* addrs); int getMyPort(); - - private: - bool closeFd; }; class TcpFilter : public ConnectionFilter { @@ -99,6 +98,12 @@ namespace network { std::list<Pattern> filter; }; + void createLocalTcpListeners(std::list<TcpListener> *listeners, + int port); + void createTcpListeners(std::list<TcpListener> *listeners, + const char *addr, + int port); + } #endif // __NETWORK_TCP_SOCKET_H__ Index: tigervnc-1.4.3/unix/x0vncserver/x0vncserver.cxx =================================================================== --- tigervnc-1.4.3.orig/unix/x0vncserver/x0vncserver.cxx +++ tigervnc-1.4.3/unix/x0vncserver/x0vncserver.cxx @@ -475,6 +475,8 @@ int main(int argc, char** argv) signal(SIGINT, CleanupSignalHandler); signal(SIGTERM, CleanupSignalHandler); + std::list<TcpListener> listeners; + try { TXWindow::init(dpy,"x0vncserver"); Geometry geo(DisplayWidth(dpy, DefaultScreen(dpy)), @@ -489,13 +491,16 @@ int main(int argc, char** argv) QueryConnHandler qcHandler(dpy, &server); server.setQueryConnectionHandler(&qcHandler); - TcpListener listener(NULL, (int)rfbport); + createTcpListeners(&listeners, 0, (int)rfbport); vlog.info("Listening on port %d", (int)rfbport); const char *hostsData = hostsFile.getData(); FileTcpFilter fileTcpFilter(hostsData); if (strlen(hostsData) != 0) - listener.setFilter(&fileTcpFilter); + for (std::list<TcpListener>::iterator i = listeners.begin(); + i != listeners.end(); + i++) + (*i).setFilter(&fileTcpFilter); delete[] hostsData; PollingScheduler sched((int)pollingCycle, (int)maxProcessorUsage); @@ -511,7 +516,11 @@ int main(int argc, char** argv) FD_ZERO(&rfds); FD_SET(ConnectionNumber(dpy), &rfds); - FD_SET(listener.getFd(), &rfds); + for (std::list<TcpListener>::iterator i = listeners.begin(); + i != listeners.end(); + i++) + FD_SET((*i).getFd(), &rfds); + server.getSockets(&sockets); int clients_connected = 0; for (i = sockets.begin(); i != sockets.end(); i++) { @@ -556,12 +565,16 @@ int main(int argc, char** argv) } // Accept new VNC connections - if (FD_ISSET(listener.getFd(), &rfds)) { - Socket* sock = listener.accept(); - if (sock) { - server.addSocket(sock); - } else { - vlog.status("Client connection rejected"); + for (std::list<TcpListener>::iterator i = listeners.begin(); + i != listeners.end(); + i++) { + if (FD_ISSET((*i).getFd(), &rfds)) { + Socket* sock = (*i).accept(); + if (sock) { + server.addSocket(sock); + } else { + vlog.status("Client connection rejected"); + } } } Index: tigervnc-1.4.3/unix/xserver/hw/vnc/XserverDesktop.cc =================================================================== --- tigervnc-1.4.3.orig/unix/xserver/hw/vnc/XserverDesktop.cc +++ tigervnc-1.4.3/unix/xserver/hw/vnc/XserverDesktop.cc @@ -133,13 +133,13 @@ public: XserverDesktop::XserverDesktop(ScreenPtr pScreen_, - network::TcpListener* listener_, - network::TcpListener* httpListener_, + std::list<network::TcpListener> listeners_, + std::list<network::TcpListener> httpListeners_, const char* name, const rfb::PixelFormat &pf, void* fbptr, int stride) : pScreen(pScreen_), server(0), httpServer(0), - listener(listener_), httpListener(httpListener_), + listeners(listeners_), httpListeners(httpListeners_), deferredUpdateTimerSet(false), grabbing(false), ignoreHooks_(false), directFbptr(true), queryConnectId(0) @@ -150,7 +150,7 @@ XserverDesktop::XserverDesktop(ScreenPtr setFramebuffer(pScreen->width, pScreen->height, fbptr, stride); server->setQueryConnectionHandler(this); - if (httpListener) + if (!httpListeners.empty ()) httpServer = new FileHTTPServer(this); } @@ -292,7 +292,7 @@ char* XserverDesktop::substitute(const c } 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) { @@ -523,14 +523,18 @@ void XserverDesktop::blockHandler(fd_set // 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()) { @@ -582,20 +586,24 @@ void XserverDesktop::wakeupHandler(fd_se // 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()); Index: tigervnc-1.4.3/unix/xserver/hw/vnc/XserverDesktop.h =================================================================== --- tigervnc-1.4.3.orig/unix/xserver/hw/vnc/XserverDesktop.h +++ tigervnc-1.4.3/unix/xserver/hw/vnc/XserverDesktop.h @@ -58,8 +58,9 @@ class XserverDesktop : public rfb::SDesk public rfb::VNCServerST::QueryConnectionHandler { public: - XserverDesktop(ScreenPtr pScreen, network::TcpListener* listener, - network::TcpListener* httpListener_, + XserverDesktop(ScreenPtr pScreen_, + std::list<network::TcpListener> listeners_, + std::list<network::TcpListener> httpListeners_, const char* name, const rfb::PixelFormat &pf, void* fbptr, int stride); virtual ~XserverDesktop(); @@ -127,8 +128,8 @@ private: ScreenPtr pScreen; 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 grabbing; bool ignoreHooks_; Index: tigervnc-1.4.3/unix/xserver/hw/vnc/vncExtInit.cc =================================================================== --- tigervnc-1.4.3.orig/unix/xserver/hw/vnc/vncExtInit.cc +++ tigervnc-1.4.3/unix/xserver/hw/vnc/vncExtInit.cc @@ -223,30 +223,38 @@ void vncExtensionInit() for (int scr = 0; scr < screenInfo.numScreens; 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 { int port = rfbport; if (port == 0) port = 5900 + atoi(display); port += 1000 * scr; - listener = new network::TcpListener(listenaddr, port, localhostOnly); + if (localhostOnly) + network::createLocalTcpListeners(&listeners, port); + else + network::createTcpListeners(&listeners, listenaddr, port); vlog.info("Listening for VNC connections on %s interface(s), port %d", - listenaddr == NULL ? "all" : listenaddr, port); + localhostOnly ? "local" : (listenaddr ? listenaddr : "all"), + port); CharArray httpDirStr(httpDir.getData()); if (httpDirStr.buf[0]) { port = httpPort; if (port == 0) port = 5800 + atoi(display); port += 1000 * scr; - httpListener = new network::TcpListener(listenaddr, port, localhostOnly); + if (localhostOnly) + network::createLocalTcpListeners(&httpListeners, port); + else + network::createTcpListeners(&httpListeners, listenaddr, port); vlog.info("Listening for HTTP connections on %s interface(s), port %d", - listenaddr == NULL ? "all" : listenaddr, port); + localhostOnly ? "local" : (listenaddr ? listenaddr : "all"), + port); } } @@ -254,15 +262,15 @@ void vncExtensionInit() PixelFormat pf = vncGetPixelFormat(screenInfo.screens[scr]); desktop[scr] = new XserverDesktop(screenInfo.screens[scr], - listener, - httpListener, + listeners, + httpListeners, desktopNameStr.buf, pf, vncFbptr[scr], 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"); Index: tigervnc-1.4.3/unix/xserver/hw/vnc/xvnc.cc =================================================================== --- tigervnc-1.4.3.orig/unix/xserver/hw/vnc/xvnc.cc +++ tigervnc-1.4.3/unix/xserver/hw/vnc/xvnc.cc @@ -352,9 +352,12 @@ static bool displayNumFree(int num) { try { - network::TcpListener l(NULL, 6000+num); + // 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, 6000 + num); } catch (rdr::Exception& e) { - return false; + return false; } char file[256]; sprintf(file, "/tmp/.X%d-lock", num); Index: tigervnc-1.4.3/vncviewer/vncviewer.cxx =================================================================== --- tigervnc-1.4.3.orig/vncviewer/vncviewer.cxx +++ tigervnc-1.4.3/vncviewer/vncviewer.cxx @@ -488,15 +488,45 @@ int main(int argc, char** argv) #endif if (listenMode) { + std::list<TcpListener> listeners; try { int port = 5500; if (isdigit(vncServerName[0])) port = atoi(vncServerName); - TcpListener listener(NULL, port); + createTcpListeners(&listeners, 0, port); vlog.info(_("Listening on port %d\n"), port); - sock = listener.accept(); + + /* Wait for a connection */ + while (sock == NULL) { + fd_set rfds; + FD_ZERO(&rfds); + for (std::list<TcpListener>::iterator i = listeners.begin(); + i != listeners.end(); + i++) + FD_SET((*i).getFd(), &rfds); + + int n = select(FD_SETSIZE, &rfds, 0, 0, 0); + if (n < 0) { + if (errno == EINTR) { + vlog.debug("Interrupted select() system call"); + continue; + } else { + throw rdr::SystemException("select", errno); + } + } + + for (std::list<TcpListener>::iterator i = listeners.begin (); + i != listeners.end(); + i++) + if (FD_ISSET((*i).getFd(), &rfds)) { + sock = (*i).accept(); + if (sock) + /* Got a connection */ + break; + } + } } catch (rdr::Exception& e) { vlog.error("%s", e.str()); fl_alert("%s", e.str());
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor