⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsocks5socketengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtNetwork module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qsocks5socketengine_p.h"#ifndef QT_NO_SOCKS5#include "qtcpsocket.h"#include "qudpsocket.h"#include "qtcpserver.h"#include "qdebug.h"#include "qhash.h"#include "qqueue.h"#include "qdatetime.h"#include "qmutex.h"#include "qthread.h"#include "qcoreapplication.h"#include <qendian.h>//#define QSOCKS5SOCKETLAYER_DEBUG#define MAX_DATA_DUMP 256#define SOCKS5_BLOCKING_BIND_TIMEOUT 5000#define Q_INIT_CHECK(returnValue) do { \    if (!d->data) { \        return returnValue; \    } } while (0)#ifdef QSOCKS5SOCKETLAYER_DEBUG#  define QSOCKS5_Q_DEBUG qDebug() << this#  define QSOCKS5_D_DEBUG qDebug() << q_ptr#  define QSOCKS5_DEBUG qDebug() << "[QSocks5]"#else#  define QSOCKS5_DEBUG if (0) qDebug()#  define QSOCKS5_Q_DEBUG if (0) qDebug()#  define QSOCKS5_D_DEBUG if (0) qDebug()#endif#define S5_VERSION_5 0x05#define S5_CONNECT 0x01#define S5_BIND 0x02#define S5_UDP_ASSOCIATE 0x03#define S5_IP_V4 0x01#define S5_DOMAINNAME 0x03#define S5_IP_V6 0x04#define S5_SUCCESS 0x00#define S5_R_ERROR_SOCKS_FAILURE 0x01#define S5_R_ERROR_CON_NOT_ALLOWED 0x02#define S5_R_ERROR_NET_UNREACH 0x03#define S5_R_ERROR_HOST_UNREACH 0x04#define S5_R_ERROR_CONN_REFUSED 0x05#define S5_R_ERROR_TTL 0x06#define S5_R_ERROR_CMD_NOT_SUPPORTED 0x07#define S5_R_ERROR_ADD_TYPE_NOT_SUPORTED 0x08static QString s5RequestErrorToString(int s5_r_error){    QString ret;    switch(s5_r_error) {    case 0x01 : ret = QLatin1String("general SOCKS server failure"); break;    case 0x02 : ret = QLatin1String("connection not allowed by ruleset"); break;    case 0x03 : ret = QLatin1String("Network unreachable"); break;    case 0x04 : ret = QLatin1String("Host unreachable"); break;    case 0x05 : ret = QLatin1String("Connection refused"); break;    case 0x06 : ret = QLatin1String("TTL expired"); break;    case 0x07 : ret = QLatin1String("Command not supported"); break;    case 0x08 : ret = QLatin1String("Address type not supported"); break;    default   : ret = QLatin1String("unassigned error code"); break;    }    return ret;}static QString makeErrorString(const QString & e){    return QLatin1String("Socks 5 - ") + e;}static QAbstractSocket::SocketError s5RAsSocketError(int s5_r_error){    QAbstractSocket::SocketError ret;    switch(s5_r_error) {    case 0x01 : ret = QAbstractSocket::NetworkError; break;    case 0x02 : ret = QAbstractSocket::SocketAccessError; break;    case 0x03 : ret = QAbstractSocket::NetworkError; break;    case 0x04 : ret = QAbstractSocket::HostNotFoundError; break;    case 0x05 : ret = QAbstractSocket::ConnectionRefusedError; break;    case 0x06 : ret = QAbstractSocket::NetworkError; break;    case 0x07 : ret = QAbstractSocket::UnsupportedSocketOperationError; break;    case 0x08 : ret = QAbstractSocket::UnsupportedSocketOperationError; break;    default   : ret = QAbstractSocket::NetworkError; break;    }    return ret;}static QString s5StateToString(QSocks5SocketEnginePrivate::Socks5State s){    switch (s) {    case QSocks5SocketEnginePrivate::unInitialized: return QLatin1String("unInitialized");    case QSocks5SocketEnginePrivate::AuthenticationMethodsSent: return QLatin1String("AuthenticationMethodsSent");    case QSocks5SocketEnginePrivate::Authenticating: return QLatin1String("Authenticating");    case QSocks5SocketEnginePrivate::RequestMethodSent: return QLatin1String("RequestMethodSent");    case QSocks5SocketEnginePrivate::RequestSuccess: return QLatin1String("RequestSuccess");    case QSocks5SocketEnginePrivate::RequestError: return QLatin1String("RequestError");    case QSocks5SocketEnginePrivate::Connected: return QLatin1String("Connected");    case QSocks5SocketEnginePrivate::ConnectError: return QLatin1String("BindSuccess");    case QSocks5SocketEnginePrivate::BindSuccess: return QLatin1String("unInitialized");    case QSocks5SocketEnginePrivate::BindError: return QLatin1String("BindError");    case QSocks5SocketEnginePrivate::ControlSocketError: return QLatin1String("ControlSocketError");    case QSocks5SocketEnginePrivate::SocksError: return QLatin1String("SocksError");    default: break;    }    return QLatin1String("unknown state");}static QString dump(const QByteArray &buf){    QString data;    for (int i = 0; i < qMin<int>(MAX_DATA_DUMP, buf.size()); ++i) {        if (i) data += QLatin1Char(' ');        uint val = (unsigned char)buf.at(i);       // data += QString("0x%1").arg(val, 3, 16, QLatin1Char('0'));        data += QString::number(val);    }    if (buf.size() > MAX_DATA_DUMP)        data += QLatin1String(" ...");    return QString::fromLatin1("size: %1 data: { %2 }").arg(buf.size()).arg(data);}/*   inserets the host address in buf at pos and updates pos.   if the func fails the data in buf and the vallue of pos is undefined*/static bool qt_socks5_set_host_address_and_port(const QHostAddress &address, quint16 port, QByteArray *pBuf, int *pPos){    bool ret = false;    int pos = *pPos;    QSOCKS5_DEBUG << "setting [" << address << ":" << port << "]";    if (address.protocol() == QAbstractSocket::IPv4Protocol) {        int spaceAvailable = pBuf->size() - pos;        if (spaceAvailable < int(sizeof(quint32) + 1))            pBuf->resize(pBuf->size() + sizeof(quint32) + 1 - spaceAvailable);        unsigned char *buf = reinterpret_cast<unsigned char *>(pBuf->data());        buf[pos++] = S5_IP_V4;        qToUnaligned(qToBigEndian<quint32>(address.toIPv4Address()), &buf[pos]);        pos += sizeof(quint32);        ret = true;    } else if (address.protocol() == QAbstractSocket::IPv6Protocol) {        int spaceAvailable = pBuf->size() - pos;        if (spaceAvailable < 17)            pBuf->resize(pBuf->size() + 17 - spaceAvailable);        char *buf = pBuf->data();        buf[pos++] = S5_IP_V6;        QIPv6Address ipv6 = address.toIPv6Address();        for (int i = 0; i < 16; ++i)            buf[pos++] = ipv6[i];        ret = true;    } else {        // domain name.        ret = false;    }    if (ret) {        int spaceAvailable = pBuf->size() - pos;        if (spaceAvailable < int(sizeof(quint16)))            pBuf->resize(pBuf->size() + sizeof(quint16) - spaceAvailable);        unsigned char *buf = reinterpret_cast<unsigned char *>(pBuf->data());        qToUnaligned(qToBigEndian<quint16>(port), &buf[pos]);        pos += sizeof(quint16);    }    if (ret)        *pPos = pos;    return ret;}/*   retrives the host address in buf at pos and updates pos.   if the func fails the value of the address and the pos is undefined*/static bool qt_socks5_get_host_address_and_port(const QByteArray &buf, QHostAddress *pAddress, quint16 *pPort, int *pPos){    bool ret = false;    int pos = *pPos;    const unsigned char *pBuf = reinterpret_cast<const unsigned char*>(buf.constData());    QHostAddress address;    quint16 port = 0;    if (buf.size() - pos < 1) {        QSOCKS5_DEBUG << "need more data address/port";        return false;    }    if (pBuf[pos] == S5_IP_V4) {        pos++;        if (buf.size() - pos < 4) {            QSOCKS5_DEBUG << "need more data for ip4 address";            return false;        }        address.setAddress(qFromBigEndian<quint32>(&pBuf[pos]));        pos += 4;        ret = true;    } else if (pBuf[pos] == S5_IP_V6) {        pos++;        if (buf.size() - pos < 16) {            QSOCKS5_DEBUG << "need more data for ip6 address";            return false;        }        QIPv6Address add;        for (int i = 0; i < 16; ++i)            add[i] = buf[pos++];        ret = true;    } else if (pBuf[pos] == S5_DOMAINNAME){        pos++;        // domain name.        ret = false;    } else {        QSOCKS5_DEBUG << "invalid address type" << (int)pBuf[pos];        ret = false;    }    if (ret) {        if (buf.size() - pos < 2) {            QSOCKS5_DEBUG << "need more data for port";            return false;        }        port = qFromBigEndian<quint16>(&pBuf[pos]);        pos += 2;    }    if (ret) {        QSOCKS5_DEBUG << "got [" << address << ":" << port << "]";        *pAddress = address;        *pPort = port;        *pPos = pos;    }    return ret;}/*   Returns the difference between msecs and elapsed. If msecs is -1,   however, -1 is returned.*/static int qt_timeout_value(int msecs, int elapsed){    if (msecs == -1)        return -1;    int timeout = msecs - elapsed;    return timeout < 0 ? 0 : timeout;}struct QSocks5Data{    QTcpSocket *controlSocket;    QSocks5Authenticator *authenticator;};struct QSocks5ConnectData : public QSocks5Data{    QByteArray readBuffer;};struct QSocks5BindData : public QSocks5Data{    QHostAddress localAddress;    quint16 localPort;    QHostAddress peerAddress;    quint16 peerPort;    QDateTime timeStamp;};struct QSocks5RevivedDatagram{    QByteArray data;    QHostAddress address;    quint16 port;};#ifndef QT_NO_UDPSOCKETstruct QSocks5UdpAssociateData : public QSocks5Data{    QUdpSocket *udpSocket;    QHostAddress associateAddress;    quint16 associatePort;    QQueue<QSocks5RevivedDatagram> pendingDatagrams;};#endif// needs to be thread safeclass QSocks5BindStore : public QObject{public:    QSocks5BindStore();    ~QSocks5BindStore();    void add(int socketDescriptor, QSocks5BindData *bindData);    bool contains(int socketDescriptor);    QSocks5BindData *retrieve(int socketDescriptor);protected:    void timerEvent(QTimerEvent * event);    QMutex mutex;    int sweepTimerId;    //socket descriptor, data, timestamp    QHash<int, QSocks5BindData *> store;};Q_GLOBAL_STATIC(QSocks5BindStore, socks5BindStore);QSocks5BindStore::QSocks5BindStore()    : mutex(QMutex::Recursive)    , sweepTimerId(-1){    QCoreApplication *app = QCoreApplication::instance();    if (app && app->thread() != thread())        moveToThread(app->thread());}QSocks5BindStore::~QSocks5BindStore(){}void QSocks5BindStore::add(int socketDescriptor, QSocks5BindData *bindData){    QMutexLocker lock(&mutex);    if (store.contains(socketDescriptor)) {        // qDebug() << "delete it";    }    bindData->timeStamp = QDateTime::currentDateTime();    store.insert(socketDescriptor, bindData);    // start sweep timer if not started    if (sweepTimerId == -1)        sweepTimerId = startTimer(60000);}bool QSocks5BindStore::contains(int socketDescriptor){    QMutexLocker lock(&mutex);    return store.contains(socketDescriptor);}QSocks5BindData *QSocks5BindStore::retrieve(int socketDescriptor){    QMutexLocker lock(&mutex);    if (!store.contains(socketDescriptor))        return 0;    QSocks5BindData *bindData = store.take(socketDescriptor);    if (bindData) {        if (bindData->controlSocket->thread() != QThread::currentThread()) {            qWarning("Can not access socks5 bind data from different thread");            return 0;        }    } else {        QSOCKS5_DEBUG << "__ERROR__ binddata == 0";    }    // stop the sweep timer if not needed    if (store.isEmpty()) {        killTimer(sweepTimerId);        sweepTimerId = -1;    }    return bindData;}void QSocks5BindStore::timerEvent(QTimerEvent * event){    QMutexLocker lock(&mutex);    if (event->timerId() == sweepTimerId) {        QSOCKS5_DEBUG << "QSocks5BindStore performing sweep";        QMutableHashIterator<int, QSocks5BindData *> it(store);        while (it.hasNext()) {            it.next();            if (it.value()->timeStamp.secsTo(QDateTime::currentDateTime()) > 350) {                QSOCKS5_DEBUG << "QSocks5BindStore removing JJJJ";                it.remove();            }        }    }}QSocks5Authenticator::QSocks5Authenticator(){}QSocks5Authenticator::~QSocks5Authenticator(){}char QSocks5Authenticator::methodId(){    return 0x00;}bool QSocks5Authenticator::beginAuthenticate(QTcpSocket *socket, bool *completed){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -