/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** 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$
**
****************************************************************************/

// Prevent windows system header files from defining min/max as macros.
#define NOMINMAX 1

#include <winsock2.h>
#include <ws2tcpip.h>

#include "qnativesocketengine_p.h"

#include <qabstracteventdispatcher.h>
#include <qsocketnotifier.h>
#include <qdebug.h>
#include <qdatetime.h>
#include <qnetworkinterface.h>
#include <qoperatingsystemversion.h>

#include <algorithm>

//#define QNATIVESOCKETENGINE_DEBUG
#if defined(QNATIVESOCKETENGINE_DEBUG)
#   include <qstring.h>
#   include <qbytearray.h>
#endif

QT_BEGIN_NAMESPACE

//Some distributions of mingw (including 4.7.2 from mingw.org) are missing this from headers.
//Also microsoft headers don't include it when building on XP and earlier.
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
#endif
#ifndef IP_HOPLIMIT
#define IP_HOPLIMIT               21 // Receive packet hop limit.
#endif

#if defined(QNATIVESOCKETENGINE_DEBUG)

void verboseWSErrorDebug(int r)
{
    switch (r) {
        case WSANOTINITIALISED : qDebug("WSA error : WSANOTINITIALISED"); break;
        case WSAEINTR: qDebug("WSA error : WSAEINTR"); break;
        case WSAEBADF: qDebug("WSA error : WSAEBADF"); break;
        case WSAEACCES: qDebug("WSA error : WSAEACCES"); break;
        case WSAEFAULT: qDebug("WSA error : WSAEFAULT"); break;
        case WSAEINVAL: qDebug("WSA error : WSAEINVAL"); break;
        case WSAEMFILE: qDebug("WSA error : WSAEMFILE"); break;
        case WSAEWOULDBLOCK: qDebug("WSA error : WSAEWOULDBLOCK"); break;
        case WSAEINPROGRESS: qDebug("WSA error : WSAEINPROGRESS"); break;
        case WSAEALREADY: qDebug("WSA error : WSAEALREADY"); break;
        case WSAENOTSOCK: qDebug("WSA error : WSAENOTSOCK"); break;
        case WSAEDESTADDRREQ: qDebug("WSA error : WSAEDESTADDRREQ"); break;
        case WSAEMSGSIZE: qDebug("WSA error : WSAEMSGSIZE"); break;
        case WSAEPROTOTYPE: qDebug("WSA error : WSAEPROTOTYPE"); break;
        case WSAENOPROTOOPT: qDebug("WSA error : WSAENOPROTOOPT"); break;
        case WSAEPROTONOSUPPORT: qDebug("WSA error : WSAEPROTONOSUPPORT"); break;
        case WSAESOCKTNOSUPPORT: qDebug("WSA error : WSAESOCKTNOSUPPORT"); break;
        case WSAEOPNOTSUPP: qDebug("WSA error : WSAEOPNOTSUPP"); break;
        case WSAEPFNOSUPPORT: qDebug("WSA error : WSAEPFNOSUPPORT"); break;
        case WSAEAFNOSUPPORT: qDebug("WSA error : WSAEAFNOSUPPORT"); break;
        case WSAEADDRINUSE: qDebug("WSA error : WSAEADDRINUSE"); break;
        case WSAEADDRNOTAVAIL: qDebug("WSA error : WSAEADDRNOTAVAIL"); break;
        case WSAENETDOWN: qDebug("WSA error : WSAENETDOWN"); break;
        case WSAENETUNREACH: qDebug("WSA error : WSAENETUNREACH"); break;
        case WSAENETRESET: qDebug("WSA error : WSAENETRESET"); break;
        case WSAECONNABORTED: qDebug("WSA error : WSAECONNABORTED"); break;
        case WSAECONNRESET: qDebug("WSA error : WSAECONNRESET"); break;
        case WSAENOBUFS: qDebug("WSA error : WSAENOBUFS"); break;
        case WSAEISCONN: qDebug("WSA error : WSAEISCONN"); break;
        case WSAENOTCONN: qDebug("WSA error : WSAENOTCONN"); break;
        case WSAESHUTDOWN: qDebug("WSA error : WSAESHUTDOWN"); break;
        case WSAETOOMANYREFS: qDebug("WSA error : WSAETOOMANYREFS"); break;
        case WSAETIMEDOUT: qDebug("WSA error : WSAETIMEDOUT"); break;
        case WSAECONNREFUSED: qDebug("WSA error : WSAECONNREFUSED"); break;
        case WSAELOOP: qDebug("WSA error : WSAELOOP"); break;
        case WSAENAMETOOLONG: qDebug("WSA error : WSAENAMETOOLONG"); break;
        case WSAEHOSTDOWN: qDebug("WSA error : WSAEHOSTDOWN"); break;
        case WSAEHOSTUNREACH: qDebug("WSA error : WSAEHOSTUNREACH"); break;
        case WSAENOTEMPTY: qDebug("WSA error : WSAENOTEMPTY"); break;
        case WSAEPROCLIM: qDebug("WSA error : WSAEPROCLIM"); break;
        case WSAEUSERS: qDebug("WSA error : WSAEUSERS"); break;
        case WSAEDQUOT: qDebug("WSA error : WSAEDQUOT"); break;
        case WSAESTALE: qDebug("WSA error : WSAESTALE"); break;
        case WSAEREMOTE: qDebug("WSA error : WSAEREMOTE"); break;
        case WSAEDISCON: qDebug("WSA error : WSAEDISCON"); break;
        default: qDebug("WSA error : Unknown"); break;
    }
    qErrnoWarning(r, "more details");
}

/*
    Returns a human readable representation of the first \a len
    characters in \a data.
*/
static QByteArray qt_prettyDebug(const char *data, int len, int maxLength)
{
    if (!data) return "(null)";
    QByteArray out;
    for (int i = 0; i < len; ++i) {
        char c = data[i];
        if (isprint(int(uchar(c)))) {
            out += c;
        } else switch (c) {
        case '\n': out += "\\n"; break;
        case '\r': out += "\\r"; break;
        case '\t': out += "\\t"; break;
        default:
            QString tmp;
            tmp.sprintf("\\%o", c);
            out += tmp.toLatin1().constData();
        }
    }

    if (len < maxLength)
        out += "...";

    return out;
}


#define WS_ERROR_DEBUG(x) verboseWSErrorDebug(x);

#else

#define WS_ERROR_DEBUG(x) Q_UNUSED(x)

#endif

#ifndef AF_INET6
#define AF_INET6        23              /* Internetwork Version 6 */
#endif

