void QListener::onConnection()
{
/* Getting the pending connection */
QTcpSocket *clientSocket = serverSocket.nextPendingConnection();
if ( ! clientSocket )
return;
QString ip = clientSocket->peerAddress().toString();
/* Checking if connection is allowed */
bool isInCache = false;
QUserInfo userInfo;
userInfo = userInfoMap.value(ip, userInfo);
if ( ! userInfo.user.isEmpty() )
{
if ( userInfo.lastUpdate.secsTo(QTime::currentTime()) < (60 * 10) )
isInCache = true;
}
bool isAllowed = true;
/* If user is not in cache - get it from SQL and add to cache */
if ( ! isInCache )
{
userInfo.user.clear();
if ( ! db.open() )
qDebug() << "Failed to open DB!";
QSqlQuery *sqlQuery = NULL;
try
{
sqlQuery = new QSqlQuery(db);
} catch(...)
{
qDebug() << "Exception! [1]";
return;
}
if ( ! sqlQuery->exec(QString("SELECT user, threads FROM users WHERE ip='%1'").arg(ip)) )
{
qDebug() << "Query failed:" << sqlQuery->lastError().text();
isAllowed = false;
}
if ( sqlQuery->next() && isAllowed )
{
userInfo.user = sqlQuery->value(0).toString();
userInfo.maxThreads = sqlQuery->value(1).toInt();
userInfo.lastUpdate = QTime::currentTime();
userInfoMap.remove(ip); // Remove the old user info from the cache
userInfoMap.insert(ip, userInfo); // Insert user info to the cache
} else
isAllowed = false;
sqlQuery->finish();
delete sqlQuery;
db.close();
if ( isAllowed )
qDebug() << "Cache record for" << ip << "is deprecated and was updated";
}
/* Check if threads limit is reached */
qint32 connectionsCount = connectionsList.count(ip);
if ( connectionsCount >= userInfo.maxThreads )
{
connectionsList.removeAt(connectionsList.indexOf(ip));
}
/* If not allowed - disconnect */
if ( ! isAllowed )
{
clientSocket->disconnectFromHost();
clientSocket->deleteLater();
return;
}
/* Trying to connect to the proxy */
QTcpSocket *proxySocket = NULL;
try
{
proxySocket = new QTcpSocket;
} catch(...)
{
qDebug() << "Exception (2)!";
clientSocket->disconnectFromHost();
clientSocket->deleteLater();
return;
}
if ( ! proxySocket )
{
clientSocket->disconnectFromHost();
clientSocket->deleteLater();
return;
}
/* Get the proxy host & port from the DB */
if ( proxiesCount == 0 )
{
qDebug() << "Proxies count == 0!";
clientSocket->disconnectFromHost();
clientSocket->deleteLater();
return;
}
mutex.lock();
QString host = proxiesList.at(currentProxy);
quint16 port = portsList.at(currentProxy);
if ( currentProxy >= (proxiesCount - 1) )
currentProxy = 0;
else
currentProxy++;
mutex.unlock();
/* Connect to the proxy */
proxySocket->connectToHost(host, port);
if ( ! proxySocket->waitForConnected(5000) )
{
qDebug() << "Failed to connect to the proxy!";
clientSocket->disconnectFromHost();
clientSocket->deleteLater();
return;
}
connectionsCount++;
connectionsList.append(ip);
qDebug() << "New connection accepted! " << connectionsCount << "connections for this IP";
qDebug() << "Total:" << socketsMap.count() << "connections";
/* Add sockets to the map and connect to the slots */
clientSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
proxySocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
socketsMap[clientSocket] = proxySocket;
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(proxySocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
connect(proxySocket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
}
Вот код, немного индусский, ибо писался в спешке.
Функция выполняется до конца.