/*! Add a new connection. A connection is defined using a connection struct. */ ConnectionPtr Server::addConnectionToList (Socket* s, MYSERVER_SOCKADDRIN* /*asockIn*/, char *ipAddr, char *localIpAddr, u_short port, u_short localPort, int /*id*/) { int doSSLhandshake = 0; int doFastCheck = 0; Protocol* protocol; int opts = 0; ConnectionPtr newConnection; vector<Multicast<string, void*, int>*>* handlers; connectionsPoolLock.lock (); try { newConnection = connectionsPool.forcedGet (); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } if (!newConnection) return NULL; else newConnection->init (); newConnection->setPort (port); newConnection->setTimeout ( getTicks () ); newConnection->setLocalPort (localPort); newConnection->setIpAddr (ipAddr); newConnection->setLocalIpAddr (localIpAddr); newConnection->host = vhostManager.getVHost (0, localIpAddr, localPort); if (newConnection->host == NULL) { try { connectionsPoolLock.lock (); connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } return 0; } protocol = getProtocol (newConnection->host->getProtocolName ()); if (protocol) opts = protocol->getProtocolOptions (); if (opts & Protocol::SSL) doSSLhandshake = 1; if (opts & Protocol::FAST_CHECK) doFastCheck = 1; string msg ("new-connection"); handlers = getHandlers (msg); if (handlers) { for (size_t i = 0; i < handlers->size (); i++) if ((*handlers)[i]->updateMulticast (this, msg, newConnection) == 1) { connectionsPoolLock.lock (); try { connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } return 0; } } /* Do the SSL handshake if required. */ if (doSSLhandshake) { int ret = 0; SslSocket *sslSocket = new SslSocket (s); sslSocket->setSSLContext (newConnection->host->getSSLContext (), newConnection->host->getSSLPriorityCache ()); ret = sslSocket->sslAccept (); if (ret < 0) { connectionsPoolLock.lock (); try { connectionsPool.put (newConnection); connectionsPoolLock.unlock (); } catch (...) { connectionsPoolLock.unlock (); throw; } delete sslSocket; return 0; } newConnection->socket = sslSocket; } else newConnection->socket = s; if (doFastCheck) { newConnection->setScheduled (1); newConnection->setForceControl (1); newConnection->socket->setNonBlocking (1); connectionsScheduler.addNewReadyConnection (newConnection); } else connectionsScheduler.addNewWaitingConnection (newConnection); /* If defined maxConnections and the number of active connections is bigger than it say to the protocol that will parse the connection to remove it from the active connections list. */ if (maxConnections && connectionsScheduler.getNumAliveConnections () > maxConnections) newConnection->setToRemove (Connection::REMOVE_OVERLOAD); connectionsScheduler.registerConnectionID (newConnection); return newConnection; }