#ifndef SO_EXCLUSIVEADDRUSE
#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR)) /* disallow local address reuse */
#endif

/*
    Extracts the port and address from a sockaddr, and stores them in
    \a port and \a addr if they are non-null.
*/
static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt_sockaddr *sa, quint16 *port, QHostAddress *address)
{
    if (sa->a.sa_family == AF_INET6) {
        const sockaddr_in6 *sa6 = &sa->a6;
        Q_IPV6ADDR tmp;
        for (int i = 0; i < 16; ++i)
            tmp.c[i] = sa6->sin6_addr.s6_addr[i];
        if (address) {
            QHostAddress a;
            a.setAddress(tmp);
            if (sa6->sin6_scope_id)
                a.setScopeId(QString::number(sa6->sin6_scope_id));
            *address = a;
        }
        if (port)
            WSANtohs(socketDescriptor, sa6->sin6_port, port);
    } else

    if (sa->a.sa_family == AF_INET) {
        const sockaddr_in *sa4 = &sa->a4;
        unsigned long addr;
        WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr);
        QHostAddress a;
        a.setAddress(addr);
        if (address)
            *address = a;
        if (port)
            WSANtohs(socketDescriptor, sa4->sin_port, port);
    }
}

static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
                                    QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
{
    n = -1;
    level = SOL_SOCKET; // default

    switch (opt) {
    case QNativeSocketEngine::NonBlockingSocketOption:      // WSAIoctl
    case QNativeSocketEngine::TypeOfServiceOption:          // not supported
    case QNativeSocketEngine::MaxStreamsSocketOption:
        Q_UNREACHABLE();

    case QNativeSocketEngine::ReceiveBufferSocketOption:
        n = SO_RCVBUF;
        break;
    case QNativeSocketEngine::SendBufferSocketOption:
        n = SO_SNDBUF;
        break;
    case QNativeSocketEngine::BroadcastSocketOption:
        n = SO_BROADCAST;
        break;
    case QNativeSocketEngine::AddressReusable:
        n = SO_REUSEADDR;
        break;
    case QNativeSocketEngine::BindExclusively:
        n = SO_EXCLUSIVEADDRUSE;
        break;
    case QNativeSocketEngine::ReceiveOutOfBandData:
        n = SO_OOBINLINE;
        break;
    case QNativeSocketEngine::LowDelayOption:
        level = IPPROTO_TCP;
        n = TCP_NODELAY;
        break;
    case QNativeSocketEngine::KeepAliveOption:
        n = SO_KEEPALIVE;
        break;
    case QNativeSocketEngine::MulticastTtlOption:
        if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
            level = IPPROTO_IPV6;
            n = IPV6_MULTICAST_HOPS;
        } else
        {
            level = IPPROTO_IP;
            n = IP_MULTICAST_TTL;
        }
        break;
    case QNativeSocketEngine::MulticastLoopbackOption:
        if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
            level = IPPROTO_IPV6;
            n = IPV6_MULTICAST_LOOP;
        } else
        {
            level = IPPROTO_IP;
            n = IP_MULTICAST_LOOP;
        }
        break;
    case QNativeSocketEngine::ReceivePacketInformation:
        if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
            level = IPPROTO_IPV6;
            n = IPV6_PKTINFO;
        } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
            level = IPPROTO_IP;
            n = IP_PKTINFO;
        }
        break;
    case QNativeSocketEngine::ReceiveHopLimit:
        if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
            level = IPPROTO_IPV6;
            n = IPV6_HOPLIMIT;
        } else if (socketProtocol == QAbstractSocket::IPv4Protocol) {
            level = IPPROTO_IP;
            n = IP_HOPLIMIT;
        }
        break;

    case QAbstractSocketEngine::PathMtuInformation:
        break;          // not supported on Windows
    }
}

/*! \internal

*/
static inline QAbstractSocket::SocketType qt_socket_getType(qintptr socketDescriptor)
{
    int value = 0;
    QT_SOCKLEN_T valueSize = sizeof(value);
    if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_TYPE,
                     reinterpret_cast<char *>(&value), &valueSize) != 0) {
        WS_ERROR_DEBUG(WSAGetLastError());
    } else {
        if (value == SOCK_STREAM)
            return QAbstractSocket::TcpSocket;
        else if (value == SOCK_DGRAM)
            return QAbstractSocket::UdpSocket;
    }
    return QAbstractSocket::UnknownSocketType;
}

// MS Transport Provider IOCTL to control
// reporting PORT_UNREACHABLE messages
// on UDP sockets via recv/WSARecv/etc.
// Path TRUE in input buffer to enable (default if supported),
// FALSE to disable.
#ifndef SIO_UDP_CONNRESET
#  ifndef IOC_VENDOR
#    define IOC_VENDOR 0x18000000
#  endif
#  ifndef _WSAIOW
#    define _WSAIOW(x,y) (IOC_IN|(x)|(y))
#  endif
#  define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
#endif

bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
{

    //### no ip6 support on winsocket 1.1 but we will try not to use this !!!!!!!!!!!!1
    /*
    if (winsockVersion < 0x20 && socketProtocol == QAbstractSocket::IPv6Protocol) {
        //### no ip6 support
        return -1;
    }
    */

    //### SCTP not implemented
    if (socketType == QAbstractSocket::SctpSocket) {
        setError(QAbstractSocket::UnsupportedSocketOperationError,
                 ProtocolUnsupportedErrorString);
        return false;
    }

    //Windows XP and 2003 support IPv6 but not dual stack sockets
    int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol
        || (socketProtocol == QAbstractSocket::AnyIPProtocol)) ? AF_INET6 : AF_INET;
    int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;

    // MSDN KB179942 states that on winnt 4 WSA_FLAG_OVERLAPPED is needed if socket is to be non blocking
    // and recomends alwasy doing it for cross windows version comapablity.

    // WSA_FLAG_NO_HANDLE_INHERIT is atomic (like linux O_CLOEXEC), but requires windows 7 SP 1 or later
    // SetHandleInformation is supported since W2K but isn't atomic
