/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsocks5socketengine_p.h"

#include "qtcpsocket.h"
#include "qudpsocket.h"
#include "qtcpserver.h"
#include "qdebug.h"
#include "qhash.h"
#include "qqueue.h"
#include "qelapsedtimer.h"
#include "qmutex.h"
#include "qthread.h"
#include "qcoreapplication.h"
#include "qurl.h"
#include "qauthenticator.h"
#include "private/qiodevice_p.h"
#include "private/qringbuffer_p.h"
#include <qendian.h>
#include <qnetworkinterface.h>

QT_BEGIN_NAMESPACE

static const int MaxWriteBufferSize = 128*1024;

//#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)

#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 0x08

#define S5_AUTHMETHOD_NONE 0x00
#define S5_AUTHMETHOD_PASSWORD 0x02
#define S5_AUTHMETHOD_NOTACCEPTABLE 0xFF

#define S5_PASSWORDAUTH_VERSION 0x01

#ifdef QSOCKS5SOCKETLAYER_DEBUG
#  define QSOCKS5_Q_DEBUG qDebug() << this
#  define QSOCKS5_D_DEBUG qDebug() << q_ptr
#  define QSOCKS5_DEBUG qDebug() << "[QSocks5]"
static QString s5StateToString(QSocks5SocketEnginePrivate::Socks5State s)
{
    switch (s) {
    case QSocks5SocketEnginePrivate::Uninitialized: return QLatin1String("Uninitialized");
    case QSocks5SocketEnginePrivate::ConnectError: return QLatin1String("ConnectError");
    case QSocks5SocketEnginePrivate::AuthenticationMethodsSent: return QLatin1String("AuthenticationMethodsSent");
    case QSocks5SocketEnginePrivate::Authenticating: return QLatin1String("Authenticating");
    case QSocks5SocketEnginePrivate::AuthenticatingError: return QLatin1String("AuthenticatingError");
    case QSocks5SocketEnginePrivate::RequestMethodSent: return QLatin1String("RequestMethodSent");
    case QSocks5SocketEnginePrivate::RequestError: return QLatin1String("RequestError");
    case QSocks5SocketEnginePrivate::Connected: return QLatin1String("Connected");
    case QSocks5SocketEnginePrivate::UdpAssociateSuccess: return QLatin1String("UdpAssociateSuccess");
    case QSocks5SocketEnginePrivate::BindSuccess: return QLatin1String("BindSuccess");
    case QSocks5SocketEnginePrivate::ControlSocketError: return QLatin1String("ControlSocketError");
    case QSocks5SocketEnginePrivate::SocksError: return QLatin1String("SocksError");
    case QSocks5SocketEnginePrivate::HostNameLookupError: return QLatin1String("HostNameLookupError");
    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);
}

#else
#  define QSOCKS5_DEBUG if (0) qDebug()
#  define QSOCKS5_Q_DEBUG if (0) qDebug()
#  define QSOCKS5_D_DEBUG if (0) qDebug()

static inline QString s5StateToString(QSocks5SocketEnginePrivate::Socks5State) { return QString(); }
static inline QString dump(const QByteArray &) { return QString(); }
#endif

/*
   inserts 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)
{
    QSOCKS5_DEBUG << "setting [" << address << ':' << port << ']';

    union {
        quint16 port;
        quint32 ipv4;
        QIPv6Address ipv6;
        char ptr;
    } data;

    // add address
    if (address.protocol() == QAbstractSocket::IPv4Protocol) {
        data.ipv4 = qToBigEndian<quint32>(address.toIPv4Address());
        pBuf->append(S5_IP_V4);
        pBuf->append(QByteArray::fromRawData(&data.ptr, sizeof data.ipv4));
    } else if (address.protocol() == QAbstractSocket::IPv6Protocol) {
        data.ipv6 = address.toIPv6Address();
        pBuf->append(S5_IP_V6);
        pBuf->append(QByteArray::fromRawData(&data.ptr, sizeof data.ipv6));
    } else {
        return false;
    }

    // add port
    data.port = qToBigEndian<quint16>(port);
    pBuf->append(QByteArray::fromRawData(&data.ptr, sizeof data.port));
    return true;
}

/*
   like above, but for a hostname
*/
static bool qt_socks5_set_host_name_and_port(const QString &hostname, quint16 port, QByteArray *pBuf)
{
    QSOCKS5_DEBUG << "setting [" << hostname << ':' << port << ']';

    QByteArray encodedHostName = QUrl::toAce(hostname);
    QByteArray &buf = *pBuf;

    if (encodedHostName.length() > 255)
        return false;

    buf.append(S5_DOMAINNAME);
    buf.append(uchar(encodedHostName.length()));
    buf.append(encodedHostName);

    // add port
    union {
        quint16 port;
        char ptr;
    } data;
    data.port = qToBigEndian<quint16>(port);
    buf.append(QByteArray::fromRawData(&data.ptr, sizeof data.port));

    return true;
}


/*
   retrives the host address in buf at pos and updates pos.
   return 1 if OK, 0 if need more data, -1 if error
   if the func fails the value of the address and the pos is undefined
*/
static int qt_socks5_get_host_address_and_port(const QByteArray &buf, QHostAddress *pAddress, quint16 *pPort, int *pPos)
{
    int ret = -1;
    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 0;
    }
    if (pBuf[pos] == S5_IP_V4) {
        pos++;
        if (buf.size() - pos < 4) {
            QSOCKS5_DEBUG << "need more data for ip4 address";
            return 0;
        }
        address.setAddress(qFromBigEndian<quint32>(&pBuf[pos]));
        pos += 4;
        ret = 1;
    } else if (pBuf[pos] == S5_IP_V6) {
        pos++;
        if (buf.size() - pos < 16) {
            QSOCKS5_DEBUG << "need more data for ip6 address";
            return 0;
        }
        QIPv6Address add;
        for (int i = 0; i < 16; ++i)
            add[i] = buf[pos++];
        address.setAddress(add);
        ret = 1;
    } else if (pBuf[pos] == S5_DOMAINNAME){
        // just skip it
        pos++;
        qDebug() << "skipping hostname of len" << uint(pBuf[pos]);
        pos += uchar(pBuf[pos]);
    } else {
        QSOCKS5_DEBUG << "invalid address type" << (int)pBuf[pos];
        ret = -1;
    }

    if (ret == 1) {
        if (buf.size() - pos < 2) {
            QSOCKS5_DEBUG << "need more data for port";
            return 0;
        }
        port = qFromBigEndian<quint16>(&pBuf[pos]);
        pos += 2;
    }

    if (ret == 1) {
        QSOCKS5_DEBUG << "got [" << address << ':' << port << ']';
        *pAddress = address;
        *pPort = port;
        *pPos = pos;
    }

    return ret;
}

struct QSocks5Data
{
    QTcpSocket *controlSocket;
    QSocks5Authenticator *authenticator;
};

struct QSocks5ConnectData : public QSocks5Data
{
    QRingBuffer readBuffer;
};

struct QSocks5BindData : public QSocks5Data
{
    QHostAddress localAddress;
    quint16 localPort;
    QHostAddress peerAddress;
    quint16 peerPort;
    QElapsedTimer timeStamp;
};

struct QSocks5RevivedDatagram
{
    QByteArray data;
    QHostAddress address;
    quint16 port;
};

#ifndef QT_NO_UDPSOCKET
struct QSocks5UdpAssociateData : public QSocks5Data
{
    QUdpSocket *udpSocket;
    QHostAddress associateAddress;
    quint16 associatePort;
    QQueue<QSocks5RevivedDatagram> pendingDatagrams;
};
#endif

// needs to be thread safe
class QSocks5BindStore : public QObject
{
public:
    QSocks5BindStore();
    ~QSocks5BindStore();

    void add(qintptr socketDescriptor, QSocks5BindData *bindData);
    bool contains(qintptr socketDescriptor);
    QSocks5BindData *retrieve(qintptr socketDescriptor);

protected:
    void timerEvent(QTimerEvent * event) override;

    QRecursiveMutex mutex;
    int sweepTimerId = -1;
    //socket descriptor, data, timestamp
    QHash<int, QSocks5BindData *> store;
};

Q_GLOBAL_STATIC(QSocks5BindStore, socks5BindStore)

QSocks5BindStore::QSocks5BindStore()
{
    QCoreApplication *app = QCoreApplication::instance();
    if (app && app->thread() != thread())
        moveToThread(app->thread());
}

QSocks5BindStore::~QSocks5BindStore()
{
}

void QSocks5BindStore::add(qintptr socketDescriptor, QSocks5BindData *bindData)
{
    QMutexLocker lock(&mutex);
    if (store.contains(socketDescriptor)) {
        // qDebug("delete it");
    }
    bindData->timeStamp.start();
    store.insert(socketDescriptor, bindData);
    // start sweep timer if not started
    if (sweepTimerId == -1)
        sweepTimerId = startTimer(60000);
}

bool QSocks5BindStore::contains(qintptr socketDescriptor)
{
    QMutexLocker lock(&mutex);
    return store.contains(socketDescriptor);
}

QSocks5BindData *QSocks5BindStore::retrieve(qintptr socketDescriptor)
{
    QMutexLocker lock(&mutex);
    const auto it = store.constFind(socketDescriptor);
    if (it == store.cend())
        return nullptr;
    QSocks5BindData *bindData = it.value();
    store.erase(it);
    if (bindData) {
        if (bindData->controlSocket->thread() != QThread::currentThread()) {
            qWarning("Cannot access socks5 bind data from different thread");
            return nullptr;
        }
    } 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";
        for (auto it = store.begin(), end = store.end(); it != end;) {
            if (it.value()->timeStamp.hasExpired(350000)) {
                QSOCKS5_DEBUG << "QSocks5BindStore removing JJJJ";
                it = store.erase(it);
            } else {
                ++it;
            }
        }
    }
}

QSocks5Authenticator::QSocks5Authenticator()
{
}

QSocks5Authenticator::~QSocks5Authenticator()
{
}

char QSocks5Authenticator::methodId()
{
    return 0x00;
}

bool QSocks5Authenticator::beginAuthenticate(QTcpSocket *socket, bool *completed)
{
    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++] = S5_PASSWORDAUTH_VERSION;
    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) == S5_PASSWORDAUTH_VERSION && buf.at(1) == 0x00) {
        *completed = true;
        return true;
    }

    // must disconnect
    socket->close();
    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(nullptr)
    , connectData(nullptr)
#ifndef QT_NO_UDPSOCKET
    , udpData(nullptr)
#endif
    , bindData(nullptr)
    , readNotificationActivated(false)
    , writeNotificationActivated(false)
    , readNotificationPending(false)
    , writeNotificationPending(false)
    , connectionNotificationPending(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);
#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
        udpData->udpSocket->setProperty("_q_networksession", q->property("_q_networksession"));
#endif
        udpData->udpSocket->setProxy(QNetworkProxy::NoProxy);
        QObject::connect(udpData->udpSocket, SIGNAL(readyRead()),
                         q, SLOT(_q_udpSocketReadNotification()),
                         Qt::DirectConnection);
#endif // QT_NO_UDPSOCKET
    } else if (mode == BindMode) {
        bindData = new QSocks5BindData;
        data = bindData;
    }

    data->controlSocket = new QTcpSocket(q);
#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
    data->controlSocket->setProperty("_q_networksession", q->property("_q_networksession"));
#endif
    data->controlSocket->setProxy(QNetworkProxy::NoProxy);
    QObject::connect(data->controlSocket, SIGNAL(connected()), q, SLOT(_q_controlSocketConnected()),
                     Qt::DirectConnection);
    QObject::connect(data->controlSocket, SIGNAL(readyRead()), q, SLOT(_q_controlSocketReadNotification()),
                     Qt::DirectConnection);
    QObject::connect(data->controlSocket, SIGNAL(bytesWritten(qint64)), q, SLOT(_q_controlSocketBytesWritten()),
                     Qt::DirectConnection);
    QObject::connect(data->controlSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
                     q, SLOT(_q_controlSocketErrorOccurred(QAbstractSocket::SocketError)),
                     Qt::DirectConnection);
    QObject::connect(data->controlSocket, SIGNAL(disconnected()), q, SLOT(_q_controlSocketDisconnected()),
                     Qt::DirectConnection);
    QObject::connect(data->controlSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                     q, SLOT(_q_controlSocketStateChanged(QAbstractSocket::SocketState)),
                     Qt::DirectConnection);

    if (!proxyInfo.user().isEmpty() || !proxyInfo.password().isEmpty()) {
        QSOCKS5_D_DEBUG << "using username/password authentication; user =" << proxyInfo.user();
        data->authenticator = new QSocks5PasswordAuthenticator(proxyInfo.user(), proxyInfo.password());
    } else {
        QSOCKS5_D_DEBUG << "not using authentication";
        data->authenticator = new QSocks5Authenticator();
    }
}

void QSocks5SocketEnginePrivate::setErrorState(Socks5State state, const QString &extraMessage)
{
    Q_Q(QSocks5SocketEngine);

    switch (state) {
    case Uninitialized:
    case Authenticating:
    case AuthenticationMethodsSent:
    case RequestMethodSent:
    case Connected:
    case UdpAssociateSuccess:
    case BindSuccess:
        // these aren't error states
        return;

    case ConnectError:
    case ControlSocketError: {
        QAbstractSocket::SocketError controlSocketError = data->controlSocket->error();
        if (socks5State != Connected) {
            switch (controlSocketError) {
            case QAbstractSocket::ConnectionRefusedError:
                q->setError(QAbstractSocket::ProxyConnectionRefusedError,
                             QSocks5SocketEngine::tr("Connection to proxy refused"));
                break;
            case QAbstractSocket::RemoteHostClosedError:
                q->setError(QAbstractSocket::ProxyConnectionClosedError,
                             QSocks5SocketEngine::tr("Connection to proxy closed prematurely"));
                break;
            case QAbstractSocket::HostNotFoundError:
                q->setError(QAbstractSocket::ProxyNotFoundError,
                             QSocks5SocketEngine::tr("Proxy host not found"));
                break;
            case QAbstractSocket::SocketTimeoutError:
                if (state == ConnectError) {
                    q->setError(QAbstractSocket::ProxyConnectionTimeoutError,
                                 QSocks5SocketEngine::tr("Connection to proxy timed out"));
                    break;
                }
                Q_FALLTHROUGH();
            default:
                q->setError(controlSocketError, data->controlSocket->errorString());
                break;
            }
        } else {
            q->setError(controlSocketError, data->controlSocket->errorString());
        }
        break;
    }

    case AuthenticatingError:
        q->setError(QAbstractSocket::ProxyAuthenticationRequiredError,
                    extraMessage.isEmpty() ?
                     QSocks5SocketEngine::tr("Proxy authentication failed") :
                     QSocks5SocketEngine::tr("Proxy authentication failed: %1").arg(extraMessage));
        break;

    case RequestError:
        // error code set by caller (overload)
        break;

    case SocksError:
        q->setError(QAbstractSocket::ProxyProtocolError,
                     QSocks5SocketEngine::tr("SOCKS version 5 protocol error"));
        break;

    case HostNameLookupError:
        q->setError(QAbstractSocket::HostNotFoundError,
                    QAbstractSocket::tr("Host not found"));
        break;
    }

    q->setState(QAbstractSocket::UnconnectedState);
    socks5State = state;
}

void QSocks5SocketEnginePrivate::setErrorState(Socks5State state, Socks5Error socks5error)
{
    Q_Q(QSocks5SocketEngine);
    switch (socks5error) {
    case SocksFailure:
        q->setError(QAbstractSocket::NetworkError,
                     QSocks5SocketEngine::tr("General SOCKSv5 server failure"));
        break;
    case ConnectionNotAllowed:
        q->setError(QAbstractSocket::SocketAccessError,
                     QSocks5SocketEngine::tr("Connection not allowed by SOCKSv5 server"));
        break;
    case NetworkUnreachable:
        q->setError(QAbstractSocket::NetworkError,
                    QAbstractSocket::tr("Network unreachable"));
        break;
    case HostUnreachable:
        q->setError(QAbstractSocket::HostNotFoundError,
                    QAbstractSocket::tr("Host not found"));
        break;
    case ConnectionRefused:
        q->setError(QAbstractSocket::ConnectionRefusedError,
                    QAbstractSocket::tr("Connection refused"));
        break;
    case TTLExpired:
        q->setError(QAbstractSocket::NetworkError,
                     QSocks5SocketEngine::tr("TTL expired"));
        break;
    case CommandNotSupported:
        q->setError(QAbstractSocket::UnsupportedSocketOperationError,
                     QSocks5SocketEngine::tr("SOCKSv5 command not supported"));
        break;
    case AddressTypeNotSupported:
        q->setError(QAbstractSocket::UnsupportedSocketOperationError,
                     QSocks5SocketEngine::tr("Address type not supported"));
        break;

    default:
        q->setError(QAbstractSocket::UnknownSocketError,
                     QSocks5SocketEngine::tr("Unknown SOCKSv5 proxy error code 0x%1").arg(int(socks5error), 16));
        break;
    }

    setErrorState(state, QString());
}

void QSocks5SocketEnginePrivate::reauthenticate()
{
    Q_Q(QSocks5SocketEngine);

    // we require authentication
    QAuthenticator auth;
    q->proxyAuthenticationRequired(proxyInfo, &auth);

    if (!auth.user().isEmpty() || !auth.password().isEmpty()) {
        // we have new credentials, let's try again
        QSOCKS5_DEBUG << "authentication failure: retrying connection";
        socks5State = QSocks5SocketEnginePrivate::Uninitialized;

        delete data->authenticator;
        proxyInfo.setUser(auth.user());
        proxyInfo.setPassword(auth.password());
        data->authenticator = new QSocks5PasswordAuthenticator(proxyInfo.user(), proxyInfo.password());

        {
            const QSignalBlocker blocker(data->controlSocket);
            data->controlSocket->abort();
        }
        data->controlSocket->connectToHost(proxyInfo.hostName(), proxyInfo.port());
    } else {
        // authentication failure

        setErrorState(AuthenticatingError);
        data->controlSocket->close();
        emitConnectionNotification();
    }
}

void QSocks5SocketEnginePrivate::parseAuthenticationMethodReply()
{
    // not enough data to begin
    if (data->controlSocket->bytesAvailable() < 2)
        return;

    QByteArray buf = data->controlSocket->read(2);
    if (buf.at(0) != S5_VERSION_5) {
        QSOCKS5_D_DEBUG << "Socks5 version incorrect";
        setErrorState(SocksError);
        data->controlSocket->close();
        emitConnectionNotification();
        return;
    }

    bool authComplete = false;
    if (uchar(buf.at(1)) == S5_AUTHMETHOD_NONE) {
        authComplete = true;
    } else if (uchar(buf.at(1)) == S5_AUTHMETHOD_NOTACCEPTABLE) {
        reauthenticate();
        return;
    } else if (buf.at(1) != data->authenticator->methodId()
               || !data->authenticator->beginAuthenticate(data->controlSocket, &authComplete)) {
        setErrorState(AuthenticatingError, QLatin1String("Socks5 host did not support authentication method."));
        socketError = QAbstractSocket::SocketAccessError; // change the socket error
        emitConnectionNotification();
        return;
    }

    if (authComplete)
        sendRequestMethod();
    else
        socks5State = Authenticating;
}

void QSocks5SocketEnginePrivate::parseAuthenticatingReply()
{
    bool authComplete = false;
    if (!data->authenticator->continueAuthenticate(data->controlSocket, &authComplete)) {
        reauthenticate();
        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;
    buf.append(char(S5_VERSION_5));
    buf.append(command);
    buf.append('\0');
    if (peerName.isEmpty() && !qt_socks5_set_host_address_and_port(address, port, &buf)) {
        QSOCKS5_DEBUG << "error setting address" << address << " : " << port;
        //### set error code ....
        return;
    } else if (!peerName.isEmpty() && !qt_socks5_set_host_name_and_port(peerName, port, &buf)) {
        QSOCKS5_DEBUG << "error setting peer name" << peerName << " : " << 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()
{
    Q_Q(QSocks5SocketEngine);
    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;
    }

    inBuf.prepend(receivedHeaderFragment);
    receivedHeaderFragment.clear();
    QSOCKS5_DEBUG << dump(inBuf);
    if (inBuf.size() < 3) {
        QSOCKS5_DEBUG << "need more data for request reply header .. put this data somewhere";
        receivedHeaderFragment = inBuf;
        return;
    }

    QHostAddress address;
    quint16 port = 0;

    if (inBuf.at(0) != S5_VERSION_5 || inBuf.at(2) != 0x00) {
        QSOCKS5_DEBUG << "socks protocol error";
        setErrorState(SocksError);
    } else if (inBuf.at(1) != S5_SUCCESS) {
        Socks5Error socks5Error = Socks5Error(inBuf.at(1));
        QSOCKS5_DEBUG <<  "Request error :" << socks5Error;
        if ((socks5Error == SocksFailure || socks5Error == ConnectionNotAllowed)
            && !peerName.isEmpty()) {
            // Dante seems to use this error code to indicate hostname resolution failure
            setErrorState(HostNameLookupError);
        } else {
            setErrorState(RequestError, socks5Error);
        }
    } else {
        // connection success, retrieve the remote addresses
        int pos = 3;
        int err = qt_socks5_get_host_address_and_port(inBuf, &address, &port, &pos);
        if (err == -1) {
            QSOCKS5_DEBUG << "error getting address";
            setErrorState(SocksError);
        } else if (err == 0) {
            //need more data
            receivedHeaderFragment = inBuf;
            return;
        } else {
            inBuf.remove(0, pos);
            for (int i = inBuf.size() - 1; i >= 0 ; --i)
                data->controlSocket->ungetChar(inBuf.at(i));
        }
    }

    if (socks5State == RequestMethodSent) {
        // no error
        localAddress = address;
        localPort = port;

        if (mode == ConnectMode) {
            inboundStreamCount = outboundStreamCount = 1;
            socks5State = Connected;
            // notify the upper layer that we're done
            q->setState(QAbstractSocket::ConnectedState);
            emitConnectionNotification();
        } else if (mode == BindMode) {
            socks5State = BindSuccess;
            q->setState(QAbstractSocket::ListeningState);
        } else {
            socks5State = UdpAssociateSuccess;
        }
    } else if (socks5State == BindSuccess) {
        // no error and we got a connection
        bindData->peerAddress = address;
        bindData->peerPort = port;

        emitReadNotification();
    } else {
        // got an error
        data->controlSocket->close();
        emitConnectionNotification();
    }
}

void QSocks5SocketEnginePrivate::_q_emitPendingReadNotification()
{
    Q_Q(QSocks5SocketEngine);
    readNotificationPending = false;
    if (readNotificationEnabled) {
        QSOCKS5_D_DEBUG << "emitting readNotification";
        QPointer<QSocks5SocketEngine> qq = q;
        q->readNotification();
        if (!qq)
            return;
        // check if there needs to be a new zero read notification
        if (data && data->controlSocket->state() == QAbstractSocket::UnconnectedState
                && 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";
        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);
    }
}

void QSocks5SocketEnginePrivate::_q_emitPendingConnectionNotification()
{
    connectionNotificationPending = false;
    Q_Q(QSocks5SocketEngine);
    QSOCKS5_D_DEBUG << "emitting connectionNotification";
    q->connectionNotification();
}

void QSocks5SocketEnginePrivate::emitConnectionNotification()
{
    Q_Q(QSocks5SocketEngine);
    QSOCKS5_D_DEBUG << "queueing connectionNotification";
    connectionNotificationPending = true;
    QMetaObject::invokeMethod(q, "_q_emitPendingConnectionNotification", 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 int nextDescriptor()
{
    static QBasicAtomicInt counter;
    return 1 + counter.fetchAndAddRelaxed(1);
}

bool QSocks5SocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol)
{
    Q_D(QSocks5SocketEngine);

    d->socketDescriptor = nextDescriptor();

    d->socketType = type;
    d->socketProtocol = protocol;

    return true;
}

bool QSocks5SocketEngine::initialize(qintptr 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 = QAbstractSocket::ConnectedState;
        d->socketType = QAbstractSocket::TcpSocket;
        d->connectData = new QSocks5ConnectData;
        d->data = d->connectData;
        d->mode = QSocks5SocketEnginePrivate::ConnectMode;
        d->data->controlSocket = bindData->controlSocket;
        bindData->controlSocket = nullptr;
        d->data->controlSocket->setParent(this);
        d->socketProtocol = d->data->controlSocket->localAddress().protocol();
        d->data->authenticator = bindData->authenticator;
        bindData->authenticator = nullptr;
        d->localPort = bindData->localPort;
        d->localAddress = bindData->localAddress;
        d->peerPort = bindData->peerPort;
        d->peerAddress = bindData->peerAddress;
        d->inboundStreamCount = d->outboundStreamCount = 1;
        delete bindData;

        QObject::connect(d->data->controlSocket, SIGNAL(connected()), this, SLOT(_q_controlSocketConnected()),
                         Qt::DirectConnection);
        QObject::connect(d->data->controlSocket, SIGNAL(readyRead()), this, SLOT(_q_controlSocketReadNotification()),
                         Qt::DirectConnection);
        QObject::connect(d->data->controlSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(_q_controlSocketBytesWritten()),
                         Qt::DirectConnection);
        QObject::connect(d->data->controlSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(_q_controlSocketErrorOccurred(QAbstractSocket::SocketError)),
                         Qt::DirectConnection);
        QObject::connect(d->data->controlSocket, SIGNAL(disconnected()), this, SLOT(_q_controlSocketDisconnected()),
                         Qt::DirectConnection);
        QObject::connect(d->data->controlSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
                         this, SLOT(_q_controlSocketStateChanged(QAbstractSocket::SocketState)),
                         Qt::DirectConnection);

        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;
}

qintptr QSocks5SocketEngine::socketDescriptor() const
{
    Q_D(const QSocks5SocketEngine);
    return d->socketDescriptor;
}

bool QSocks5SocketEngine::isValid() const
{
    Q_D(const QSocks5SocketEngine);
    return d->socketType != QAbstractSocket::UnknownSocketType
           && d->socks5State != QSocks5SocketEnginePrivate::SocksError
           && (d->socketError == QAbstractSocket::UnknownSocketError
               || d->socketError == QAbstractSocket::SocketTimeoutError
               || d->socketError == QAbstractSocket::UnfinishedSocketOperationError);
}

bool QSocks5SocketEngine::connectInternal()
{
    Q_D(QSocks5SocketEngine);

    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;

            setState(QAbstractSocket::ConnectedState);
            return true;
#endif
        } else {
            qFatal("QSocks5SocketEngine::connectToHost: in QTcpServer mode");
            return false;
        }
    }

    if (d->socketState != QAbstractSocket::ConnectingState) {
        if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized
            // We may have new auth credentials since an earlier failure:
         || d->socks5State == QSocks5SocketEnginePrivate::AuthenticatingError) {
            setState(QAbstractSocket::ConnectingState);
            //limit buffer in internal socket, data is buffered in the external socket under application control
            d->data->controlSocket->setReadBufferSize(65536);
        }

        d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port());
    }

    return false;
}

bool QSocks5SocketEngine::connectToHost(const QHostAddress &address, quint16 port)
{
    Q_D(QSocks5SocketEngine);
    QSOCKS5_DEBUG << "connectToHost" << address << ':' << port;

    setPeerAddress(address);
    setPeerPort(port);
    d->peerName.clear();

    return connectInternal();
}

bool QSocks5SocketEngine::connectToHostByName(const QString &hostname, quint16 port)
{
    Q_D(QSocks5SocketEngine);

    setPeerAddress(QHostAddress());
    setPeerPort(port);
    d->peerName = hostname;

    return connectInternal();
}

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();
            if (socks5State == Connected && data->controlSocket->bytesAvailable())
                _q_controlSocketReadNotification();
            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.append(buf);
                emitReadNotification();
            }
            break;
        }
        case BindSuccess:
            // only get here if command is bind
            if (mode == BindMode) {
                parseRequestMethodReply();
                break;
            }

            Q_FALLTHROUGH();
        default:
            qWarning("QSocks5SocketEnginePrivate::_q_controlSocketReadNotification: "
                     "Unexpectedly received data while in state=%d and mode=%d",
                     socks5State, mode);
            break;
    };
}

void QSocks5SocketEnginePrivate::_q_controlSocketBytesWritten()
{
    QSOCKS5_DEBUG << "_q_controlSocketBytesWritten";

    if (socks5State != Connected
        || (mode == ConnectMode
        && data->controlSocket->bytesToWrite()))
        return;
    if (data->controlSocket->bytesToWrite() < MaxWriteBufferSize) {
        emitWriteNotification();
        writeNotificationActivated = false;
    }
}

