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

📄 qsocks5socketengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    Q_UNUSED(socket);    *completed = true;    return true;}bool QSocks5Authenticator::continueAuthenticate(QTcpSocket *socket, bool *completed){    Q_UNUSED(socket);    *completed = true;    return true;}bool QSocks5Authenticator::seal(const QByteArray buf, QByteArray *sealedBuf){    *sealedBuf = buf;    return true;}bool QSocks5Authenticator::unSeal(const QByteArray sealedBuf, QByteArray *buf){    *buf = sealedBuf;    return true;}bool QSocks5Authenticator::unSeal(QTcpSocket *sealedSocket, QByteArray *buf){    return unSeal(sealedSocket->readAll(), buf);}QSocks5PasswordAuthenticator::QSocks5PasswordAuthenticator(const QString &userName, const QString &password){    this->userName = userName;    this->password = password;}char QSocks5PasswordAuthenticator::methodId(){    return 0x02;}bool QSocks5PasswordAuthenticator::beginAuthenticate(QTcpSocket *socket, bool *completed){    *completed = false;    QByteArray uname = userName.toLatin1();    QByteArray passwd = password.toLatin1();    QByteArray dataBuf(3 + uname.size() + passwd.size(), 0);    char *buf = dataBuf.data();    int pos = 0;    buf[pos++] = 0x01;    buf[pos++] = uname.size();    memcpy(&buf[pos], uname.data(), uname.size());    pos += uname.size();    buf[pos++] = passwd.size();    memcpy(&buf[pos], passwd.data(), passwd.size());    return socket->write(dataBuf) == dataBuf.size();}bool QSocks5PasswordAuthenticator::continueAuthenticate(QTcpSocket *socket, bool *completed){    *completed = false;    if (socket->bytesAvailable() < 2)        return true;    QByteArray buf = socket->read(2);    if (buf.at(0) == 0x01) {        *completed = true;        return buf.at(1) == 0x00;    }    return false;}QString QSocks5PasswordAuthenticator::errorString(){    return QLatin1String("Socks5 user name or password incorrect");}QSocks5SocketEnginePrivate::QSocks5SocketEnginePrivate()    : socks5State(unInitialized)    , readNotificationEnabled(false)    , writeNotificationEnabled(false)    , exceptNotificationEnabled(false)    , socketDescriptor(-1)    , data(0)    , connectData(0)#ifndef QT_NO_UDPSOCKET    , udpData(0)#endif    , bindData(0)    , readNotificationActivated(false)    , writeNotificationActivated(false)    , readNotificationPending(false)    , writeNotificationPending(false){    mode = NoMode;}QSocks5SocketEnginePrivate::~QSocks5SocketEnginePrivate(){}void QSocks5SocketEnginePrivate::initialize(Socks5Mode socks5Mode){    Q_Q(QSocks5SocketEngine);    mode = socks5Mode;    if (mode == ConnectMode) {        connectData = new QSocks5ConnectData;        data = connectData;#ifndef QT_NO_UDPSOCKET    } else if (mode == UdpAssociateMode) {        udpData = new QSocks5UdpAssociateData;        data = udpData;        udpData->udpSocket = new QUdpSocket(q);        QNetworkProxy proxy;        proxy.setType(QNetworkProxy::NoProxy);        udpData->udpSocket->setProxy(proxy);        QObject::connect(udpData->udpSocket, SIGNAL(readyRead()), q, SLOT(_q_udpSocketReadNotification()));#endif // QT_NO_UDPSOCKET    } else if (mode == BindMode) {        bindData = new QSocks5BindData;        data = bindData;    }    data->controlSocket = new QTcpSocket(q);    QNetworkProxy proxy;    proxy.setType(QNetworkProxy::NoProxy);    data->controlSocket->setProxy(proxy);    QObject::connect(data->controlSocket, SIGNAL(connected()), q, SLOT(_q_controlSocketConnected()));    QObject::connect(data->controlSocket, SIGNAL(readyRead()), q, SLOT(_q_controlSocketReadNotification()));    QObject::connect(data->controlSocket, SIGNAL(bytesWritten(qint64)), q, SLOT(_q_controlSocketBytesWritten()));    QObject::connect(data->controlSocket, SIGNAL(error(QAbstractSocket::SocketError)),                     q, SLOT(_q_controlSocketError(QAbstractSocket::SocketError)));    QObject::connect(data->controlSocket, SIGNAL(disconnected()), q, SLOT(_q_controlSocketDisconnected()));    QObject::connect(data->controlSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),                     q, SLOT(_q_controlSocketStateChanged(QAbstractSocket::SocketState)));    //### this should be some where else when authentication methods are public    if (!proxyInfo.user().isEmpty() || !proxyInfo.password().isEmpty()) {        data->authenticator = new QSocks5PasswordAuthenticator(proxyInfo.user(), proxyInfo.password());    } else {        data->authenticator = new QSocks5Authenticator();    }}void QSocks5SocketEnginePrivate::parseAuthenticationMethodReply(){    Q_Q(QSocks5SocketEngine);    // not enough data to begin    if (data->controlSocket->bytesAvailable() < 2)        return;    QByteArray buf(2, 0);    if (data->controlSocket->read(buf.data(), 2) != 2) {        QSOCKS5_D_DEBUG << "Control socket read failure";        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::NetworkError, QLatin1String("Socks5 read error on control socket"));        data->controlSocket->close();        emitWriteNotification();        return;    }    if (buf.at(0) != S5_VERSION_5) {        QSOCKS5_D_DEBUG << "Socks5 version incorrect";        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::NetworkError, QLatin1String("Socks5 version incorrect"));        data->controlSocket->close();        emitWriteNotification();        return;    }    if (uchar(buf.at(1)) == 0xFF) {        QSOCKS5_D_DEBUG << "Authentication method not supported";        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::SocketAccessError, QLatin1String("Socks5 host did not support authentication method."));        emitWriteNotification();        return;    }    if (buf.at(1) != data->authenticator->methodId()) {        QSOCKS5_D_DEBUG << "Authentication method was not what we sent";        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::SocketAccessError, QLatin1String("Socks5 host did not support authentication method."));        emitWriteNotification();        return;    }    bool AuthComplete = false;    if (!data->authenticator->beginAuthenticate(data->controlSocket, &AuthComplete)) {        QSOCKS5_D_DEBUG << "Authentication faled" << data->authenticator->errorString();        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::SocketAccessError, data->authenticator->errorString());        emitWriteNotification();        return;    }    if (AuthComplete) {        sendRequestMethod();        return;    }    socks5State = Authenticating;}void QSocks5SocketEnginePrivate::parseAuthenticatingReply(){    Q_Q(QSocks5SocketEngine);    bool authComplete = false;    if (!data->authenticator->continueAuthenticate(data->controlSocket, &authComplete)) {        QSOCKS5_D_DEBUG << "Authentication faled" << data->authenticator->errorString();        socks5State = AuthenticatingError;        q->setError(QAbstractSocket::SocketAccessError, data->authenticator->errorString());        emitWriteNotification();        return;    }    if (authComplete)        sendRequestMethod();}void QSocks5SocketEnginePrivate::sendRequestMethod(){    QHostAddress address;    quint16 port = 0;    char command = 0;    if (mode == ConnectMode) {        command = S5_CONNECT;        address = peerAddress;        port = peerPort;    } else if (mode == BindMode) {        command = S5_BIND;        address = localAddress;        port = localPort;    } else {#ifndef QT_NO_UDPSOCKET        command = S5_UDP_ASSOCIATE;        address = localAddress; //data->controlSocket->localAddress();        port = localPort;#endif    }    QByteArray buf;    buf.reserve(270); // big enough for domain name;    int pos = 0;    buf[pos++] = S5_VERSION_5;    buf[pos++] = command;    buf[pos++] = 0x00;    if (!qt_socks5_set_host_address_and_port(address, port, &buf, &pos)) {        QSOCKS5_DEBUG << "error setting address" << address << " : " << port;        //### set error code ....        return;    }    QSOCKS5_DEBUG << "sending" << dump(buf);    QByteArray sealedBuf;    if (!data->authenticator->seal(buf, &sealedBuf)) {        // ### Handle this error.    }    data->controlSocket->write(sealedBuf);    data->controlSocket->flush();    socks5State = RequestMethodSent;}void QSocks5SocketEnginePrivate::parseRequestMethodReply(){    QSOCKS5_DEBUG << "parseRequestMethodReply()";    QByteArray inBuf;    if (!data->authenticator->unSeal(data->controlSocket, &inBuf)) {        // ### check error and not just not enough data        QSOCKS5_DEBUG << "unSeal failed, needs more data";        return;    }    QSOCKS5_DEBUG << dump(inBuf);    int pos = 0;    const char *buf = inBuf.constData();    if (inBuf.size() < 2) {        QSOCKS5_DEBUG << "need more data for request reply header .. put this data somewhere";        return;    }    if (buf[pos++] != S5_VERSION_5) {        QSOCKS5_DEBUG << "totally lost";    }    if (buf[pos++] != S5_SUCCESS ) {        socks5Error = Socks5Error(buf[pos-1]);        socks5State = RequestError;        socks5ErrorString = s5RequestErrorToString(socks5Error);        QSOCKS5_DEBUG <<  "Request error :" << s5RequestErrorToString(socks5Error);        emitWriteNotification();        return;    }    if (buf[pos++] != 0x00) {        QSOCKS5_DEBUG << "totally lost";    }    if (!qt_socks5_get_host_address_and_port(inBuf, &localAddress, &localPort, &pos)) {        QSOCKS5_DEBUG << "error getting address";        //### set error code ....        return;    }    // need a better place to keep this stuff and any others untill connect called again    // should use peek    inBuf.remove(0, pos);    for (int i = inBuf.size() - 1; i >= 0 ; --i)        data->controlSocket->ungetChar(inBuf.at(i));    socks5State = RequestSuccess;    // fire writeNotifier for connect and wait for the next call to conectTOHost    if (mode == ConnectMode)        emitWriteNotification();}void QSocks5SocketEnginePrivate::parseNewConnection(){    QSOCKS5_D_DEBUG << "parseNewConnection()";    // only emit readyRead if in listening state ...    QByteArray inBuf;    if (!data->authenticator->unSeal(data->controlSocket, &inBuf)) {        // ### check error and not just not enough data        QSOCKS5_DEBUG << "unSeal failed, needs more data";        return;    }    QSOCKS5_D_DEBUG << dump(inBuf);    int pos = 0;    const char *buf = inBuf.constData();    if (inBuf.length() < 2) {        QSOCKS5_D_DEBUG << "need more data for request reply header .. put this data somewhere";        return;    }    if (buf[pos++] != S5_VERSION_5) {        QSOCKS5_D_DEBUG << "totally lost";    }    if (buf[pos++] != S5_SUCCESS) {        QSOCKS5_D_DEBUG <<  "Request error :" << s5RequestErrorToString(buf[pos-1]);        socks5State = BindError;        socks5Error = Socks5Error(buf[pos-1]);        socks5ErrorString = s5RequestErrorToString(socks5Error);        // #### now what        return;    }    if (buf[pos++] != 0x00) {        QSOCKS5_D_DEBUG << "totally lost";    }    if (!qt_socks5_get_host_address_and_port(inBuf, &bindData->peerAddress, &bindData->peerPort, &pos)) {        QSOCKS5_D_DEBUG << "error getting address";        //### set error code ....        return;    }    // need a better place to keep this stuff and any others untill connect called again    // should use peek    inBuf.remove(0, pos);    for (int i = inBuf.size() - 1; i >= 0 ; --i)        data->controlSocket->ungetChar(inBuf.at(i));    // got a successful reply    socks5State = BindSuccess;    if (socketState == QAbstractSocket::ListeningState)        emitReadNotification();}void QSocks5SocketEnginePrivate::_q_emitPendingReadNotification(){    Q_Q(QSocks5SocketEngine);    readNotificationPending = false;    if (readNotificationEnabled) {        QSOCKS5_D_DEBUG << "emitting readNotification";        QPointer<QSocks5SocketEngine> qq = q;        emit q->readNotification();        if (!qq)            return;        // check if there needs to be a new zero read notifcation        if (socks5State == ControlSocketError            && data->controlSocket->error() == QAbstractSocket::RemoteHostClosedError) {            connectData->readBuffer.clear();            emitReadNotification();        }    }}void QSocks5SocketEnginePrivate::emitReadNotification(){    Q_Q(QSocks5SocketEngine);    readNotificationActivated = true;    if (readNotificationEnabled && !readNotificationPending) {        QSOCKS5_D_DEBUG << "queueing readNotification";        readNotificationPending = true;        QMetaObject::invokeMethod(q, "_q_emitPendingReadNotification", Qt::QueuedConnection);    }}void QSocks5SocketEnginePrivate::_q_emitPendingWriteNotification(){    writeNotificationPending = false;    Q_Q(QSocks5SocketEngine);    if (writeNotificationEnabled) {        QSOCKS5_D_DEBUG << "emitting writeNotification";        emit q->writeNotification();    }}void QSocks5SocketEnginePrivate::emitWriteNotification(){    Q_Q(QSocks5SocketEngine);    writeNotificationActivated = true;    if (writeNotificationEnabled && !writeNotificationPending) {        QSOCKS5_D_DEBUG << "queueing writeNotification";        writeNotificationPending = true;        QMetaObject::invokeMethod(q, "_q_emitPendingWriteNotification", Qt::QueuedConnection);    }}QSocks5SocketEngine::QSocks5SocketEngine(QObject *parent):QAbstractSocketEngine(*new QSocks5SocketEnginePrivate(), parent){}QSocks5SocketEngine::~QSocks5SocketEngine(){    Q_D(QSocks5SocketEngine);    if (d->data) {        delete d->data->authenticator;        delete d->data->controlSocket;    }    if (d->connectData)        delete d->connectData;#ifndef QT_NO_UDPSOCKET    if (d->udpData) {        delete d->udpData->udpSocket;        delete d->udpData;    }#endif    if (d->bindData)        delete d->bindData;}static QBasicAtomic descriptorCounter = Q_ATOMIC_INIT(1);

⌨️ 快捷键说明

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