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

📄 qsocks5socketengine.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
bool QSocks5SocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol){    Q_D(QSocks5SocketEngine);    d->socketDescriptor = descriptorCounter.fetchAndAdd(1);    d->socketType = type;    d->socketProtocol = protocol;    return true;}bool QSocks5SocketEngine::initialize(int socketDescriptor, QAbstractSocket::SocketState socketState){    Q_D(QSocks5SocketEngine);    QSOCKS5_Q_DEBUG << "initialize" << socketDescriptor;    // this is only valid for the other side of a bind, nothing else is supported    if (socketState != QAbstractSocket::ConnectedState) {        //### must be connected state ???        return false;    }    QSocks5BindData *bindData = socks5BindStore()->retrieve(socketDescriptor);    if (bindData) {        d->socketState = socketState;        d->socketType = QAbstractSocket::TcpSocket;        d->connectData = new QSocks5ConnectData;        d->data = d->connectData;        d->mode = QSocks5SocketEnginePrivate::ConnectMode;        d->data->controlSocket = bindData->controlSocket;        bindData->controlSocket = 0;        d->data->controlSocket->setParent(this);        d->socketProtocol = d->data->controlSocket->localAddress().protocol();        d->data->authenticator = bindData->authenticator;        bindData->authenticator = 0;        d->localPort = bindData->localPort;        d->localAddress = bindData->localAddress;        d->peerPort = bindData->peerPort;        d->peerAddress = bindData->peerAddress;        delete bindData;        QObject::connect(d->data->controlSocket, SIGNAL(connected()), this, SLOT(_q_controlSocketConnected()));        QObject::connect(d->data->controlSocket, SIGNAL(readyRead()), this, SLOT(_q_controlSocketReadNotification()));        QObject::connect(d->data->controlSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(_q_controlSocketBytesWritten()));        QObject::connect(d->data->controlSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_q_controlSocketError(QAbstractSocket::SocketError)));        QObject::connect(d->data->controlSocket, SIGNAL(disconnected()), this, SLOT(_q_controlSocketDisconnected()));        QObject::connect(d->data->controlSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),                         this, SLOT(_q_controlSocketStateChanged(QAbstractSocket::SocketState)));        d->socks5State = QSocks5SocketEnginePrivate::Connected;        if (d->data->controlSocket->bytesAvailable() != 0)            d->_q_controlSocketReadNotification();        return true;    }    return false;}void QSocks5SocketEngine::setProxy(const QNetworkProxy &networkProxy){    Q_D(QSocks5SocketEngine);    d->proxyInfo = networkProxy;}int QSocks5SocketEngine::socketDescriptor() const{    Q_D(const QSocks5SocketEngine);    return d->socketDescriptor;}bool QSocks5SocketEngine::isValid() const{    Q_D(const QSocks5SocketEngine);    return d->socketType != QAbstractSocket::UnknownSocketType           && d->socketProtocol != QAbstractSocket::UnknownNetworkLayerProtocol           && d->socks5State != QSocks5SocketEnginePrivate::SocksError           && (d->socketError == QAbstractSocket::UnknownSocketError               || d->socketError == QAbstractSocket::SocketTimeoutError);}bool QSocks5SocketEngine::connectToHost(const QHostAddress &address, quint16 port){    Q_D(QSocks5SocketEngine);    QSOCKS5_DEBUG << "connectToHost" << address << ":" << port;    if (!d->data) {        if (socketType() == QAbstractSocket::TcpSocket) {            d->initialize(QSocks5SocketEnginePrivate::ConnectMode);#ifndef QT_NO_UDPSOCKET        } else if (socketType() == QAbstractSocket::UdpSocket) {            d->initialize(QSocks5SocketEnginePrivate::UdpAssociateMode);            // all udp needs to be bound            if (!bind(QHostAddress(QLatin1String("0.0.0.0")), 0))                return false;            d->peerAddress = address;            d->peerPort = port;            setState(QAbstractSocket::ConnectedState);            return true;#endif        } else {            //### something invalied            return false;        }    }    if (d->socks5State == QSocks5SocketEnginePrivate::unInitialized && d->socketState != QAbstractSocket::ConnectingState) {        setPeerAddress(address);        setPeerPort(port);        setState(QAbstractSocket::ConnectingState);        d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port());        return false;    } else if (d->socks5State == QSocks5SocketEnginePrivate::RequestSuccess) {        setState(QAbstractSocket::ConnectedState);        d->socks5State = QSocks5SocketEnginePrivate::Connected;        // check for pending data        if (d->data->controlSocket->bytesAvailable())            d->_q_controlSocketReadNotification();        return true;    } else if (d->socks5State == QSocks5SocketEnginePrivate::RequestError) {        setError(s5RAsSocketError(d->socks5Error), makeErrorString(d->socks5ErrorString));        setState(QAbstractSocket::UnconnectedState);        return false;    } else if (d->socks5State == QSocks5SocketEnginePrivate::ConnectError) {        setError(d->data->controlSocket->error(), d->data->controlSocket->errorString());        setState(QAbstractSocket::UnconnectedState);        return false;    } else if (d->socks5State == QSocks5SocketEnginePrivate::AuthenticatingError) {        setState(QAbstractSocket::UnconnectedState);        return false;    } else if (d->socketState == QAbstractSocket::ConnectingState && d->socks5State != QSocks5SocketEnginePrivate::RequestSuccess) {        QSOCKS5_DEBUG << "not yet connected";        return false;    } else {        // qDebug() << "unexpected call to contectToHost";    }    return false;}void QSocks5SocketEnginePrivate::_q_controlSocketConnected(){    QSOCKS5_DEBUG << "_q_controlSocketConnected";    QByteArray buf(3, 0);    buf[0] = S5_VERSION_5;    buf[1] = 0x01;    buf[2] = data->authenticator->methodId();    data->controlSocket->write(buf);    socks5State = AuthenticationMethodsSent;}void QSocks5SocketEnginePrivate::_q_controlSocketReadNotification(){    QSOCKS5_D_DEBUG << "_q_controlSocketReadNotification socks5state" <<  s5StateToString(socks5State)                    << "bytes available" << data->controlSocket->bytesAvailable();    if (data->controlSocket->bytesAvailable() == 0) {        QSOCKS5_D_DEBUG << "########## bogus read why do we get these ... on windows only";        return;    }    switch (socks5State) {        case AuthenticationMethodsSent:            parseAuthenticationMethodReply();            break;        case Authenticating:            parseAuthenticatingReply();            break;        case RequestMethodSent:            parseRequestMethodReply();            break;        case RequestSuccess:            if (mode == BindMode) {                // only get here if command is bind                parseNewConnection();            }            // else in conect mode but wating for second call to connectToHost            break;        case Connected: {            QByteArray buf;            if (!data->authenticator->unSeal(data->controlSocket, &buf)) {                // qDebug() << "unseal error maybe need to wait for more data";            }            if (buf.size()) {                QSOCKS5_DEBUG << dump(buf);                connectData->readBuffer += buf;                emitReadNotification();            }            break;        }        default:            QSOCKS5_DEBUG << "why a _q_controlSocketReadNotification ????";            break;    };}void QSocks5SocketEnginePrivate::_q_controlSocketBytesWritten(){    QSOCKS5_DEBUG << "_q_controlSocketBytesWritten";    if (socks5State != Connected        || (mode == ConnectMode        && data->controlSocket->bytesToWrite()))        return;    emitWriteNotification();    writeNotificationActivated = false;}void QSocks5SocketEnginePrivate::_q_controlSocketError(QAbstractSocket::SocketError error){    QSOCKS5_D_DEBUG << "controlSocketError" << error << data->controlSocket->errorString();    if (error == QAbstractSocket::RemoteHostClosedError) {        // clear the read buffer in connect mode so that bytes available returns 0        // if there already is a read notification pending then this will be porcessed first        if (mode == ConnectMode) {            socks5State = ControlSocketError;            if (!readNotificationPending)                connectData->readBuffer.clear();            emitReadNotification();        }    } else if (error == QAbstractSocket::ConnectionRefusedError        || error == QAbstractSocket::HostNotFoundError) {        socks5State = ConnectError;        emitWriteNotification();    }}void QSocks5SocketEnginePrivate::_q_controlSocketDisconnected(){    QSOCKS5_D_DEBUG << "_q_controlSocketDisconnected";}void QSocks5SocketEnginePrivate::_q_controlSocketStateChanged(QAbstractSocket::SocketState state){    QSOCKS5_D_DEBUG << "_q_controlSocketStateChanged" << state;}#ifndef QT_NO_UDPSOCKETvoid QSocks5SocketEnginePrivate::checkForDatagrams() const{    // udp should be unbuffered so we need to do some polling at certain points    if (udpData->udpSocket->hasPendingDatagrams())        const_cast<QSocks5SocketEnginePrivate *>(this)->_q_udpSocketReadNotification();}void QSocks5SocketEnginePrivate::_q_udpSocketReadNotification(){    QSOCKS5_D_DEBUG << "_q_udpSocketReadNotification()";    // check some state stuff    if (!udpData->udpSocket->hasPendingDatagrams()) {        QSOCKS5_D_DEBUG << "false read ??";        return;    }    while (udpData->udpSocket->hasPendingDatagrams()) {        QByteArray sealedBuf(udpData->udpSocket->pendingDatagramSize(), 0);        QSOCKS5_D_DEBUG << "new datagram";        udpData->udpSocket->readDatagram(sealedBuf.data(), sealedBuf.size());        QByteArray inBuf;        if (!data->authenticator->unSeal(sealedBuf, &inBuf)) {            QSOCKS5_D_DEBUG << "failed unsealing datagram discarding";            return;        }        QSOCKS5_DEBUG << dump(inBuf);        int pos = 0;        const char *buf = inBuf.constData();        if (inBuf.size() < 4) {            QSOCKS5_D_DEBUG << "bugus udp data, discarding";            return;        }        QSocks5RevivedDatagram datagram;        if (buf[pos++] != 0 || buf[pos++] != 0) {            QSOCKS5_D_DEBUG << "invalid datagram discarding";            return;        }        if (buf[pos++] != 0) { //### add fragmentation reading support            QSOCKS5_D_DEBUG << "don't support fragmentation yet disgarding";            return;        }        if (!qt_socks5_get_host_address_and_port(inBuf, &datagram.address, &datagram.port, &pos)) {            QSOCKS5_D_DEBUG << "failed to get address from datagram disgarding";            return;        }        datagram.data = QByteArray(&buf[pos], inBuf.size() - pos);        udpData->pendingDatagrams.enqueue(datagram);    }    emitReadNotification();}#endif // QT_NO_UDPSOCKETbool QSocks5SocketEngine::bind(const QHostAddress &address, quint16 port){    Q_D(QSocks5SocketEngine);    // when bind wee will block until the bind is finished as the info from the proxy server is needed    if (!d->data) {        if (socketType() == QAbstractSocket::TcpSocket) {            d->initialize(QSocks5SocketEnginePrivate::BindMode);#ifndef QT_NO_UDPSOCKET        } else if (socketType() == QAbstractSocket::UdpSocket) {            d->initialize(QSocks5SocketEnginePrivate::UdpAssociateMode);#endif        } else {            //### something invalid            return false;        }    }#ifndef QT_NO_UDPSOCKET    if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {        if (!d->udpData->udpSocket->bind(address, port)) {            QSOCKS5_Q_DEBUG << "local udp bind failed";            setError(d->udpData->udpSocket->error(), d->udpData->udpSocket->errorString());            return false;        }        d->localAddress = d->udpData->udpSocket->localAddress();        d->localPort = d->udpData->udpSocket->localPort();    } else#endif    if (d->mode == QSocks5SocketEnginePrivate::BindMode) {        d->localAddress = address;        d->localPort = port;    } else {        //### something invalid        return false;    }    int msecs = SOCKS5_BLOCKING_BIND_TIMEOUT;    QTime stopWatch;    stopWatch.start();    d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port());    if (!d->data->controlSocket->waitForConnected(qt_timeout_value(msecs, stopWatch.elapsed()))) {        if (d->data->controlSocket->error() != QAbstractSocket::SocketTimeoutError) {            setError(d->data->controlSocket->error(), d->data->controlSocket->errorString());        } else {            setError(QAbstractSocket::SocketTimeoutError, tr("Socks5 timeout error connecting to socks server"));        }        QSOCKS5_Q_DEBUG << "waitForConnected to proxy server" << d->data->controlSocket->errorString();        return false;    }    while (d->data->controlSocket->waitForReadyRead(qt_timeout_value(msecs, stopWatch.elapsed()))) {        // check error        if (d->socks5State == QSocks5SocketEnginePrivate::RequestSuccess) {            setState(QAbstractSocket::BoundState);#ifndef QT_NO_UDPSOCKET            if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {                d->udpData->associateAddress = d->localAddress;                d->localAddress = QHostAddress();                d->udpData->associatePort = d->localPort;                d->localPort = 0;                QUdpSocket dummy;                QNetworkProxy proxy;                proxy.setType(QNetworkProxy::NoProxy);                dummy.setProxy(proxy);                if (!dummy.bind()                    || writeDatagram(0,0, d->data->controlSocket->localAddress(), dummy.localPort()) != 0                    || !dummy.waitForReadyRead(qt_timeout_value(msecs, stopWatch.elapsed()))                    || dummy.readDatagram(0,0, &d->localAddress, &d->localPort) != 0) {                    QSOCKS5_DEBUG << "udp actual address and port lookup failed";                    //### reset and error                    return false;                }                QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ":" << d->localPort;            }#endif // QT_NO_UDPSOCKET            return true;        }        QSOCKS5_DEBUG << "looping";    }    // set error string = socks 5 timeout///###    delete d->udpSocket;///###    d->udpSocket = 0;    return false;}bool QSocks5SocketEngine::listen(){    Q_D(QSocks5SocketEngine);    QSOCKS5_Q_DEBUG << "listen()";    // check that we are in bound and then go to listening.    if (d->socketState == QAbstractSocket::BoundState) {        d->socketState = QAbstractSocket::ListeningState;        // check if we already have a connection        if (d->socks5State == QSocks5SocketEnginePrivate::BindSuccess)            d->emitReadNotification();        return true;    }    return false;}int QSocks5SocketEngine::accept(){    Q_D(QSocks5SocketEngine);    // check we are listing ---    QSOCKS5_Q_DEBUG << "accept()";    if (d->socks5State == QSocks5SocketEnginePrivate::BindSuccess) {        QSOCKS5_Q_DEBUG << "BindSuccess adding" << d->socketDescriptor << "to the bind store";        d->data->controlSocket->disconnect();        d->data->controlSocket->setParent(0);        d->bindData->localAddress = d->localAddress;        d->bindData->localPort = d->localPort;        int sd = d->socketDescriptor;        socks5BindStore()->add(sd, d->bindData);        d->data = 0;        d->bindData = 0;        d->socketDescriptor = 0;        //### do something about this socket layer ... set it closed and an error about why ...        // reset state and local port/address        d->socks5State = QSocks5SocketEnginePrivate::unInitialized; // ..??        d->socketState = QAbstractSocket::UnconnectedState;        return sd;    } else if (d->socks5State == QSocks5SocketEnginePrivate::BindError) {        // what now    } else if (d->socks5State == QSocks5SocketEnginePrivate::RequestSuccess) {        // accept was called to early ...    }    return -1;}void QSocks5SocketEngine::close(){

⌨️ 快捷键说明

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