void QSocks5SocketEnginePrivate::_q_controlSocketErrorOccurred(QAbstractSocket::SocketError error)
{
    QSOCKS5_D_DEBUG << "controlSocketError" << error << data->controlSocket->errorString();

    if (error == QAbstractSocket::SocketTimeoutError)
        return;                 // ignore this error -- comes from the waitFor* functions

    if (error == QAbstractSocket::RemoteHostClosedError
        && socks5State == Connected) {
        // 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 processed first
        if (!readNotificationPending)
            connectData->readBuffer.clear();
        emitReadNotification();
        data->controlSocket->close();
        // cause a disconnect in the outer socket
        emitWriteNotification();
    } else if (socks5State == Uninitialized
               || socks5State == AuthenticationMethodsSent
               || socks5State == Authenticating
               || socks5State == RequestMethodSent) {
        setErrorState(socks5State == Uninitialized ? ConnectError : ControlSocketError);
        data->controlSocket->close();
        emitConnectionNotification();
    } else {
        q_func()->setError(data->controlSocket->error(), data->controlSocket->errorString());
        emitReadNotification();
        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_UDPSOCKET
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) != 1) {
            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_UDPSOCKET

bool QSocks5SocketEngine::bind(const QHostAddress &addr, quint16 port)
{
    Q_D(QSocks5SocketEngine);

    // when bind wee will block until the bind is finished as the info from the proxy server is needed

    QHostAddress address;
    if (addr.protocol() == QAbstractSocket::AnyIPProtocol)
        address = QHostAddress::AnyIPv4; //SOCKS5 doesn't support dual stack, and there isn't any implementation of udp on ipv6 yet
    else
        address = addr;

    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;
    QElapsedTimer stopWatch;
    stopWatch.start();
    d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port());
    if (!d->waitForConnected(msecs, nullptr) ||
        d->data->controlSocket->state() == QAbstractSocket::UnconnectedState) {
        // waitForConnected sets the error state and closes the socket
        QSOCKS5_Q_DEBUG << "waitForConnected to proxy server" << d->data->controlSocket->errorString();
        return false;
    }
    if (d->socks5State == QSocks5SocketEnginePrivate::BindSuccess) {
        setState(QAbstractSocket::BoundState);
        return true;
#ifndef QT_NO_UDPSOCKET
    } else if (d->socks5State == QSocks5SocketEnginePrivate::UdpAssociateSuccess) {
        setState(QAbstractSocket::BoundState);
        d->udpData->associateAddress = d->localAddress;
        d->localAddress = QHostAddress();
        d->udpData->associatePort = d->localPort;
        d->localPort = 0;
        return true;
#endif // QT_NO_UDPSOCKET
    }

    // binding timed out
    setError(QAbstractSocket::SocketTimeoutError,
             QLatin1String(QT_TRANSLATE_NOOP("QSocks5SocketEngine", "Network operation timed out")));

///###    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()";

    qintptr sd = -1;
    switch (d->socks5State) {
    case QSocks5SocketEnginePrivate::BindSuccess:
        QSOCKS5_Q_DEBUG << "BindSuccess adding" << d->socketDescriptor << "to the bind store";
        d->data->controlSocket->disconnect();
        d->data->controlSocket->setParent(nullptr);
        d->bindData->localAddress = d->localAddress;
        d->bindData->localPort = d->localPort;
        sd = d->socketDescriptor;
        socks5BindStore()->add(sd, d->bindData);
        d->data = nullptr;
        d->bindData = nullptr;
        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;
        break;
    case QSocks5SocketEnginePrivate::ControlSocketError:
        setError(QAbstractSocket::ProxyProtocolError, QLatin1String("Control socket error"));
        break;
    default:
        setError(QAbstractSocket::ProxyProtocolError, QLatin1String("SOCKS5 proxy error"));
        break;
    }
    return sd;
}

void QSocks5SocketEngine::close()
{
    QSOCKS5_Q_DEBUG << "close()";
    Q_D(QSocks5SocketEngine);
    if (d->data && d->data->controlSocket) {
        if (d->data->controlSocket->state() == QAbstractSocket::ConnectedState) {
            int msecs = 100;
            QElapsedTimer stopWatch;
            stopWatch.start();
            while (!d->data->controlSocket->bytesToWrite()) {
               if (!d->data->controlSocket->waitForBytesWritten(qt_subtract_from_timeout(msecs, stopWatch.elapsed())))
                   break;
            }
        }
        d->data->controlSocket->close();
    }
    d->inboundStreamCount = d->outboundStreamCount = 0;
#ifndef QT_NO_UDPSOCKET
    if (d->udpData && d->udpData->udpSocket)
        d->udpData->udpSocket->close();
#endif
}

qint64 QSocks5SocketEngine::bytesAvailable() const
{
    Q_D(const QSocks5SocketEngine);
    if (d->mode == QSocks5SocketEnginePrivate::ConnectMode)
        return d->connectData->readBuffer.size();
#ifndef QT_NO_UDPSOCKET
    else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode
             && !d->udpData->pendingDatagrams.isEmpty())
        return d->udpData->pendingDatagrams.first().data.size();
#endif
    return 0;
}

qint64 QSocks5SocketEngine::read(char *data, qint64 maxlen)
{
    Q_D(QSocks5SocketEngine);
    QSOCKS5_Q_DEBUG << "read( , maxlen = " << maxlen << ')';
    if (d->mode == QSocks5SocketEnginePrivate::ConnectMode) {
        if (d->connectData->readBuffer.isEmpty()) {
            if (d->data->controlSocket->state() == QAbstractSocket::UnconnectedState) {
                //imitate remote closed
                close();
                setError(QAbstractSocket::RemoteHostClosedError,
                         QLatin1String("Remote host closed connection###"));
                setState(QAbstractSocket::UnconnectedState);
                return -1;
            } else {
                return 0;       // nothing to be read
            }
        }
        const qint64 copy = d->connectData->readBuffer.read(data, maxlen);
        QSOCKS5_DEBUG << "read" << dump(QByteArray(data, copy));
        return copy;
#ifndef QT_NO_UDPSOCKET
    } else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
        return readDatagram(data, maxlen);
#endif
    }
    return 0;
}

qint64 QSocks5SocketEngine::write(const char *data, qint64 len)
{
    Q_D(QSocks5SocketEngine);
    QSOCKS5_Q_DEBUG << "write" << dump(QByteArray(data, len));

    if (d->mode == QSocks5SocketEnginePrivate::ConnectMode) {
        // clamp down the amount of bytes to transfer at once
        len = qMin<qint64>(len, MaxWriteBufferSize) - d->data->controlSocket->bytesToWrite();
        if (len <= 0)
            return 0;

        QByteArray buf = QByteArray::fromRawData(data, len);
        QByteArray sealedBuf;
        if (!d->data->authenticator->seal(buf, &sealedBuf)) {
            // ### Handle this error.
        }

        qint64 written = d->data->controlSocket->write(sealedBuf);
        if (written <= 0) {
            QSOCKS5_Q_DEBUG << "native write returned" << written;
            return written;
        }
        d->data->controlSocket->waitForBytesWritten(0);
        //NB: returning len rather than written for the OK case, because the "sealing" may increase the length
        return len;
#ifndef QT_NO_UDPSOCKET
    } else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) {
        // send to connected address
        return writeDatagram(data, len, QIpPacketHeader(d->peerAddress, d->peerPort));
#endif
    }
    //### set an error ???
    return -1;
}

#ifndef QT_NO_UDPSOCKET
#ifndef QT_NO_NETWORKINTERFACE
bool QSocks5SocketEngine::joinMulticastGroup(const QHostAddress &,
                                             const QNetworkInterface &)
{
    setError(QAbstractSocket::UnsupportedSocketOperationError,
             QLatin1String("Operation on socket is not supported"));
    return false;
}

bool QSocks5SocketEngine::leaveMulticastGroup(const QHostAddress &,
                                              const QNetworkInterface &)
{
    setError(QAbstractSocket::UnsupportedSocketOperationError,
             QLatin1String("Operation on socket is not supported"));
    return false;
}