#ifndef WSA_FLAG_NO_HANDLE_INHERIT
#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
#endif

    SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT | WSA_FLAG_OVERLAPPED);
    // previous call fails if the windows 7 service pack 1 or hot fix isn't installed.

    // Try the old API if the new one failed on Windows 7
    if (socket == INVALID_SOCKET && QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8) {
        socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
#ifdef HANDLE_FLAG_INHERIT
        if (socket != INVALID_SOCKET) {
            // make non inheritable the old way
            BOOL handleFlags = SetHandleInformation(reinterpret_cast<HANDLE>(socket), HANDLE_FLAG_INHERIT, 0);
#ifdef QNATIVESOCKETENGINE_DEBUG
            qDebug() << "QNativeSocketEnginePrivate::createNewSocket - set inheritable" << handleFlags;
#else
            Q_UNUSED(handleFlags);
#endif
        }
#endif
    }

    if (socket == INVALID_SOCKET) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSANOTINITIALISED:
            //###
            break;
        case WSAEAFNOSUPPORT:
        case WSAESOCKTNOSUPPORT:
        case WSAEPROTOTYPE:
        case WSAEINVAL:
            setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString);
            break;
        case WSAEMFILE:
        case WSAENOBUFS:
            setError(QAbstractSocket::SocketResourceError, ResourceErrorString);
            break;
        default:
            break;
        }

        return false;
    }

    if (socketType == QAbstractSocket::UdpSocket) {
        // enable new behavior using
        // SIO_UDP_CONNRESET
        DWORD dwBytesReturned = 0;
        int bNewBehavior = 1;
        if (::WSAIoctl(socket, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
                       NULL, 0, &dwBytesReturned, NULL, NULL) == SOCKET_ERROR) {
            // not to worry isBogusUdpReadNotification() should handle this otherwise
            int err = WSAGetLastError();
            WS_ERROR_DEBUG(err);
        }
    }

    // get the pointer to sendmsg and recvmsg
    DWORD bytesReturned;
    GUID recvmsgguid = WSAID_WSARECVMSG;
    if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
                 &recvmsgguid, sizeof(recvmsgguid),
                 &recvmsg, sizeof(recvmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
        recvmsg = 0;

    GUID sendmsgguid = WSAID_WSASENDMSG;
    if (WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER,
                 &sendmsgguid, sizeof(sendmsgguid),
                 &sendmsg, sizeof(sendmsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
        sendmsg = 0;

    socketDescriptor = socket;
    if (socket != INVALID_SOCKET) {
        this->socketProtocol = socketProtocol;
        this->socketType = socketType;
    }

    // Make the socket nonblocking.
    if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) {
        setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString);
        q_func()->close();
        return false;
    }

    return true;
}

/*! \internal

    Returns the value of the socket option \a opt.
*/
int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) const
{
    Q_Q(const QNativeSocketEngine);
    if (!q->isValid())
        return -1;

    // handle non-getsockopt
    switch (opt) {
    case QNativeSocketEngine::NonBlockingSocketOption: {
        unsigned long buf = 0;
        if (WSAIoctl(socketDescriptor, FIONBIO, 0,0, &buf, sizeof(buf), 0,0,0) == 0)
            return buf;
        else
            return -1;
        break;
    }
    case QNativeSocketEngine::TypeOfServiceOption:
    case QNativeSocketEngine::MaxStreamsSocketOption:
        return -1;

    default:
        break;
    }

#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
#error code assumes windows is little endian
#endif
    int n, level;
    int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int
    QT_SOCKOPTLEN_T len = sizeof(v);

    convertToLevelAndOption(opt, socketProtocol, level, n);
    if (n != -1) {
        if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
            return v;
        WS_ERROR_DEBUG(WSAGetLastError());
    }
    return -1;
}


/*! \internal
    Sets the socket option \a opt to \a v.
*/
bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt, int v)
{
    Q_Q(const QNativeSocketEngine);
    if (!q->isValid())
        return false;

    // handle non-setsockopt options
    switch (opt) {
    case QNativeSocketEngine::SendBufferSocketOption:
        // see QTBUG-30478 SO_SNDBUF should not be used on Vista or later
        return false;
    case QNativeSocketEngine::NonBlockingSocketOption:
        {
        unsigned long buf = v;
        unsigned long outBuf;
        DWORD sizeWritten = 0;
        if (::WSAIoctl(socketDescriptor, FIONBIO, &buf, sizeof(unsigned long), &outBuf, sizeof(unsigned long), &sizeWritten, 0,0) == SOCKET_ERROR) {
            WS_ERROR_DEBUG(WSAGetLastError());
            return false;
        }
        return true;
        break;
        }
    case QNativeSocketEngine::TypeOfServiceOption:
    case QNativeSocketEngine::MaxStreamsSocketOption:
        return false;

    default:
        break;
    }

    int n, level;
    convertToLevelAndOption(opt, socketProtocol, level, n);
    if (n == -1)
        return false;
    if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
        WS_ERROR_DEBUG(WSAGetLastError());
        return false;
    }
    return true;
}

/*!
    Fetches information about both ends of the connection: whatever is
    available.
*/
bool QNativeSocketEnginePrivate::fetchConnectionParameters()
{
    localPort = 0;
    localAddress.clear();
    peerPort = 0;
    peerAddress.clear();
    inboundStreamCount = outboundStreamCount = 0;

    if (socketDescriptor == -1)
       return false;

    qt_sockaddr sa;
    QT_SOCKLEN_T sockAddrSize = sizeof(sa);

    // Determine local address
    memset(&sa, 0, sizeof(sa));
    if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
        qt_socket_getPortAndAddress(socketDescriptor, &sa, &localPort, &localAddress);
        // Determine protocol family
        switch (sa.a.sa_family) {
        case AF_INET:
            socketProtocol = QAbstractSocket::IPv4Protocol;
            break;
        case AF_INET6:
            socketProtocol = QAbstractSocket::IPv6Protocol;
            break;
        default:
            socketProtocol = QAbstractSocket::UnknownNetworkLayerProtocol;
            break;
        }
    } else {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        if (err == WSAENOTSOCK) {
            setError(QAbstractSocket::UnsupportedSocketOperationError,
                InvalidSocketErrorString);
            return false;
        }
    }

    // determine if local address is dual mode
    DWORD ipv6only = 0;
    QT_SOCKOPTLEN_T optlen = sizeof(ipv6only);
    if (localAddress == QHostAddress::AnyIPv6
        && !getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, &optlen )) {
            if (!ipv6only) {
                socketProtocol = QAbstractSocket::AnyIPProtocol;
                localAddress = QHostAddress::Any;
            }
    }

    // Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a
    // local address of the socket which bound on both IPv4 and IPv6 interfaces.
    // This address does not match to any special address and should not be used
    // to send the data. So, replace it with QHostAddress::Any.
    const uchar ipv6MappedNet[] = {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
    if (localAddress.isInSubnet(QHostAddress(ipv6MappedNet), 128 - 32)) {
        bool ok = false;
        const quint32 localIPv4 = localAddress.toIPv4Address(&ok);
        if (ok && localIPv4 == INADDR_ANY) {
            socketProtocol = QAbstractSocket::AnyIPProtocol;
            localAddress = QHostAddress::Any;
        }
    }

    memset(&sa, 0, sizeof(sa));
    if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
        qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
        inboundStreamCount = outboundStreamCount = 1;
    } else {
        WS_ERROR_DEBUG(WSAGetLastError());
    }

    socketType = qt_socket_getType(socketDescriptor);

