Exemple #1
0
/*!
  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;
}