]> source.dussan.org Git - tigervnc.git/commitdiff
The "network" library merged with VNC 4.1.1 code.
authorConstantin Kaplinsky <const@tightvnc.com>
Sun, 16 Apr 2006 06:47:16 +0000 (06:47 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Sun, 16 Apr 2006 06:47:16 +0000 (06:47 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@521 3789f03b-4d11-0410-bbf8-ca57d06f2519

network/Socket.h
network/TcpSocket.cxx
network/TcpSocket.h

index 09d88bec6b8ff9a30976db3fd2c6b266d1eac10a..b93da2ef0d2a1b519e9356f6215188dee32cedc0 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -21,6 +21,7 @@
 #ifndef __NETWORK_SOCKET_H__
 #define __NETWORK_SOCKET_H__
 
+#include <limits.h>
 #include <rdr/FdInStream.h>
 #include <rdr/FdOutStream.h>
 #include <rdr/Exception.h>
@@ -32,9 +33,10 @@ namespace network {
     Socket(int fd)
       : instream(new rdr::FdInStream(fd)),
       outstream(new rdr::FdOutStream(fd)),
-      own_streams(true) {}
+      ownStreams(true), isShutdown_(false),
+      queryConnection(false) {}
     virtual ~Socket() {
-      if (own_streams) {
+      if (ownStreams) {
         delete instream;
         delete outstream;
       }
@@ -42,7 +44,10 @@ namespace network {
     rdr::FdInStream &inStream() {return *instream;}
     rdr::FdOutStream &outStream() {return *outstream;}
     int getFd() {return outstream->getFd();}
-    virtual void shutdown() = 0;
+
+    // if shutdown() is overridden then the override MUST call on to here
+    virtual void shutdown() {isShutdown_ = true;}
+    bool isShutdown() const {return isShutdown_;}
 
     // information about this end of the socket
     virtual char* getMyAddress() = 0; // a string e.g. "192.168.0.1"
@@ -57,19 +62,26 @@ namespace network {
     // Is the remote end on the same machine?
     virtual bool sameMachine() = 0;
 
+    // Was there a "?" in the ConnectionFilter used to accept this Socket?
+    void setRequiresQuery() {queryConnection = true;}
+    bool requiresQuery() const {return queryConnection;}
+
   protected:
-    Socket() : instream(0), outstream(0), own_streams(false) {}
+    Socket() : instream(0), outstream(0), ownStreams(false),
+      isShutdown_(false), queryConnection(false) {}
     Socket(rdr::FdInStream* i, rdr::FdOutStream* o, bool own)
-      : instream(i), outstream(o), own_streams(own) {}
+      : instream(i), outstream(o), ownStreams(own),
+      isShutdown_(false), queryConnection(false) {}
     rdr::FdInStream* instream;
     rdr::FdOutStream* outstream;
-    bool own_streams;
+    bool ownStreams;
+    bool isShutdown_;
+    bool queryConnection;
   };
 
   class ConnectionFilter {
   public:
     virtual bool verifyConnection(Socket* s) = 0;
-    virtual bool queryUserAcceptConnection(Socket*) {return false;}
   };
 
   class SocketListener {
@@ -85,6 +97,7 @@ namespace network {
     // if one is installed.  Otherwise, returns 0.
     virtual Socket* accept() = 0;
 
+    // setFilter() applies the specified filter to all new connections
     void setFilter(ConnectionFilter* f) {filter = f;}
     int getFd() {return fd;}
   protected:
@@ -100,28 +113,34 @@ namespace network {
   public:
     virtual ~SocketServer() {}
 
-    // addClient() tells the server to manage the socket.
-    //   If the server can't manage the socket, it must shutdown() it.
-    virtual void addClient(network::Socket* sock) = 0;
-
-    // processSocketEvent() tells the server there is a socket read event.
-    //   If there is an error, or the socket has been closed/shutdown then
-    //   the server MUST delete the socket AND return false.
-    virtual bool processSocketEvent(network::Socket* sock) = 0;
+    // addSocket() tells the server to serve the Socket.  The caller
+    //   retains ownership of the Socket - the only way for the server
+    //   to discard a Socket is by calling shutdown() on it.
+    //   outgoing is set to true if the socket was created by connecting out
+    //   to another host, or false if the socket was created by accept()ing
+    //   an incoming connection.
+    virtual void addSocket(network::Socket* sock, bool outgoing=false) = 0;
+
+    // removeSocket() tells the server to stop serving the Socket.  The
+    //   caller retains ownership of the Socket - the server must NOT
+    //   delete the Socket!  This call is used mainly to cause per-Socket
+    //   resources to be freed.
+    virtual void removeSocket(network::Socket* sock) = 0;
+
+    // processSocketEvent() tells the server there is a Socket read event.
+    //   The implementation can indicate that the Socket is no longer active
+    //   by calling shutdown() on it.  The caller will then call removeSocket()
+    //   soon after processSocketEvent returns, to allow any pre-Socket
+    //   resources to be tidied up.
+    virtual void processSocketEvent(network::Socket* sock) = 0;
 
     // checkTimeouts() allows the server to check socket timeouts, etc.  The
-    // return value is the number of milliseconds to wait before
-    // checkTimeouts() should be called again.  If this number is zero then
-    // there is no timeout and checkTimeouts() should be called the next time
-    // an event occurs.
+    //   return value is the number of milliseconds to wait before
+    //   checkTimeouts() should be called again.  If this number is zero then
+    //   there is no timeout and checkTimeouts() should be called the next time
+    //   an event occurs.
     virtual int checkTimeouts() = 0;
 
-    // soonestTimeout() is a function to help work out the soonest of several
-    // timeouts.
-    static void soonestTimeout(int* timeout, int newTimeout) {
-      if (newTimeout && (!*timeout || newTimeout < *timeout))
-        *timeout = newTimeout;
-    }
     virtual bool getDisable() {return false;};
   };
 
index 035c7f261f348b182ab427b0579ed0ae8dc03ca4..3212ace757cdc5e5cb6fc44981ca51ab2cb8ea60 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -81,8 +81,11 @@ int network::findFreeTcpPort (void)
 }
 
 
-void
-TcpSocket::initTcpSockets() {
+// -=- Socket initialisation
+static bool socketsInitialised = false;
+static void initSockets() {
+  if (socketsInitialised)
+    return;
 #ifdef WIN32
   WORD requiredVersion = MAKEWORD(2,0);
   WSADATA initResult;
@@ -92,8 +95,10 @@ TcpSocket::initTcpSockets() {
 #else
   signal(SIGPIPE, SIG_IGN);
 #endif
+  socketsInitialised = true;
 }
 
+
 // -=- TcpSocket
 
 TcpSocket::TcpSocket(int sock, bool close)
@@ -107,6 +112,7 @@ TcpSocket::TcpSocket(const char *host, int port)
   int sock;
 
   // - Create a socket
+  initSockets();
   if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
     throw SocketException("unable to create socket", errorNumber);
 
@@ -149,18 +155,13 @@ TcpSocket::TcpSocket(const char *host, int port)
     } else break;
   }
 
-  int one = 1;
-  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
-                (char *)&one, sizeof(one)) < 0) {
-    int e = errorNumber;
-    closesocket(sock);
-    throw SocketException("unable to setsockopt TCP_NODELAY", e);
-  }
+  // Disable Nagle's algorithm, to reduce latency
+  enableNagles(sock, false);
 
   // Create the input and output streams
   instream = new FdInStream(sock);
   outstream = new FdOutStream(sock);
-  own_streams = true;
+  ownStreams = true;
 }
 
 TcpSocket::~TcpSocket() {
@@ -244,9 +245,21 @@ bool TcpSocket::sameMachine() {
 
 void TcpSocket::shutdown()
 {
+  Socket::shutdown();
   ::shutdown(getFd(), 2);
 }
 
+bool TcpSocket::enableNagles(int sock, bool enable) {
+  int one = enable ? 0 : 1;
+  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+                (char *)&one, sizeof(one)) < 0) {
+    int e = errorNumber;
+    vlog.error("unable to setsockopt TCP_NODELAY: %d", e);
+    return false;
+  }
+  return true;
+}
+
 bool TcpSocket::isSocket(int sock)
 {
   struct sockaddr_in info;
@@ -279,12 +292,13 @@ TcpListener::TcpListener(int port, bool localhostOnly, int sock, bool close_)
     return;
   }
 
+  initSockets();
   if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
     throw SocketException("unable to create listening socket", errorNumber);
 
 #ifndef WIN32
   // - By default, close the socket on exec()
-  fcntl(sock, F_SETFD, FD_CLOEXEC);
+  fcntl(fd, F_SETFD, FD_CLOEXEC);
 
   int one = 1;
   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
@@ -345,14 +359,8 @@ TcpListener::accept() {
   fcntl(new_sock, F_SETFD, FD_CLOEXEC);
 #endif
 
-  // Disable Nagle's algorithm
-  int one = 1;
-  if (setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY,
-   (char *)&one, sizeof(one)) < 0) {
-    int e = errorNumber;
-    closesocket(new_sock);
-    throw SocketException("unable to setsockopt TCP_NODELAY", e);
-  }
+  // Disable Nagle's algorithm, to reduce latency
+  TcpSocket::enableNagles(new_sock, false);
 
   // Create the socket object & check connection is allowed
   TcpSocket* s = new TcpSocket(new_sock);
@@ -418,7 +426,8 @@ TcpFilter::verifyConnection(Socket* s) {
         return true;
       case Query:
         vlog.debug("QUERY %s", name.buf);
-        return queryUserAcceptConnection(s);
+        s->setRequiresQuery();
+        return true;
       case Reject:
         vlog.debug("REJECT %s", name.buf);
         return false;
index 74697829900e43f980e977a039265f43abe3710a..774c6e135b7e7a89967933d9178b966ac7198233 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -57,8 +57,7 @@ namespace network {
 
     virtual void shutdown();
 
-    static void initTcpSockets();
-
+    static bool enableNagles(int sock, bool enable);
     static bool isSocket(int sock);
     static bool isConnected(int sock);
     static int getSockPort(int sock);