#if defined (QNATIVESOCKETENGINE_DEBUG)
    QString socketProtocolStr = QStringLiteral("UnknownProtocol");
    if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol");
    else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = QStringLiteral("IPv6Protocol");

    QString socketTypeStr = QStringLiteral("UnknownSocketType");
    if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket");
    else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = QStringLiteral("UdpSocket");

    qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() localAddress == %s, localPort = %i, peerAddress == %s, peerPort = %i, socketProtocol == %s, socketType == %s", localAddress.toString().toLatin1().constData(), localPort, peerAddress.toString().toLatin1().constData(), peerPort, socketProtocolStr.toLatin1().constData(), socketTypeStr.toLatin1().constData());
#endif

    return true;
}


static void setErrorFromWSAError(int error, QNativeSocketEnginePrivate *d)
{
    Q_ASSERT(d);
    switch (error) {
    case WSAEISCONN:
        d->socketState = QAbstractSocket::ConnectedState;
        break;
    case WSAEHOSTUNREACH:
        d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAEADDRNOTAVAIL:
        d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressNotAvailableErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAEINPROGRESS:
        d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString);
        d->socketState = QAbstractSocket::ConnectingState;
        break;
    case WSAEADDRINUSE:
        d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressInuseErrorString);
        break;
    case WSAECONNREFUSED:
        d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAETIMEDOUT:
        d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAEACCES:
        d->setError(QAbstractSocket::SocketAccessError, QNativeSocketEnginePrivate::AccessErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAENETUNREACH:
        d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::NetworkUnreachableErrorString);
        d->socketState = QAbstractSocket::UnconnectedState;
        break;
    case WSAEINVAL:
    case WSAEALREADY:
        d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString);
        break;
    default:
        break;
    }
}

bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quint16 port)
{

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeConnect() to %s :: %i", address.toString().toLatin1().constData(), port);
#endif

    qt_sockaddr aa;
    QT_SOCKLEN_T sockAddrSize = 0;

    setPortAndAddress(port, address, &aa, &sockAddrSize);

    if ((socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) && address.toIPv4Address()) {
        //IPV6_V6ONLY option must be cleared to connect to a V4 mapped address
        DWORD ipv6only = 0;
        ipv6only = ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
    }

    forever {
        int connectResult = ::WSAConnect(socketDescriptor, &aa.a, sockAddrSize, 0,0,0,0);
        if (connectResult == SOCKET_ERROR) {
            int err = WSAGetLastError();
            WS_ERROR_DEBUG(err);

            switch (err) {
            case WSANOTINITIALISED:
                //###
                break;
            case WSAEWOULDBLOCK: {
                // If WSAConnect returns WSAEWOULDBLOCK on the second
                // connection attempt, we have to check SO_ERROR's
                // value to detect ECONNREFUSED. If we don't get
                // ECONNREFUSED, we'll have to treat it as an
                // unfinished operation.
                int value = 0;
                QT_SOCKLEN_T valueSize = sizeof(value);
                bool tryAgain = false;
                bool errorDetected = false;
                int tries = 0;
                do {
                    if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
                        if (value != NOERROR) {
                            WS_ERROR_DEBUG(value);
                            errorDetected = true;
                            // MSDN says getsockopt with SO_ERROR clears the error, but it's not actually cleared
                            // and this can affect all subsequent WSAConnect attempts, so clear it now.
                            const int val = NO_ERROR;
                            ::setsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, reinterpret_cast<const char*>(&val), sizeof val);
                        } else {
                            // When we get WSAEWOULDBLOCK the outcome was not known, so a
                            // NOERROR might indicate that the result of the operation
                            // is still unknown. We try again to increase the chance that we did
                            // get the correct result.
                            tryAgain = !tryAgain;
                        }
                        setErrorFromWSAError(value, this);
                    }
                    tries++;
                } while (tryAgain && (tries < 2));

                if (errorDetected)
                    break;
                // fall through to unfinished operation error handling
                err = WSAEINPROGRESS;
                Q_FALLTHROUGH();
            }

            default:
                setErrorFromWSAError(err, this);
                break;
            }
            if (socketState != QAbstractSocket::ConnectedState) {
#if defined (QNATIVESOCKETENGINE_DEBUG)
                qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
                        address.toString().toLatin1().constData(), port,
                        socketState == QAbstractSocket::ConnectingState
                        ? "Connection in progress" : socketErrorString.toLatin1().constData());
#endif
                return false;
            }
        }
        break;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
           address.toString().toLatin1().constData(), port);
#endif

    socketState = QAbstractSocket::ConnectedState;
    return true;
}


bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &a, quint16 port)
{
    QHostAddress address = a;
    if (address.protocol() == QAbstractSocket::IPv4Protocol) {
        if ((address.toIPv4Address() & 0xffff0000) == 0xefff0000) {
            // binding to a multicast address
            address = QHostAddress(QHostAddress::AnyIPv4);
        }
    }

    qt_sockaddr aa;
    QT_SOCKLEN_T sockAddrSize = 0;
    setPortAndAddress(port, address, &aa, &sockAddrSize);

    if (aa.a.sa_family == AF_INET6) {
        // The default may change in future, so set it explicitly
        int ipv6only = 0;
        if (address.protocol() == QAbstractSocket::IPv6Protocol)
            ipv6only = 1;
        ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) );
    }


    int bindResult = ::bind(socketDescriptor, &aa.a, sockAddrSize);
    if (bindResult == SOCKET_ERROR && WSAGetLastError() == WSAEAFNOSUPPORT
            && address.protocol() == QAbstractSocket::AnyIPProtocol) {
        // retry with v4
        aa.a4.sin_family = AF_INET;
        aa.a4.sin_port = htons(port);
        aa.a4.sin_addr.s_addr = htonl(address.toIPv4Address());
        sockAddrSize = sizeof(aa.a4);
        bindResult = ::bind(socketDescriptor, &aa.a, sockAddrSize);
    }
    if (bindResult == SOCKET_ERROR) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSANOTINITIALISED:
            //###
            break;
        case WSAEADDRINUSE:
        case WSAEINVAL:
            setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString);
            break;
        case WSAEACCES:
            setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString);
            break;
        case WSAEADDRNOTAVAIL:
            setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString);
            break;
        default:
            break;
        }