QNetworkInterface QSocks5SocketEngine::multicastInterface() const
{
    return QNetworkInterface();
}

bool QSocks5SocketEngine::setMulticastInterface(const QNetworkInterface &)
{
    setError(QAbstractSocket::UnsupportedSocketOperationError,
             QLatin1String("Operation on socket is not supported"));
    return false;
}
#endif // QT_NO_NETWORKINTERFACE

bool QSocks5SocketEngine::hasPendingDatagrams() const
{
    Q_D(const QSocks5SocketEngine);
    Q_INIT_CHECK(false);

    return !d->udpData->pendingDatagrams.isEmpty();
}

qint64 QSocks5SocketEngine::pendingDatagramSize() const
{
    Q_D(const QSocks5SocketEngine);

    if (!d->udpData->pendingDatagrams.isEmpty())
        return d->udpData->pendingDatagrams.head().data.size();
    return 0;
}
#endif // QT_NO_UDPSOCKET

qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHeader *header, PacketHeaderOptions)
{
#ifndef QT_NO_UDPSOCKET
    Q_D(QSocks5SocketEngine);

    if (d->udpData->pendingDatagrams.isEmpty())
        return 0;

    QSocks5RevivedDatagram datagram = d->udpData->pendingDatagrams.dequeue();
    int copyLen = qMin<int>(maxlen, datagram.data.size());
    memcpy(data, datagram.data.constData(), copyLen);
    if (header) {
        header->senderAddress = datagram.address;
        header->senderPort = datagram.port;
    }
    return copyLen;
#else
    Q_UNUSED(data)
    Q_UNUSED(maxlen)
    Q_UNUSED(header)
    return -1;
#endif // QT_NO_UDPSOCKET
}

qint64 QSocks5SocketEngine::writeDatagram(const char *data, qint64 len, const QIpPacketHeader &header)
{
#ifndef QT_NO_UDPSOCKET
    Q_D(QSocks5SocketEngine);

    // it is possible to send with out first binding with udp, but socks5 requires a bind.
    if (!d->data) {
        d->initialize(QSocks5SocketEnginePrivate::UdpAssociateMode);
        // all udp needs to be bound
        if (!bind(QHostAddress(QLatin1String("0.0.0.0")), 0)) {
            //### set error
            return -1;
        }
    }

    QByteArray outBuf;
    outBuf.reserve(270 + len);
    outBuf[0] = 0x00;
    outBuf[1] = 0x00;
    outBuf[2] = 0x00;
    if (!qt_socks5_set_host_address_and_port(header.destinationAddress, header.destinationPort, &outBuf)) {
    }
    outBuf += QByteArray(data, len);
    QSOCKS5_DEBUG << "sending" << dump(outBuf);
    QByteArray sealedBuf;
    if (!d->data->authenticator->seal(outBuf, &sealedBuf)) {
        QSOCKS5_DEBUG << "sealing data failed";
        setError(QAbstractSocket::SocketAccessError, d->data->authenticator->errorString());
        return -1;
    }
    if (d->udpData->udpSocket->writeDatagram(sealedBuf, d->udpData->associateAddress, d->udpData->associatePort) != sealedBuf.size()) {
        //### try frgamenting
        if (d->udpData->udpSocket->error() == QAbstractSocket::DatagramTooLargeError)
            setError(d->udpData->udpSocket->error(), d->udpData->udpSocket->errorString());
        //### else maybe more serious error
        return -1;
    }

    return len;
#else
    Q_UNUSED(data)
    Q_UNUSED(len)
    Q_UNUSED(header)
    return -1;
#endif // QT_NO_UDPSOCKET
}

qint64 QSocks5SocketEngine::bytesToWrite() const
{
    Q_D(const QSocks5SocketEngine);
    if (d->data && d->data->controlSocket) {
        return d->data->controlSocket->bytesToWrite();
    } else {
        return 0;
    }
}

int QSocks5SocketEngine::option(SocketOption option) const
{
    Q_D(const QSocks5SocketEngine);
    if (d->data && d->data->controlSocket) {
        // convert the enum and call the real socket
        if (option == QAbstractSocketEngine::LowDelayOption)
            return d->data->controlSocket->socketOption(QAbstractSocket::LowDelayOption).toInt();
        if (option == QAbstractSocketEngine::KeepAliveOption)
            return d->data->controlSocket->socketOption(QAbstractSocket::KeepAliveOption).toInt();
    }
    return -1;
}

bool QSocks5SocketEngine::setOption(SocketOption option, int value)
{
    Q_D(QSocks5SocketEngine);
    if (d->data && d->data->controlSocket) {
        // convert the enum and call the real socket
        if (option == QAbstractSocketEngine::LowDelayOption)
            d->data->controlSocket->setSocketOption(QAbstractSocket::LowDelayOption, value);
        if (option == QAbstractSocketEngine::KeepAliveOption)
            d->data->controlSocket->setSocketOption(QAbstractSocket::KeepAliveOption, value);
        return true;
    }
    return false;
}

bool QSocks5SocketEnginePrivate::waitForConnected(int msecs, bool *timedOut)
{
    if (data->controlSocket->state() == QAbstractSocket::UnconnectedState)
        return false;

    const Socks5State wantedState =
        mode == ConnectMode ? Connected :
        mode == BindMode ? BindSuccess :
        UdpAssociateSuccess;

    QElapsedTimer stopWatch;
    stopWatch.start();

    while (socks5State != wantedState) {
        if (!data->controlSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
            if (data->controlSocket->state() == QAbstractSocket::UnconnectedState)
                return true;

            setErrorState(QSocks5SocketEnginePrivate::ControlSocketError);
            if (timedOut && data->controlSocket->error() == QAbstractSocket::SocketTimeoutError)
                *timedOut = true;
            return false;
        }
    }

    return true;
}

