Panda3D
|
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 }