#if defined (QNATIVESOCKETENGINE_DEBUG)
        qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
               address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData());
#endif

        return false;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
           address.toString().toLatin1().constData(), port);
#endif
    socketState = QAbstractSocket::BoundState;
    return true;
}


bool QNativeSocketEnginePrivate::nativeListen(int backlog)
{
    if (::listen(socketDescriptor, backlog) == SOCKET_ERROR) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSANOTINITIALISED:
            //###
            break;
        case WSAEADDRINUSE:
            setError(QAbstractSocket::AddressInUseError,
                     PortInuseErrorString);
            break;
        default:
            break;
        }

#if defined (QNATIVESOCKETENGINE_DEBUG)
        qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",
               backlog, socketErrorString.toLatin1().constData());
#endif
        return false;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeListen(%i) == true", backlog);
#endif

    socketState = QAbstractSocket::ListeningState;
    return true;
}

int QNativeSocketEnginePrivate::nativeAccept()
{
    int acceptedDescriptor = WSAAccept(socketDescriptor, 0,0,0,0);
    if (acceptedDescriptor == -1) {
        int err = WSAGetLastError();
        switch (err) {
        case WSAEACCES:
            setError(QAbstractSocket::SocketAccessError, AccessErrorString);
            break;
        case WSAECONNREFUSED:
            setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
            break;
        case WSAECONNRESET:
            setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString);
            break;
        case WSAENETDOWN:
            setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
            break;
        case WSAENOTSOCK:
            setError(QAbstractSocket::SocketResourceError, NotSocketErrorString);
            break;
        case WSAEINVAL:
        case WSAEOPNOTSUPP:
            setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString);
            break;
        case WSAEFAULT:
        case WSAEMFILE:
        case WSAENOBUFS:
            setError(QAbstractSocket::SocketResourceError, ResourceErrorString);
            break;
        case WSAEWOULDBLOCK:
            setError(QAbstractSocket::TemporaryError, TemporaryErrorString);
            break;
        default:
            setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString);
            break;
        }
    } else if (acceptedDescriptor != -1 && QAbstractEventDispatcher::instance()) {
        // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket
        // with the same attributes as the listening socket including the current
        // WSAAsyncSelect(). To be able to change the socket to blocking mode the
        // WSAAsyncSelect() call must be cancled.
        QSocketNotifier n(acceptedDescriptor, QSocketNotifier::Read);
        n.setEnabled(true);
        n.setEnabled(false);
    }
#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor);
#endif
    return acceptedDescriptor;
}

static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d,
                                      int how6,
                                      int how4,
                                      const QHostAddress &groupAddress,
                                      const QNetworkInterface &iface)
{
    int level = 0;
    int sockOpt = 0;
    char *sockArg;
    int sockArgSize;

    struct ip_mreq mreq4;
    struct ipv6_mreq mreq6;

    if (groupAddress.protocol() == QAbstractSocket::IPv6Protocol) {
        level = IPPROTO_IPV6;
        sockOpt = how6;
        sockArg = reinterpret_cast<char *>(&mreq6);
        sockArgSize = sizeof(mreq6);
        memset(&mreq6, 0, sizeof(mreq6));
        Q_IPV6ADDR ip6 = groupAddress.toIPv6Address();
        memcpy(&mreq6.ipv6mr_multiaddr, &ip6, sizeof(ip6));
        mreq6.ipv6mr_interface = iface.index();
    } else if (groupAddress.protocol() == QAbstractSocket::IPv4Protocol) {
        level = IPPROTO_IP;
        sockOpt = how4;
        sockArg = reinterpret_cast<char *>(&mreq4);
        sockArgSize = sizeof(mreq4);
        memset(&mreq4, 0, sizeof(mreq4));
        mreq4.imr_multiaddr.s_addr = htonl(groupAddress.toIPv4Address());

        if (iface.isValid()) {
            const QList<QNetworkAddressEntry> addressEntries = iface.addressEntries();
            bool found = false;
            for (const QNetworkAddressEntry &entry : addressEntries) {
                const QHostAddress ip = entry.ip();
                if (ip.protocol() == QAbstractSocket::IPv4Protocol) {
                    mreq4.imr_interface.s_addr = htonl(ip.toIPv4Address());
                    found = true;
                    break;
                }
            }
            if (!found) {
                d->setError(QAbstractSocket::NetworkError,
                            QNativeSocketEnginePrivate::NetworkUnreachableErrorString);
                return false;
            }
        } else {
            mreq4.imr_interface.s_addr = INADDR_ANY;
        }
    } else {
        // unreachable
        d->setError(QAbstractSocket::UnsupportedSocketOperationError,
                    QNativeSocketEnginePrivate::ProtocolUnsupportedErrorString);
        return false;
    }

    int res = setsockopt(d->socketDescriptor, level, sockOpt, sockArg, sockArgSize);
    if (res == -1) {
        d->setError(QAbstractSocket::UnsupportedSocketOperationError,
                    QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
        return false;
    }
    return true;
}

bool QNativeSocketEnginePrivate::nativeJoinMulticastGroup(const QHostAddress &groupAddress,
                                                          const QNetworkInterface &iface)
{
    return multicastMembershipHelper(this,
                                     IPV6_JOIN_GROUP,
                                     IP_ADD_MEMBERSHIP,
                                     groupAddress,
                                     iface);
}

bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
                                                           const QNetworkInterface &iface)
{
    return multicastMembershipHelper(this,
                                     IPV6_LEAVE_GROUP,
                                     IP_DROP_MEMBERSHIP,
                                     groupAddress,
                                     iface);
}

QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
{
    if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
        uint v;
        QT_SOCKOPTLEN_T sizeofv = sizeof(v);
        if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
            return QNetworkInterface();
        return QNetworkInterface::interfaceFromIndex(v);
    }

    struct in_addr v;
    v.s_addr = 0;
    QT_SOCKOPTLEN_T sizeofv = sizeof(v);
    if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
        return QNetworkInterface();
    if (v.s_addr != 0 && sizeofv >= QT_SOCKOPTLEN_T(sizeof(v))) {
        QHostAddress ipv4(ntohl(v.s_addr));
        QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
        for (int i = 0; i < ifaces.count(); ++i) {
            const QNetworkInterface &iface = ifaces.at(i);
            if (!(iface.flags() & QNetworkInterface::CanMulticast))
                continue;
            QList<QNetworkAddressEntry> entries = iface.addressEntries();
            for (int j = 0; j < entries.count(); ++j) {
                const QNetworkAddressEntry &entry = entries.at(j);
                if (entry.ip() == ipv4)
                    return iface;
            }
        }
    }
    return QNetworkInterface();
}

bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface)
{

    if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
        uint v = iface.isValid() ? iface.index() : 0;
        return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
    }

    struct in_addr v;
    if (iface.isValid()) {
        QList<QNetworkAddressEntry> entries = iface.addressEntries();
        for (int i = 0; i < entries.count(); ++i) {
            const QNetworkAddressEntry &entry = entries.at(i);
            const QHostAddress &ip = entry.ip();
            if (ip.protocol() == QAbstractSocket::IPv4Protocol) {
                v.s_addr = htonl(ip.toIPv4Address());
                int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v));
                if (r != -1)
                    return true;
            }
        }
        return false;
    }

    v.s_addr = INADDR_ANY;
    return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
}

qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
{
    unsigned long  nbytes = 0;
    unsigned long dummy = 0;
    DWORD sizeWritten = 0;
    if (::WSAIoctl(socketDescriptor, FIONREAD, &dummy, sizeof(dummy), &nbytes, sizeof(nbytes), &sizeWritten, 0,0) == SOCKET_ERROR) {
        WS_ERROR_DEBUG(WSAGetLastError());
        return -1;
    }

    // ioctlsocket sometimes reports 1 byte available for datagrams
    // while the following recvfrom returns -1 and claims connection
    // was reset (udp is connectionless). so we peek one byte to
    // catch this case and return 0 bytes available if recvfrom
    // fails.
    if (nbytes == 1 && socketType == QAbstractSocket::UdpSocket) {
        char c;
        WSABUF buf;
        buf.buf = &c;
        buf.len = sizeof(c);
        DWORD bytesReceived;
        DWORD flags = MSG_PEEK;
        if (::WSARecvFrom(socketDescriptor, &buf, 1, &bytesReceived, &flags, 0,0,0,0) == SOCKET_ERROR) {
            int err = WSAGetLastError();
            if (err != WSAECONNRESET && err != WSAENETRESET)
                return 0;
        } else {
            return bytesReceived;
        }
    }
    return nbytes;
}


bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const
{
    // Create a sockaddr struct and reset its port number.
    qt_sockaddr storage;
    QT_SOCKLEN_T storageSize = sizeof(storage);
    memset(&storage, 0, storageSize);

    bool result = false;

    // Peek 0 bytes into the next message. The size of the message may
    // well be 0, so we check if there was a sender.
    char c;
    WSABUF buf;
    buf.buf = &c;
    buf.len = sizeof(c);
    DWORD available = 0;
    DWORD flags = MSG_PEEK;
    int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, &storage.a, &storageSize,0,0);
    int err = WSAGetLastError();
    if (ret == SOCKET_ERROR && err !=  WSAEMSGSIZE) {
        WS_ERROR_DEBUG(err);
        result = (err == WSAECONNRESET || err == WSAENETRESET);
    } else {
        // If there's no error, or if our buffer was too small, there must be
        // a pending datagram.
        result = true;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == %s",
           result ? "true" : "false");
#endif
    return result;
}


qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
{
    qint64 ret = -1;
    int recvResult = 0;
    DWORD flags;
    // We increase the amount we peek by 2048 * 5 on each iteration
    // Grabs most cases fast and early.
    char udpMessagePeekBuffer[2048];
    const int increments = 5;
    QVarLengthArray<WSABUF, 10> buf;
    for (;;) {
        buf.reserve(buf.size() + increments);
        std::fill_n(std::back_inserter(buf), increments, WSABUF{sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});

        flags = MSG_PEEK;
        DWORD bytesRead = 0;
        recvResult = ::WSARecv(socketDescriptor, buf.data(), DWORD(buf.size()), &bytesRead, &flags, nullptr, nullptr);
        int err = WSAGetLastError();
        if (recvResult != SOCKET_ERROR) {
            ret = qint64(bytesRead);
            break;
        } else {
            switch (err) {
            case WSAEMSGSIZE:
                continue;
            case WSAECONNRESET:
            case WSAENETRESET:
                ret = 0;
                break;
            default:
                WS_ERROR_DEBUG(err);
                ret = -1;
                break;
            }
            break;
        }
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret);
#endif

    return ret;
}

qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
                                                         QAbstractSocketEngine::PacketHeaderOptions options)
{
    union {
        char cbuf[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo)) + WSA_CMSG_SPACE(sizeof(int))];
        WSACMSGHDR align;    // only to ensure alignment
    };
    WSAMSG msg;
    WSABUF buf;
    qt_sockaddr aa;
    char c;
    memset(&msg, 0, sizeof(msg));
    memset(&aa, 0, sizeof(aa));

    // we need to receive at least one byte, even if our user isn't interested in it
    buf.buf = maxLength ? data : &c;
    buf.len = maxLength ? maxLength : 1;
    msg.lpBuffers = &buf;
    msg.dwBufferCount = 1;
    msg.name = reinterpret_cast<LPSOCKADDR>(&aa);
    msg.namelen = sizeof(aa);
    msg.Control.buf = cbuf;
    msg.Control.len = sizeof(cbuf);

    DWORD flags = 0;
    DWORD bytesRead = 0;
    qint64 ret;

    if (recvmsg)
        ret = recvmsg(socketDescriptor, &msg, &bytesRead, 0,0);
    else
        ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, msg.name, &msg.namelen,0,0);
    if (ret == SOCKET_ERROR) {
        int err = WSAGetLastError();
        if (err == WSAEMSGSIZE) {
            // it is ok the buffer was to small if bytesRead is larger than
            // maxLength then assume bytes read is really maxLenth
            ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead);
            if (options & QNativeSocketEngine::WantDatagramSender)
                qt_socket_getPortAndAddress(socketDescriptor, &aa, &header->senderPort, &header->senderAddress);
        } else {
            WS_ERROR_DEBUG(err);
            switch (err) {
            case WSAENETRESET:
                setError(QAbstractSocket::NetworkError, NetworkDroppedConnectionErrorString);
                break;
            case WSAECONNRESET:
                setError(QAbstractSocket::ConnectionRefusedError, ConnectionResetErrorString);
                break;
            default:
                setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
                break;
            }
            ret = -1;
            if (header)
                header->clear();
        }
    } else {
        ret = qint64(bytesRead);
        if (options & QNativeSocketEngine::WantDatagramSender)
            qt_socket_getPortAndAddress(socketDescriptor, &aa, &header->senderPort, &header->senderAddress);
    }

    if (ret != -1 && recvmsg && options != QAbstractSocketEngine::WantNone) {
        // get the ancillary data
        header->destinationPort = localPort;
        WSACMSGHDR *cmsgptr;
        for (cmsgptr = WSA_CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
             cmsgptr = WSA_CMSG_NXTHDR(&msg, cmsgptr)) {
            if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO
                    && cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in6_pktinfo))) {
                in6_pktinfo *info = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsgptr));

                header->destinationAddress.setAddress(reinterpret_cast<quint8 *>(&info->ipi6_addr));
                header->ifindex = info->ipi6_ifindex;
                if (header->ifindex)
                    header->destinationAddress.setScopeId(QString::number(info->ipi6_ifindex));
            }
            if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_PKTINFO
                    && cmsgptr->cmsg_len >= WSA_CMSG_LEN(sizeof(in_pktinfo))) {
                in_pktinfo *info = reinterpret_cast<in_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
                u_long addr;
                WSANtohl(socketDescriptor, info->ipi_addr.s_addr, &addr);
                header->destinationAddress.setAddress(addr);
                header->ifindex = info->ipi_ifindex;
            }

            if (cmsgptr->cmsg_len == WSA_CMSG_LEN(sizeof(int))
                    && ((cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_HOPLIMIT)
                        || (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_TTL))) {
                header->hopLimit = *reinterpret_cast<int *>(WSA_CMSG_DATA(cmsgptr));
            }
        }
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    bool printSender = (ret != -1 && (options & QNativeSocketEngine::WantDatagramSender) != 0);
    qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",
           data, qt_prettyDebug(data, qMin<qint64>(ret, 16), ret).data(), maxLength,
           printSender ? header->senderAddress.toString().toLatin1().constData() : "(unknown)",
           printSender ? header->senderPort : 0, ret);
