Panda3D

connectionManager.cxx

00001 // Filename: connectionManager.cxx
00002 // Created by:  jns (07Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "connectionManager.h"
00016 #include "connection.h"
00017 #include "connectionReader.h"
00018 #include "connectionWriter.h"
00019 #include "netAddress.h"
00020 #include "config_net.h"
00021 #include "lightMutexHolder.h"
00022 #include "trueClock.h"
00023 
00024 #if defined(WIN32_VC) || defined(WIN64_VC)
00025 #include <winsock2.h>  // For gethostname()
00026 #endif
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: ConnectionManager::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 ConnectionManager::
00034 ConnectionManager() : _set_mutex("ConnectionManager::_set_mutex") 
00035 {
00036 }
00037 
00038 ////////////////////////////////////////////////////////////////////
00039 //     Function: ConnectionManager::Destructor
00040 //       Access: Public, Virtual
00041 //  Description:
00042 ////////////////////////////////////////////////////////////////////
00043 ConnectionManager::
00044 ~ConnectionManager() {
00045   // Notify all of our associated readers and writers that we're gone.
00046   Readers::iterator ri;
00047   for (ri = _readers.begin(); ri != _readers.end(); ++ri) {
00048     (*ri)->clear_manager();
00049   }
00050   Writers::iterator wi;
00051   for (wi = _writers.begin(); wi != _writers.end(); ++wi) {
00052     (*wi)->clear_manager();
00053   }
00054 }
00055 
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: ConnectionManager::open_UDP_connection
00059 //       Access: Public
00060 //  Description: Opens a socket for sending and/or receiving UDP
00061 //               packets.  If the port number is greater than zero,
00062 //               the UDP connection will be opened for listening on
00063 //               the indicated port; otherwise, it will be useful only
00064 //               for sending.
00065 //
00066 //               Use a ConnectionReader and ConnectionWriter to handle
00067 //               the actual communication.
00068 ////////////////////////////////////////////////////////////////////
00069 PT(Connection) ConnectionManager::
00070 open_UDP_connection(int port) {
00071   Socket_UDP *socket = new Socket_UDP;
00072 
00073   if (port > 0) {
00074     NetAddress address;
00075     address.set_any(port);
00076     
00077     if (!socket->OpenForInput(address.get_addr())) {
00078       net_cat.error()
00079         << "Unable to bind to port " << port << " for UDP.\n";
00080       delete socket;
00081       return PT(Connection)();
00082     }
00083 
00084     net_cat.info()
00085       << "Creating UDP connection for port " << port << "\n";
00086 
00087   } else {
00088     if (!socket->InitNoAddress()) {
00089       net_cat.error()
00090         << "Unable to initialize outgoing UDP.\n";
00091       delete socket;
00092       return PT(Connection)();
00093     }
00094 
00095     net_cat.info()
00096       << "Creating outgoing UDP connection\n";
00097   }
00098 
00099   PT(Connection) connection = new Connection(this, socket);
00100   new_connection(connection);
00101   return connection;
00102 }
00103 
00104 
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: ConnectionManager::open_TCP_server_rendezvous
00108 //       Access: Public
00109 //  Description: Creates a socket to be used as a rendezvous socket
00110 //               for a server to listen for TCP connections.  The
00111 //               socket returned by this call should only be added to
00112 //               a ConnectionListener (not to a generic
00113 //               ConnectionReader).
00114 //
00115 //               This variant of this method accepts a single port,
00116 //               and will listen to that port on all available
00117 //               interfaces.
00118 //
00119 //               backlog is the maximum length of the queue of pending
00120 //               connections.
00121 ////////////////////////////////////////////////////////////////////
00122 PT(Connection) ConnectionManager::
00123 open_TCP_server_rendezvous(int port, int backlog) {
00124   NetAddress address;
00125   address.set_any(port);
00126   return open_TCP_server_rendezvous(address, backlog);
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: ConnectionManager::open_TCP_server_rendezvous
00131 //       Access: Public
00132 //  Description: Creates a socket to be used as a rendezvous socket
00133 //               for a server to listen for TCP connections.  The
00134 //               socket returned by this call should only be added to
00135 //               a ConnectionListener (not to a generic
00136 //               ConnectionReader).
00137 //
00138 //               This variant of this method accepts a "hostname",
00139 //               which is usually just an IP address in dotted
00140 //               notation, and a port number.  It will listen on the
00141 //               interface indicated by the IP address.  If the IP
00142 //               address is empty string, it will listen on all
00143 //               interfaces.
00144 //
00145 //               backlog is the maximum length of the queue of pending
00146 //               connections.
00147 ////////////////////////////////////////////////////////////////////
00148 PT(Connection) ConnectionManager::
00149 open_TCP_server_rendezvous(const string &hostname, int port, int backlog) {
00150   NetAddress address;
00151   if (hostname.empty()) {
00152     address.set_any(port);
00153   } else {
00154     address.set_host(hostname, port);
00155   }
00156   return open_TCP_server_rendezvous(address, backlog);
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: ConnectionManager::open_TCP_server_rendezvous
00161 //       Access: Public
00162 //  Description: Creates a socket to be used as a rendezvous socket
00163 //               for a server to listen for TCP connections.  The
00164 //               socket returned by this call should only be added to
00165 //               a ConnectionListener (not to a generic
00166 //               ConnectionReader).
00167 //
00168 //               This variant of this method accepts a NetAddress,
00169 //               which allows you to specify a specific interface to
00170 //               listen to.
00171 //
00172 //               backlog is the maximum length of the queue of pending
00173 //               connections.
00174 ////////////////////////////////////////////////////////////////////
00175 PT(Connection) ConnectionManager::
00176 open_TCP_server_rendezvous(const NetAddress &address, int backlog) {
00177   ostringstream strm;
00178   if (address.get_ip() == 0) {
00179     strm << "port " << address.get_port();  
00180   } else {
00181     strm << address.get_ip_string() << ":" << address.get_port();
00182   }
00183 
00184   Socket_TCP_Listen *socket = new Socket_TCP_Listen;
00185   bool okflag = socket->OpenForListen(address.get_addr(), backlog);
00186   if (!okflag) {
00187     net_cat.info()
00188       << "Unable to listen to " << strm.str() << " for TCP.\n";
00189     delete socket;
00190     return PT(Connection)();
00191   }
00192 
00193   net_cat.info()
00194     << "Listening for TCP connections on " << strm.str() << "\n";
00195 
00196   PT(Connection) connection = new Connection(this, socket);
00197   new_connection(connection);
00198   return connection;
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: ConnectionManager::open_TCP_client_connection
00203 //       Access: Public
00204 //  Description: Attempts to establish a TCP client connection to a
00205 //               server at the indicated address.  If the connection
00206 //               is not established within timeout_ms milliseconds, a
00207 //               null connection is returned.
00208 ////////////////////////////////////////////////////////////////////
00209 PT(Connection) ConnectionManager::
00210 open_TCP_client_connection(const NetAddress &address, int timeout_ms) {
00211   Socket_TCP *socket = new Socket_TCP;
00212 
00213   // We always open the connection with non-blocking mode first, so we
00214   // can implement the timeout.
00215   bool okflag = socket->ActiveOpenNonBlocking(address.get_addr());
00216   if (okflag && socket->GetLastError() == LOCAL_CONNECT_BLOCKING) {
00217     // Now wait for the socket to connect.
00218     TrueClock *clock = TrueClock::get_global_ptr();
00219     double start = clock->get_short_time();
00220     Thread::force_yield();
00221     Socket_fdset fset;
00222     fset.setForSocket(*socket);
00223     int ready = fset.WaitForWrite(true, 0);
00224     while (ready == 0) {
00225       double elapsed = clock->get_short_time() - start;
00226       if (elapsed * 1000.0 > timeout_ms) {
00227         // Timeout.
00228         okflag = false;
00229         break;
00230       }
00231       Thread::force_yield();
00232       fset.setForSocket(*socket);
00233       ready = fset.WaitForWrite(true, 0);
00234     }
00235   }
00236 
00237   if (!okflag) {
00238     net_cat.error()
00239       << "Unable to open TCP connection to server "
00240       << address.get_ip_string() << " on port " << address.get_port() << "\n";
00241     delete socket;
00242     return PT(Connection)();
00243   }
00244 
00245 #if !defined(HAVE_THREADS) || !defined(SIMPLE_THREADS)
00246   // Now we have opened the socket in nonblocking mode.  Unless we're
00247   // using SIMPLE_THREADS, though, we really want the socket in
00248   // blocking mode (since that's what we support here).  Change it.
00249   socket->SetBlocking();
00250 
00251 #endif  // SIMPLE_THREADS
00252 
00253   net_cat.info()
00254     << "Opened TCP connection to server " << address.get_ip_string() << " "
00255     << " on port " << address.get_port() << "\n";
00256 
00257   PT(Connection) connection = new Connection(this, socket);
00258   new_connection(connection);
00259   return connection;
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: ConnectionManager::open_TCP_client_connection
00264 //       Access: Public
00265 //  Description: This is a shorthand version of the function to
00266 //               directly establish communications to a named host and
00267 //               port.
00268 ////////////////////////////////////////////////////////////////////
00269 PT(Connection) ConnectionManager::
00270 open_TCP_client_connection(const string &hostname, int port,
00271                            int timeout_ms) {
00272   NetAddress address;
00273   if (!address.set_host(hostname, port)) {
00274     return PT(Connection)();
00275   }
00276 
00277   return open_TCP_client_connection(address, timeout_ms);
00278 }
00279 
00280 ////////////////////////////////////////////////////////////////////
00281 //     Function: ConnectionManager::close_connection
00282 //       Access: Public
00283 //  Description: Terminates a UDP or TCP socket previously opened.
00284 //               This also removes it from any associated
00285 //               ConnectionReader or ConnectionListeners.
00286 //
00287 //               The socket itself may not be immediately closed--it
00288 //               will not be closed until all outstanding pointers to
00289 //               it are cleared, including any pointers remaining in
00290 //               NetDatagrams recently received from the socket.
00291 //
00292 //               The return value is true if the connection was marked
00293 //               to be closed, or false if close_connection() had
00294 //               already been called (or the connection did not belong
00295 //               to this ConnectionManager).  In neither case can you
00296 //               infer anything about whether the connection has
00297 //               *actually* been closed yet based on the return value.
00298 ////////////////////////////////////////////////////////////////////
00299 bool ConnectionManager::
00300 close_connection(const PT(Connection) &connection) {
00301   if (connection != (Connection *)NULL) {
00302     connection->flush();
00303   }
00304 
00305   {
00306     LightMutexHolder holder(_set_mutex);
00307     Connections::iterator ci = _connections.find(connection);
00308     if (ci == _connections.end()) {
00309       // Already closed, or not part of this ConnectionManager.
00310       return false;
00311     }
00312     _connections.erase(ci);
00313     
00314     Readers::iterator ri;
00315     for (ri = _readers.begin(); ri != _readers.end(); ++ri) {
00316       (*ri)->remove_connection(connection);
00317     }
00318   }
00319 
00320   Socket_IP *socket = connection->get_socket();
00321 
00322   // We can't *actually* close the connection right now, because
00323   // there might be outstanding pointers to it.  But we can at least
00324   // shut it down.  It will be eventually closed when all the
00325   // pointers let go.
00326   
00327   net_cat.info()
00328     << "Shutting down connection " << (void *)connection
00329     << " locally.\n";
00330   socket->Close();
00331 
00332   return true;
00333 }
00334 
00335 ////////////////////////////////////////////////////////////////////
00336 //     Function: ConnectionManager::get_host_name
00337 //       Access: Public, Static
00338 //  Description: Returns the name of this particular machine on the
00339 //               network, if available, or the empty string if the
00340 //               hostname cannot be determined.
00341 ////////////////////////////////////////////////////////////////////
00342 string ConnectionManager::
00343 get_host_name() {
00344   char temp_buff[1024];
00345   if (gethostname(temp_buff, 1024) == 0) {
00346     return string(temp_buff);
00347   }
00348 
00349   return string();
00350 }
00351 
00352 ////////////////////////////////////////////////////////////////////
00353 //     Function: ConnectionManager::new_connection
00354 //       Access: Protected
00355 //  Description: This internal function is called whenever a new
00356 //               connection is established.  It allows the
00357 //               ConnectionManager to save all of the pointers to open
00358 //               connections so they can't be inadvertently deleted
00359 //               until close_connection() is called.
00360 ////////////////////////////////////////////////////////////////////
00361 void ConnectionManager::
00362 new_connection(const PT(Connection) &connection) {
00363   LightMutexHolder holder(_set_mutex);
00364   _connections.insert(connection);
00365 }
00366 
00367 ////////////////////////////////////////////////////////////////////
00368 //     Function: ConnectionManager::flush_read_connection
00369 //       Access: Protected, Virtual
00370 //  Description: An internal function called by ConnectionWriter only
00371 //               when a write failure has occurred.  This method
00372 //               ensures that all of the read data has been flushed
00373 //               from the pipe before the connection is fully removed.
00374 ////////////////////////////////////////////////////////////////////
00375 void ConnectionManager::
00376 flush_read_connection(Connection *connection) {
00377   Readers readers;
00378   {
00379     LightMutexHolder holder(_set_mutex);
00380     Connections::iterator ci = _connections.find(connection);
00381     if (ci == _connections.end()) {
00382       // Already closed, or not part of this ConnectionManager.
00383       return;
00384     }
00385     _connections.erase(ci);
00386 
00387     // Get a copy first, so we can release the lock before traversing.
00388     readers = _readers;
00389   }
00390   Readers::iterator ri;
00391   for (ri = readers.begin(); ri != readers.end(); ++ri) {
00392     (*ri)->flush_read_connection(connection);
00393   }
00394 
00395   Socket_IP *socket = connection->get_socket();
00396   socket->Close();
00397 }
00398 
00399 ////////////////////////////////////////////////////////////////////
00400 //     Function: ConnectionManager::connection_reset
00401 //       Access: Protected, Virtual
00402 //  Description: An internal function called by the ConnectionReader,
00403 //               ConnectionWriter, or ConnectionListener when a
00404 //               connection has been externally reset.  This adds the
00405 //               connection to the queue of those which have recently
00406 //               been reset.
00407 ////////////////////////////////////////////////////////////////////
00408 void ConnectionManager::
00409 connection_reset(const PT(Connection) &connection, bool okflag) {
00410   if (net_cat.is_info()) {
00411     if (okflag) {
00412       net_cat.info()
00413         << "Connection " << (void *)connection
00414         << " was closed normally by the other end";
00415 
00416     } else {
00417       net_cat.info()
00418         << "Lost connection " << (void *)connection
00419         << " unexpectedly\n";
00420     }
00421   }
00422 
00423   // Turns out we do need to explicitly mark the connection as closed
00424   // immediately, rather than waiting for the user to do it, since
00425   // otherwise we'll keep trying to listen for noise on the socket and
00426   // we'll always hear a "yes" answer.
00427   close_connection(connection);
00428 }
00429 
00430 ////////////////////////////////////////////////////////////////////
00431 //     Function: ConnectionManager::add_reader
00432 //       Access: Protected
00433 //  Description: This internal function is called by ConnectionReader
00434 //               when it is constructed.
00435 ////////////////////////////////////////////////////////////////////
00436 void ConnectionManager::
00437 add_reader(ConnectionReader *reader) {
00438   LightMutexHolder holder(_set_mutex);
00439   _readers.insert(reader);
00440 }
00441 
00442 ////////////////////////////////////////////////////////////////////
00443 //     Function: ConnectionManager::remove_reader
00444 //       Access: Protected
00445 //  Description: This internal function is called by ConnectionReader
00446 //               when it is destructed.
00447 ////////////////////////////////////////////////////////////////////
00448 void ConnectionManager::
00449 remove_reader(ConnectionReader *reader) {
00450   LightMutexHolder holder(_set_mutex);
00451   _readers.erase(reader);
00452 }
00453 
00454 ////////////////////////////////////////////////////////////////////
00455 //     Function: ConnectionManager::add_writer
00456 //       Access: Protected
00457 //  Description: This internal function is called by ConnectionWriter
00458 //               when it is constructed.
00459 ////////////////////////////////////////////////////////////////////
00460 void ConnectionManager::
00461 add_writer(ConnectionWriter *writer) {
00462   LightMutexHolder holder(_set_mutex);
00463   _writers.insert(writer);
00464 }
00465 
00466 ////////////////////////////////////////////////////////////////////
00467 //     Function: ConnectionManager::remove_writer
00468 //       Access: Protected
00469 //  Description: This internal function is called by ConnectionWriter
00470 //               when it is destructed.
00471 ////////////////////////////////////////////////////////////////////
00472 void ConnectionManager::
00473 remove_writer(ConnectionWriter *writer) {
00474   LightMutexHolder holder(_set_mutex);
00475   _writers.erase(writer);
00476 }
 All Classes Functions Variables Enumerations