bool QSocks5SocketEngine::waitForRead(int msecs, bool *timedOut)
{
    Q_D(QSocks5SocketEngine);
    QSOCKS5_DEBUG << "waitForRead" << msecs;

    d->readNotificationActivated = false;

    QElapsedTimer stopWatch;
    stopWatch.start();

    // are we connected yet?
    if (!d->waitForConnected(msecs, timedOut))
        return false;
    if (d->data->controlSocket->state() == QAbstractSocket::UnconnectedState)
        return true;
    if (bytesAvailable() && d->readNotificationPending) {
        // We've got some data incoming, but the queued call hasn't been performed yet.
        // The data is where we expect it to be already, so just return true.
        return true;
    }

    // we're connected
    if (d->mode == QSocks5SocketEnginePrivate::ConnectMode ||
        d->mode == QSocks5SocketEnginePrivate::BindMode) {
        while (!d->readNotificationActivated) {
            if (!d->data->controlSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
                if (d->data->controlSocket->state() == QAbstractSocket::UnconnectedState)
                    return true;

                setError(d->data->controlSocket->error(), d->data->controlSocket->errorString());
                if (timedOut && d->data->controlSocket->error() == QAbstractSocket::SocketTimeoutError)
                    *timedOut = true;
                return false;
            }
        }
#ifndef QT_NO_UDPSOCKET
    } else {
        while (!d->readNotificationActivated) {
            if (!d->udpData->udpSocket->waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed()))) {
                setError(d->udpData->udpSocket->error(), d->udpData->udpSocket->errorString());
                if (timedOut && d->udpData->udpSocket->error() == QAbstractSocket::SocketTimeoutError)
                    *timedOut = true;
                return false;
            }
        }
#endif // QT_NO_UDPSOCKET
    }


    bool ret = d->readNotificationActivated;
    d->readNotificationActivated = false;

    QSOCKS5_DEBUG << "waitForRead returned" << ret;
    return ret;
}


bool QSocks5SocketEngine::waitForWrite(int msecs, bool *timedOut)
{
    Q_D(QSocks5SocketEngine);
    QSOCKS5_DEBUG << "waitForWrite" << msecs;

    QElapsedTimer stopWatch;
    stopWatch.start();

    // are we connected yet?
    if (!d->waitForConnected(msecs, timedOut))
        return false;
    if (d->data->controlSocket->state() == QAbstractSocket::UnconnectedState)
        return true;

    // we're connected

    // flush any bytes we may still have buffered in the time that we have left
    if (d->data->controlSocket->bytesToWrite())
        d->data->controlSocket->waitForBytesWritten(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
    while ((msecs == -1 || stopWatch.elapsed() < msecs)
           && d->data->controlSocket->state() == QAbstractSocket::ConnectedState
           && d->data->controlSocket->bytesToWrite() >= MaxWriteBufferSize)
        d->data->controlSocket->waitForBytesWritten(qt_subtract_from_timeout(msecs, stopWatch.elapsed()));
    return d->data->controlSocket->bytesToWrite() < MaxWriteBufferSize;
}

bool QSocks5SocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
                                            bool checkRead, bool checkWrite,
                                            int msecs, bool *timedOut)
{
    Q_UNUSED(checkRead);
    if (!checkWrite) {
        bool canRead = waitForRead(msecs, timedOut);
        if (readyToRead)
            *readyToRead = canRead;
        return canRead;
    }

    bool canWrite = waitForWrite(msecs, timedOut);
    if (readyToWrite)
        *readyToWrite = canWrite;
    return canWrite;
}

bool QSocks5SocketEngine::isReadNotificationEnabled() const
{
    Q_D(const QSocks5SocketEngine);
    return d->readNotificationEnabled;
}

void QSocks5SocketEngine::setReadNotificationEnabled(bool enable)
{
    Q_D(QSocks5SocketEngine);

    QSOCKS5_Q_DEBUG << "setReadNotificationEnabled(" << enable << ')';

    bool emitSignal = false;
    if (!d->readNotificationEnabled
        && enable) {
        if (d->mode == QSocks5SocketEnginePrivate::ConnectMode)
            emitSignal = !d->connectData->readBuffer.isEmpty();
#ifndef QT_NO_UDPSOCKET
        else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode)
            emitSignal = !d->udpData->pendingDatagrams.isEmpty();
#endif
        else if (d->mode == QSocks5SocketEnginePrivate::BindMode
            && d->socketState == QAbstractSocket::ListeningState
            && d->socks5State == QSocks5SocketEnginePrivate::BindSuccess)
            emitSignal = true;
    }

    d->readNotificationEnabled = enable;

    if (emitSignal)
        d->emitReadNotification();
}

bool QSocks5SocketEngine::isWriteNotificationEnabled() const
{
    Q_D(const QSocks5SocketEngine);
    return d->writeNotificationEnabled;
}

void QSocks5SocketEngine::setWriteNotificationEnabled(bool enable)
{
    Q_D(QSocks5SocketEngine);
    d->writeNotificationEnabled = enable;
    if (enable && d->socketState == QAbstractSocket::ConnectedState) {
        if (d->mode == QSocks5SocketEnginePrivate::ConnectMode && d->data->controlSocket->bytesToWrite())
            return; // will be emitted as a result of bytes written
       d->emitWriteNotification();
       d->writeNotificationActivated = false;
    }
}

bool QSocks5SocketEngine::isExceptionNotificationEnabled() const
{
    Q_D(const QSocks5SocketEngine);
    return d->exceptNotificationEnabled;
}

void QSocks5SocketEngine::setExceptionNotificationEnabled(bool enable)
{
    Q_D(QSocks5SocketEngine);
    d->exceptNotificationEnabled = enable;
}

QAbstractSocketEngine *
QSocks5SocketEngineHandler::createSocketEngine(QAbstractSocket::SocketType socketType,
                                               const QNetworkProxy &proxy, QObject *parent)
{
    Q_UNUSED(socketType);

    // proxy type must have been resolved by now
    if (proxy.type() != QNetworkProxy::Socks5Proxy) {
        QSOCKS5_DEBUG << "not proxying";
        return nullptr;
    }
    QScopedPointer<QSocks5SocketEngine> engine(new QSocks5SocketEngine(parent));
    engine->setProxy(proxy);
    return engine.take();
}

QAbstractSocketEngine *QSocks5SocketEngineHandler::createSocketEngine(qintptr socketDescriptor, QObject *parent)
{
    QSOCKS5_DEBUG << "createSocketEngine" << socketDescriptor;
    if (socks5BindStore()->contains(socketDescriptor)) {
        QSOCKS5_DEBUG << "bind store contains" << socketDescriptor;
        return new QSocks5SocketEngine(parent);
    }
    return nullptr;
}

QT_END_NAMESPACE