#endif

    return ret;
}


qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len,
                                                      const QIpPacketHeader &header)
{
    union {
        char cbuf[WSA_CMSG_SPACE(sizeof(struct in6_pktinfo)) + WSA_CMSG_SPACE(sizeof(int))];
        WSACMSGHDR align;    // ensures alignment
    };
    WSACMSGHDR *cmsgptr = &align;
    WSAMSG msg;
    WSABUF buf;
    qt_sockaddr aa;

    memset(&msg, 0, sizeof(msg));
    memset(&aa, 0, sizeof(aa));
    buf.buf = len ? (char*)data : 0;
    msg.lpBuffers = &buf;
    msg.dwBufferCount = 1;
    msg.name = &aa.a;
    buf.len = len;

    setPortAndAddress(header.destinationPort, header.destinationAddress, &aa, &msg.namelen);

    uint oldIfIndex = 0;
    bool mustSetIpv6MulticastIf = false;

    if (msg.namelen == sizeof(aa.a6)) {
        // sending IPv6
        if (header.hopLimit != -1) {
            msg.Control.len += WSA_CMSG_SPACE(sizeof(int));
            cmsgptr->cmsg_len = WSA_CMSG_LEN(sizeof(int));
            cmsgptr->cmsg_level = IPPROTO_IPV6;
            cmsgptr->cmsg_type = IPV6_HOPLIMIT;
            memcpy(WSA_CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
            cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
                                                     + WSA_CMSG_SPACE(sizeof(int)));
        }
        if (!header.senderAddress.isNull()) {
            struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
            memset(data, 0, sizeof(*data));
            msg.Control.len += WSA_CMSG_SPACE(sizeof(*data));
            cmsgptr->cmsg_len = WSA_CMSG_LEN(sizeof(*data));
            cmsgptr->cmsg_level = IPPROTO_IPV6;
            cmsgptr->cmsg_type = IPV6_PKTINFO;
            data->ipi6_ifindex = header.ifindex;

            Q_IPV6ADDR tmp = header.senderAddress.toIPv6Address();
            memcpy(&data->ipi6_addr, &tmp, sizeof(tmp));
            cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
                                                     + WSA_CMSG_SPACE(sizeof(*data)));
        } else if (header.ifindex != 0) {
            // Unlike other operating systems, setting the interface index in the in6_pktinfo
            // structure above and leaving the ipi6_addr set to :: will cause the packets to be
            // sent with source address ::. So we have to use IPV6_MULTICAST_IF, which MSDN is
            // quite clear that "This option does not change the default interface for receiving
            // IPv6 multicast traffic."
            QT_SOCKOPTLEN_T len = sizeof(oldIfIndex);
            if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                             reinterpret_cast<char *>(&oldIfIndex), &len) == -1
                    || ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                                    reinterpret_cast<const char *>(&header.ifindex), sizeof(header.ifindex)) == -1) {
                setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
                return -1;
            }
            mustSetIpv6MulticastIf = true;
        }
    } else {
        // sending IPv4
        if (header.hopLimit != -1) {
            msg.Control.len += WSA_CMSG_SPACE(sizeof(int));
            cmsgptr->cmsg_len = WSA_CMSG_LEN(sizeof(int));
            cmsgptr->cmsg_level = IPPROTO_IP;
            cmsgptr->cmsg_type = IP_TTL;
            memcpy(WSA_CMSG_DATA(cmsgptr), &header.hopLimit, sizeof(int));
            cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
                                                     + WSA_CMSG_SPACE(sizeof(int)));
        }
        if (header.ifindex != 0 || !header.senderAddress.isNull()) {
            struct in_pktinfo *data = reinterpret_cast<in_pktinfo *>(WSA_CMSG_DATA(cmsgptr));
            memset(data, 0, sizeof(*data));
            msg.Control.len += WSA_CMSG_SPACE(sizeof(*data));
            cmsgptr->cmsg_len = WSA_CMSG_LEN(sizeof(*data));
            cmsgptr->cmsg_level = IPPROTO_IP;
            cmsgptr->cmsg_type = IP_PKTINFO;
            data->ipi_ifindex = header.ifindex;
            WSAHtonl(socketDescriptor, header.senderAddress.toIPv4Address(), &data->ipi_addr.s_addr);
            cmsgptr = reinterpret_cast<WSACMSGHDR *>(reinterpret_cast<char *>(cmsgptr)
                                                     + WSA_CMSG_SPACE(sizeof(*data)));
        }
    }

    if (msg.Control.len != 0)
        msg.Control.buf = cbuf;

    DWORD flags = 0;
    DWORD bytesSent = 0;
    qint64 ret = -1;
    if (sendmsg) {
        ret = sendmsg(socketDescriptor, &msg, flags, &bytesSent, 0,0);
    } else {
        ret = ::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, msg.name, msg.namelen, 0,0);
    }
    if (ret == SOCKET_ERROR) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSAEMSGSIZE:
            setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
            break;
        default:
            setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
            break;
        }
        ret = -1;
    } else {
        ret = qint64(bytesSent);
    }

    if (mustSetIpv6MulticastIf) {
        // undo what we did above
        ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF,
                     reinterpret_cast<char *>(&oldIfIndex), sizeof(oldIfIndex));
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
           qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), len,
           header.destinationAddress.toString().toLatin1().constData(),
           header.destinationPort, ret);
#endif

    return ret;
}


qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len)
{
    Q_Q(QNativeSocketEngine);
    qint64 ret = 0;
    qint64 bytesToSend = len;

    for (;;) {
        WSABUF buf;
        buf.buf = const_cast<char*>(data) + ret;
        buf.len = bytesToSend;
        DWORD flags = 0;
        DWORD bytesWritten = 0;

        int socketRet = ::WSASend(socketDescriptor, &buf, 1, &bytesWritten, flags, 0,0);

        ret += qint64(bytesWritten);

        int err;
        if (socketRet != SOCKET_ERROR) {
            if (ret == len || bytesToSend != qint64(bytesWritten))
                break;
        } else if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) {
            break;
        } else if (err == WSAENOBUFS) {
            // this function used to not send more than 49152 per call to WSASendTo
            // to avoid getting a WSAENOBUFS. However this is a performance regression
            // and we think it only appears with old windows versions. We now handle the
            // WSAENOBUFS and hope it never appears anyway.
            // just go on, the next loop run we will try a smaller number
        } else {
            WS_ERROR_DEBUG(err);
            switch (err) {
            case WSAECONNRESET:
            case WSAECONNABORTED:
                ret = -1;
                setError(QAbstractSocket::NetworkError, WriteErrorString);
                q->close();
                break;
            default:
                break;
            }
            break;
        }

        // for next send:
        bytesToSend = qMin<qint64>(49152, len - ret);
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %lli) == %lli",
           data, qt_prettyDebug(data, qMin(int(ret), 16), int(ret)).data(), len, ret);
#endif

    return ret;
}

qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxLength)
{
    qint64 ret = -1;
    WSABUF buf;
    buf.buf = data;
    buf.len = maxLength;
    DWORD flags = 0;
    DWORD bytesRead = 0;
    if (::WSARecv(socketDescriptor, &buf, 1, &bytesRead, &flags, 0,0) ==  SOCKET_ERROR) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSAEWOULDBLOCK:
            ret = -2;
            break;
        case WSAEBADF:
        case WSAEINVAL:
            //error string is now set in read(), not here in nativeRead()
            break;
        case WSAECONNRESET:
        case WSAECONNABORTED:
            // for tcp sockets this will be handled in QNativeSocketEngine::read
            ret = 0;
            break;
        default:
            break;
        }
    } else {
        if (WSAGetLastError() == WSAEWOULDBLOCK)
            ret = -2;
        else
            ret = qint64(bytesRead);
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    if (ret != -2) {
        qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %lli) == %lli",
               data, qt_prettyDebug(data, qMin(int(bytesRead), 16), int(bytesRead)).data(), maxLength, ret);
    } else {
        qDebug("QNativeSocketEnginePrivate::nativeRead(%p, %lli) == -2 (WOULD BLOCK)",
               data, maxLength);
    }
#endif

    return ret;
}

int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
{
    bool readEnabled = selectForRead && readNotifier && readNotifier->isEnabled();
    if (readEnabled)
        readNotifier->setEnabled(false);

    fd_set fds;

    int ret = 0;

    memset(&fds, 0, sizeof(fd_set));
    fds.fd_count = 1;
    fds.fd_array[0] = (SOCKET)socketDescriptor;

    struct timeval tv;
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;

    if (selectForRead) {
        ret = select(0, &fds, 0, 0, timeout < 0 ? 0 : &tv);
    } else {
        // select for write

        // Windows needs this to report errors when connecting a socket ...
        fd_set fdexception;
        FD_ZERO(&fdexception);
        FD_SET((SOCKET)socketDescriptor, &fdexception);

        ret = select(0, 0, &fds, &fdexception, timeout < 0 ? 0 : &tv);

        // ... but if it is actually set, pretend it did not happen
        if (ret > 0 && FD_ISSET((SOCKET)socketDescriptor, &fdexception))
            ret--;
    }

    if (readEnabled)
        readNotifier->setEnabled(true);

    return ret;
}

int QNativeSocketEnginePrivate::nativeSelect(int timeout,
                                      bool checkRead, bool checkWrite,
                                      bool *selectForRead, bool *selectForWrite) const
{
    bool readEnabled = checkRead && readNotifier && readNotifier->isEnabled();
    if (readEnabled)
        readNotifier->setEnabled(false);

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexception;

    int ret = 0;

    memset(&fdread, 0, sizeof(fd_set));
    if (checkRead) {
        fdread.fd_count = 1;
        fdread.fd_array[0] = (SOCKET)socketDescriptor;
    }
    memset(&fdwrite, 0, sizeof(fd_set));
    FD_ZERO(&fdexception);
    if (checkWrite) {
        fdwrite.fd_count = 1;
        fdwrite.fd_array[0] = (SOCKET)socketDescriptor;

        // Windows needs this to report errors when connecting a socket
        FD_SET((SOCKET)socketDescriptor, &fdexception);
    }

    struct timeval tv;
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;

    ret = select(socketDescriptor + 1, &fdread, &fdwrite, &fdexception, timeout < 0 ? 0 : &tv);

     //... but if it is actually set, pretend it did not happen
    if (ret > 0 && FD_ISSET((SOCKET)socketDescriptor, &fdexception))
        ret--;

    if (readEnabled)
        readNotifier->setEnabled(true);

    if (ret <= 0)
        return ret;

    *selectForRead = FD_ISSET((SOCKET)socketDescriptor, &fdread);
    *selectForWrite = FD_ISSET((SOCKET)socketDescriptor, &fdwrite);

    return ret;
}

void QNativeSocketEnginePrivate::nativeClose()
{
#if defined (QTCPSOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeClose()");
#endif
    // We were doing a setsockopt here before with SO_DONTLINGER. (However with kind of wrong
    // usage of parameters, it wants a BOOL but we used a struct and pretended it to be bool).
    // We don't think setting this option should be done here, if a user wants it she/he can
     // do it manually with socketDescriptor()/setSocketDescriptor();
    ::closesocket(socketDescriptor);
}

QT_END_NAMESPACE
