/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/test/channel_transport/udp_socket2_win.h"

#include <assert.h>
#include <stdlib.h>
#include <winsock2.h>

#include "webrtc/base/format_macros.h"
#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/test/channel_transport/traffic_control_win.h"
#include "webrtc/test/channel_transport/udp_socket2_manager_win.h"

#pragma warning(disable : 4311)

namespace webrtc {
namespace test {

typedef struct _QOS_DESTADDR
{
    QOS_OBJECT_HDR ObjectHdr;
    const struct sockaddr* SocketAddress;
    ULONG SocketAddressLength;
} QOS_DESTADDR, *LPQOS_DESTADDR;

typedef const QOS_DESTADDR* LPCQOS_DESTADDR;

// TODO (patrikw): seems to be defined in ws2ipdef.h as 3. How come it's
//                 redefined here (as a different value)?
#define IP_TOS 8

#define QOS_GENERAL_ID_BASE 2000
#define QOS_OBJECT_DESTADDR (0x00000004 + QOS_GENERAL_ID_BASE)

UdpSocket2Windows::UdpSocket2Windows(const int32_t id,
                                     UdpSocketManager* mgr, bool ipV6Enable,
                                     bool disableGQOS)
    : _id(id),
      _qos(true),
      _iProtocol(0),
      _outstandingCalls(0),
      _outstandingCallComplete(0),
      _terminate(false),
      _addedToMgr(false),
      _safeTodelete(false),
      _outstandingCallsDisabled(false),
      _clientHandle(NULL),
      _flowHandle(NULL),
      _filterHandle(NULL),
      _flow(NULL),
      _gtc(NULL),
      _pcp(-2),
      _receiveBuffers(0)
{
    WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
                 "UdpSocket2Windows::UdpSocket2Windows()");

    _wantsIncoming = false;
    _mgr = static_cast<UdpSocket2ManagerWindows *>(mgr);

    _obj = NULL;
    _incomingCb = NULL;
    _socket = INVALID_SOCKET;
    _pCrit = CriticalSectionWrapper::CreateCriticalSection();
    _ptrCbRWLock     = RWLockWrapper::CreateRWLock();
    _ptrDestRWLock   = RWLockWrapper::CreateRWLock();
    _ptrSocketRWLock = RWLockWrapper::CreateRWLock();
    _ptrDeleteCrit   = CriticalSectionWrapper::CreateCriticalSection();
    _ptrDeleteCond   = ConditionVariableWrapper::CreateConditionVariable();

    // Check if QoS is supported.
    BOOL bProtocolFound = FALSE;
    WSAPROTOCOL_INFO *lpProtocolBuf = NULL;
    WSAPROTOCOL_INFO    pProtocolInfo;

    if(!disableGQOS)
    {
        DWORD dwBufLen = 0;
        // Set dwBufLen to the size needed to retreive all the requested
        // information from WSAEnumProtocols.
        int32_t nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
        lpProtocolBuf = (WSAPROTOCOL_INFO*)malloc(dwBufLen);
        nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);

        if (ipV6Enable)
        {
            _iProtocol=AF_INET6;
        } else {
            _iProtocol=AF_INET;
        }

        for (int32_t i=0; i<nRet; i++)
        {
            if (_iProtocol == lpProtocolBuf[i].iAddressFamily &&
                IPPROTO_UDP == lpProtocolBuf[i].iProtocol)
            {
                if ((XP1_QOS_SUPPORTED ==
                     (XP1_QOS_SUPPORTED & lpProtocolBuf[i].dwServiceFlags1)))
                {
                    pProtocolInfo = lpProtocolBuf[i];
                    bProtocolFound = TRUE;
                    break;
                }
            }
         }
    }

    if(!bProtocolFound)
    {
        free(lpProtocolBuf);
        _qos=false;
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS,\
 !bProtocolFound");
    } else {

        _socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
                            FROM_PROTOCOL_INFO,&pProtocolInfo, 0,
                            WSA_FLAG_OVERLAPPED);
        free(lpProtocolBuf);

        if (_socket != INVALID_SOCKET)
        {
            return;
        } else {
            _qos = false;
            WEBRTC_TRACE(
                kTraceError,
                kTraceTransport,
                _id,
                "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS");
        }
    }
    // QoS not supported.
    if(ipV6Enable)
    {
        _socket = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0 , 0,
                            WSA_FLAG_OVERLAPPED);
    }else
    {
        _socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0 , 0,
                            WSA_FLAG_OVERLAPPED);
    }
    if (_socket == INVALID_SOCKET)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), INVALID_SOCKET,\
 WSAerror: %d",
            WSAGetLastError());
    }

    // Disable send buffering on the socket to improve CPU usage.
    // This is done by setting SO_SNDBUF to 0.
    int32_t nZero = 0;
    int32_t nRet = setsockopt(_socket, SOL_SOCKET, SO_SNDBUF,
                              (char*)&nZero, sizeof(nZero));
    if( nRet == SOCKET_ERROR )
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR,\
 WSAerror: %d",
            WSAGetLastError());
    }
}

UdpSocket2Windows::~UdpSocket2Windows()
{
    WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
                 "UdpSocket2Windows::~UdpSocket2Windows()");

    WaitForOutstandingCalls();

    delete _ptrCbRWLock;
    delete _ptrDeleteCrit;
    delete _ptrDeleteCond;
    delete _ptrDestRWLock;
    delete _ptrSocketRWLock;

    if(_pCrit)
        delete _pCrit;

    if (_flow)
    {
        free(_flow);
        _flow = NULL;
    }

    if (_gtc)
    {
        if(_filterHandle)
        {
            _gtc->TcDeleteFilter(_filterHandle);
        }
        if(_flowHandle)
        {
            _gtc->TcDeleteFlow(_flowHandle);
        }
        TrafficControlWindows::Release( _gtc);
    }
}

bool UdpSocket2Windows::ValidHandle()
{
    return GetFd() != INVALID_SOCKET;
}

bool UdpSocket2Windows::SetCallback(CallbackObj obj, IncomingSocketCallback cb)
{
    _ptrCbRWLock->AcquireLockExclusive();
    _obj = obj;
    _incomingCb = cb;
    _ptrCbRWLock->ReleaseLockExclusive();

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::SetCallback ",(int32_t)this);
    if(_addedToMgr)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::SetCallback alreadey added",
                     (int32_t) this);
        return false;

    }
    if (_mgr->AddSocket(this))
    {
        WEBRTC_TRACE(
            kTraceDebug, kTraceTransport, _id,
            "UdpSocket2Windows(%d)::SetCallback socket added to manager",
            (int32_t)this);
        _addedToMgr = true;
        return true;
    }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::SetCallback error adding me to mgr",
                 (int32_t) this);
    return false;
}

bool UdpSocket2Windows::SetSockopt(int32_t level, int32_t optname,
                                   const int8_t* optval, int32_t optlen)
{
    bool returnValue = true;
    if(!AquireSocket())
    {
        return false;
    }
    if(0 != setsockopt(_socket, level, optname,
                       reinterpret_cast<const char*>(optval), optlen ))
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetSockopt(), WSAerror:%d",
                     WSAGetLastError());
        returnValue = false;
    }
    ReleaseSocket();
    return returnValue;
}

bool UdpSocket2Windows::StartReceiving(uint32_t receiveBuffers)
{
    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::StartReceiving(%d)", (int32_t)this,
                 receiveBuffers);

    _wantsIncoming = true;

    int32_t numberOfReceiveBuffersToCreate =
        receiveBuffers - _receiveBuffers.Value();
    numberOfReceiveBuffersToCreate = (numberOfReceiveBuffersToCreate < 0) ?
        0 : numberOfReceiveBuffersToCreate;

    int32_t error = 0;
    for(int32_t i = 0;
        i < numberOfReceiveBuffersToCreate;
        i++)
    {
        if(PostRecv())
        {
            WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                         "UdpSocket2Windows::StartReceiving() i=%d", i);
            error = -1;
            break;
        }
        ++_receiveBuffers;
    }
    if(error == -1)
    {
        return false;
    }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "Socket receiving using:%d number of buffers",
                 _receiveBuffers.Value());
    return true;
}

bool UdpSocket2Windows::StopReceiving()
{
    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows::StopReceiving()");
    _wantsIncoming = false;
    return true;
}

bool UdpSocket2Windows::Bind(const SocketAddress& name)
{
    const struct sockaddr* addr =
        reinterpret_cast<const struct sockaddr*>(&name);
    bool returnValue = true;
    if(!AquireSocket())
    {
        return false;
    }
    if (0 != bind(_socket, addr, sizeof(SocketAddress)))
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::Bind() WSAerror: %d",
                     WSAGetLastError());
        returnValue = false;
    }
    ReleaseSocket();
    return returnValue;
}

int32_t UdpSocket2Windows::SendTo(const int8_t* buf, size_t len,
                                  const SocketAddress& to)
{
    int32_t retVal = 0;
    int32_t error = 0;
    PerIoContext* pIoContext = _mgr->PopIoContext();
    if(pIoContext == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::SendTo(), pIoContext==0",
                     (int32_t) this);
        return -1;
    }
    // sizeof(pIoContext->buffer) is smaller than the highest number that
    // can be represented by a size_t.
    if(len >= sizeof(pIoContext->buffer))
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::SendTo(), len= %" PRIuS
            " > buffer_size = %d",
            (int32_t) this,
            len,sizeof(pIoContext->buffer));
        len = sizeof(pIoContext->buffer);
    }

    memcpy(pIoContext->buffer,buf,len);
    pIoContext->wsabuf.buf = pIoContext->buffer;
    pIoContext->wsabuf.len = static_cast<ULONG>(len);
    pIoContext->fromLen=sizeof(SocketAddress);
    pIoContext->ioOperation = OP_WRITE;
    pIoContext->nTotalBytes = len;
    pIoContext->nSentBytes=0;

    DWORD numOfbytesSent = 0;
    const struct sockaddr* addr = reinterpret_cast<const struct sockaddr*>(&to);

    if(!AquireSocket())
    {
        _mgr->PushIoContext(pIoContext);
        return -1;
    }
    // Assume that the WSASendTo call will be successfull to make sure that
    // _outstandingCalls is positive. Roll back if WSASendTo failed.
    if(!NewOutstandingCall())
    {
        _mgr->PushIoContext(pIoContext);
        ReleaseSocket();
        return -1;
    }
    retVal = WSASendTo(_socket, &pIoContext->wsabuf, 1, &numOfbytesSent,
                       0, addr, sizeof(SocketAddress),
                       &(pIoContext->overlapped), 0);
    ReleaseSocket();

    if( retVal == SOCKET_ERROR  )
    {
        error =  WSAGetLastError();
        if(error != ERROR_IO_PENDING)
        {
            WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                         "UdpSocket2Windows::SendTo() WSAerror: %d",error);
        }
    }
    if(retVal == 0 || (retVal == SOCKET_ERROR && error == ERROR_IO_PENDING))
    {
        return static_cast<int32_t>(len);
    }
    error = _mgr->PushIoContext(pIoContext);
    if(error)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::SendTo(), error:%d pushing ioContext",
            (int32_t)this, error);
    }

    // Roll back.
    OutstandingCallCompleted();
    return -1;
}

void UdpSocket2Windows::IOCompleted(PerIoContext* pIOContext,
                                    uint32_t ioSize, uint32_t error)
{
    if(pIOContext == NULL || error == ERROR_OPERATION_ABORTED)
    {
        if ((pIOContext != NULL) &&
            !pIOContext->ioInitiatedByThreadWrapper &&
            (error == ERROR_OPERATION_ABORTED) &&
            (pIOContext->ioOperation == OP_READ) &&
            _outstandingCallsDisabled)
        {
            // !pIOContext->initiatedIOByThreadWrapper indicate that the I/O
            // was not initiated by a ThreadWrapper thread.
            // This may happen if the thread that initiated receiving (e.g.
            // by calling StartListen())) is deleted before any packets have
            // been received.
            // In this case there is no packet in the PerIoContext. Re-use it
            // to post a new PostRecv(..).
            // Note 1: the PerIoContext will henceforth be posted by a thread
            //         that is controlled by the socket implementation.
            // Note 2: This is more likely to happen to RTCP packets as
            //         they are less frequent than RTP packets.
            // Note 3: _outstandingCallsDisabled being false indicates
            //         that the socket isn't being shut down.
            // Note 4: This should only happen buffers set to receive packets
            //         (OP_READ).
        } else {
            if(pIOContext == NULL)
            {
                WEBRTC_TRACE(
                    kTraceError,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows::IOCompleted(%d,%d,%d), %d",
                    (int32_t)pIOContext,
                    ioSize,
                    error,
                    pIOContext ? (int32_t)pIOContext->ioOperation : -1);
            } else {
                WEBRTC_TRACE(
                    kTraceDebug,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows::IOCompleted() Operation aborted");
            }
            if(pIOContext)
            {
                int32_t remainingReceiveBuffers = --_receiveBuffers;
                if(remainingReceiveBuffers < 0)
                {
                    assert(false);
                }
                int32_t err = _mgr->PushIoContext(pIOContext);
                if(err)
                {
                    WEBRTC_TRACE(
                        kTraceError,
                        kTraceTransport,
                        _id,
                        "UdpSocket2Windows::IOCompleted(), err = %d, when\
 pushing ioContext after error",
                        err);
                }
            }
            OutstandingCallCompleted();
            return;
        }
    }  // if (pIOContext == NULL || error == ERROR_OPERATION_ABORTED)

    if(pIOContext->ioOperation == OP_WRITE)
    {
        _mgr->PushIoContext(pIOContext);
    }
    else if(pIOContext->ioOperation == OP_READ)
    {
        if(!error && ioSize != 0)
        {
            _ptrCbRWLock->AcquireLockShared();
            if(_wantsIncoming && _incomingCb)
            {
                _incomingCb(_obj,
                            reinterpret_cast<const int8_t*>(
                                pIOContext->wsabuf.buf),
                            ioSize,
                            &pIOContext->from);
            }
            _ptrCbRWLock->ReleaseLockShared();
        }
        int32_t err = PostRecv(pIOContext);
        if(err == 0)
        {
            // The PerIoContext was posted by a thread controlled by the socket
            // implementation.
            pIOContext->ioInitiatedByThreadWrapper = true;
        }
        OutstandingCallCompleted();
        return;
    } else {
        // Unknown operation. Should not happen. Return pIOContext to avoid
        // memory leak.
        assert(false);
        _mgr->PushIoContext(pIOContext);
    }
    OutstandingCallCompleted();
    // Don't touch any members after OutstandingCallCompleted() since the socket
    // may be deleted at this point.
}

int32_t UdpSocket2Windows::PostRecv()
{
    PerIoContext* pIoContext=_mgr->PopIoContext();
    if(pIoContext == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::PostRecv(), pIoContext == 0",
                     (int32_t)this);
        return -1;
    }
    // This function may have been called by thread not controlled by the socket
    // implementation.
    pIoContext->ioInitiatedByThreadWrapper = false;
    return PostRecv(pIoContext);
}

int32_t UdpSocket2Windows::PostRecv(PerIoContext* pIoContext)
{
    if(pIoContext==0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::PostRecv(?), pIoContext==0",
                     (int32_t)this);
        return -1;
    }

    DWORD numOfRecivedBytes = 0;
    DWORD flags = 0;
    pIoContext->wsabuf.buf = pIoContext->buffer;
    pIoContext->wsabuf.len = sizeof(pIoContext->buffer);
    pIoContext->fromLen = sizeof(SocketAddress);
    pIoContext->ioOperation = OP_READ;
    int32_t rxError = 0;
    int32_t nRet = 0;
    int32_t postingSucessfull = false;

    if(!AquireSocket())
    {
        _mgr->PushIoContext(pIoContext);
        return -1;
    }

    // Assume that the WSARecvFrom() call will be successfull to make sure that
    // _outstandingCalls is positive. Roll back if WSARecvFrom() failed.
    if(!NewOutstandingCall())
    {
        _mgr->PushIoContext(pIoContext);
        ReleaseSocket();
        return -1;
    }
    for(int32_t tries = 0; tries < 10; tries++)
    {
        nRet = WSARecvFrom(
            _socket,
            &(pIoContext->wsabuf),
            1,
            &numOfRecivedBytes,
            &flags,
            reinterpret_cast<struct sockaddr*>(&(pIoContext->from)),
            &(pIoContext->fromLen),
            &(pIoContext->overlapped),
            0);

        if( nRet == SOCKET_ERROR)
        {
            rxError = WSAGetLastError();
            if(rxError != ERROR_IO_PENDING)
            {
                WEBRTC_TRACE(
                    kTraceError,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows(%d)::PostRecv(?), WSAerror:%d when\
 posting new recieve,trie:%d",
                    (int32_t)this,
                    rxError,
                    tries);
                // Tell the OS that this is a good place to context switch if
                // it wants to.
                SleepMs(0);
            }
        }
        if((rxError == ERROR_IO_PENDING) || (nRet == 0))
        {
            postingSucessfull = true;
            break;
        }
    }
    ReleaseSocket();

    if(postingSucessfull)
    {
        return 0;
    }
    int32_t remainingReceiveBuffers = --_receiveBuffers;
    if(remainingReceiveBuffers < 0)
    {
        assert(false);
    }
    int32_t error = _mgr->PushIoContext(pIoContext);
    if(error)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::PostRecv(?), error:%d when PushIoContext",
            (int32_t)this,
            error);
    }
    // Roll back.
    OutstandingCallCompleted();
    return -1;
}

void UdpSocket2Windows::CloseBlocking()
{
    LINGER  lingerStruct;

    lingerStruct.l_onoff = 1;
    lingerStruct.l_linger = 0;
    if(AquireSocket())
    {
        setsockopt(_socket, SOL_SOCKET, SO_LINGER,
                   reinterpret_cast<const char*>(&lingerStruct),
                   sizeof(lingerStruct));
        ReleaseSocket();
    }

    _wantsIncoming = false;
    // Reclaims the socket and prevents it from being used again.
    InvalidateSocket();
    DisableNewOutstandingCalls();
    WaitForOutstandingCalls();
    delete this;
}

bool UdpSocket2Windows::SetQos(int32_t serviceType,
                               int32_t tokenRate,
                               int32_t bucketSize,
                               int32_t peekBandwith,
                               int32_t minPolicedSize,
                               int32_t maxSduSize,
                               const SocketAddress &stRemName,
                               int32_t overrideDSCP)
{
    if(_qos == false)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetQos(), socket not capable of QOS");
        return false;
    }
    if(overrideDSCP != 0)
    {
        FLOWSPEC f;
        int32_t err = CreateFlowSpec(serviceType, tokenRate, bucketSize,
                                     peekBandwith, minPolicedSize,
                                     maxSduSize, &f);
        if(err == -1)
        {
            return false;
        }

        SocketAddress socketName;
        struct sockaddr_in* name =
            reinterpret_cast<struct sockaddr_in*>(&socketName);
        int nameLength = sizeof(SocketAddress);
        if(AquireSocket())
        {
            getsockname(_socket, (struct sockaddr*)name, &nameLength);
            ReleaseSocket();
        }

        if(serviceType == 0)
        {
            // Disable TOS byte setting.
            return SetTrafficControl(0, -1, name, &f, &f) == 0;
        }
        return SetTrafficControl(overrideDSCP, -1, name, &f, &f) == 0;
    }

    QOS Qos;
    DWORD BytesRet;
    QOS_DESTADDR QosDestaddr;

    memset (&Qos, QOS_NOT_SPECIFIED, sizeof(QOS));

    Qos.SendingFlowspec.ServiceType        = serviceType;
    Qos.SendingFlowspec.TokenRate          = tokenRate;
    Qos.SendingFlowspec.TokenBucketSize    = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.PeakBandwidth      = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.DelayVariation     = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.Latency            = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.MaxSduSize         = QOS_NOT_SPECIFIED;

    // Only ServiceType is needed for receiving.
    Qos.ReceivingFlowspec.ServiceType        = serviceType;
    Qos.ReceivingFlowspec.TokenRate          = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.TokenBucketSize    = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.PeakBandwidth      = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.Latency            = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.DelayVariation     = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.MaxSduSize         = QOS_NOT_SPECIFIED;

    Qos.ProviderSpecific.len = 0;

    Qos.ProviderSpecific.buf = NULL;

    ZeroMemory((int8_t *)&QosDestaddr, sizeof(QosDestaddr));

    OSVERSIONINFOEX osvie;
    osvie.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx((LPOSVERSIONINFO)&osvie);

//    Operating system        Version number    dwMajorVersion    dwMinorVersion
//    Windows 7                6.1                6                1
//    Windows Server 2008 R2   6.1                6                1
//    Windows Server 2008      6.0                6                0
//    Windows Vista            6.0                6                0
//    Windows Server 2003 R2   5.2                5                2
//    Windows Server 2003      5.2                5                2
//    Windows XP               5.1                5                1
//    Windows 2000             5.0                5                0

    // SERVICE_NO_QOS_SIGNALING and QOS_DESTADDR should not be used if version
    // is 6.0 or greater.
    if(osvie.dwMajorVersion >= 6)
    {
        Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        Qos.ReceivingFlowspec.ServiceType = serviceType;

    } else {
        Qos.SendingFlowspec.MinimumPolicedSize =
            QOS_NOT_SPECIFIED | SERVICE_NO_QOS_SIGNALING;
        Qos.ReceivingFlowspec.ServiceType =
            serviceType | SERVICE_NO_QOS_SIGNALING;

        QosDestaddr.ObjectHdr.ObjectType   = QOS_OBJECT_DESTADDR;
        QosDestaddr.ObjectHdr.ObjectLength = sizeof(QosDestaddr);
        QosDestaddr.SocketAddress = (SOCKADDR *)&stRemName;
        if (AF_INET6 == _iProtocol)
        {
            QosDestaddr.SocketAddressLength = sizeof(SocketAddressInVersion6);
        } else {
            QosDestaddr.SocketAddressLength = sizeof(SocketAddressIn);
        }

        Qos.ProviderSpecific.len = QosDestaddr.ObjectHdr.ObjectLength;
        Qos.ProviderSpecific.buf = (char*)&QosDestaddr;
    }

    if(!AquireSocket()) {
        return false;
    }
    // To set QoS with SIO_SET_QOS the socket must be locally bound first
    // or the call will fail with error code 10022.
    int32_t result = WSAIoctl(GetFd(), SIO_SET_QOS, &Qos, sizeof(QOS),
                                    NULL, 0, &BytesRet, NULL,NULL);
    ReleaseSocket();
    if (result == SOCKET_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetQos() WSAerror : %d",
                     WSAGetLastError());
        return false;
    }
    return true;
}

int32_t UdpSocket2Windows::SetTOS(int32_t serviceType)
{
    SocketAddress socketName;

    struct sockaddr_in* name =
        reinterpret_cast<struct sockaddr_in*>(&socketName);
    int nameLength = sizeof(SocketAddress);
    if(AquireSocket())
    {
        getsockname(_socket, (struct sockaddr*)name, &nameLength);
        ReleaseSocket();
    }

    int32_t res = SetTrafficControl(serviceType, -1, name);
    if (res == -1)
    {
        OSVERSIONINFO OsVersion;
        OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        GetVersionEx (&OsVersion);

        if ((OsVersion.dwMajorVersion == 4)) // NT 4.0
        {
            if(SetSockopt(IPPROTO_IP,IP_TOS ,
                          (int8_t*)&serviceType, 4) != 0)
            {
                return -1;
            }
        }
    }
    return res;
}

int32_t UdpSocket2Windows::SetPCP(int32_t pcp)
{
    SocketAddress socketName;
    struct sockaddr_in* name =
        reinterpret_cast<struct sockaddr_in*>(&socketName);
    int nameLength = sizeof(SocketAddress);
    if(AquireSocket())
    {
        getsockname(_socket, (struct sockaddr*)name, &nameLength);
        ReleaseSocket();
    }
    return SetTrafficControl(-1, pcp, name);
}

int32_t UdpSocket2Windows::SetTrafficControl(
    int32_t dscp,
    int32_t pcp,
    const struct sockaddr_in* name,
    FLOWSPEC* send, FLOWSPEC* recv)
{
    if (pcp == _pcp)
    {
        // No change.
        pcp = -1;
    }
    if ((-1 == pcp) && (-1 == dscp))
    {
        return 0;
    }
    if (!_gtc)
    {
        _gtc = TrafficControlWindows::GetInstance(_id);
    }
    if (!_gtc)
    {
        return -1;
    }
    if(_filterHandle)
    {
        _gtc->TcDeleteFilter(_filterHandle);
        _filterHandle = NULL;
    }
    if(_flowHandle)
    {
        _gtc->TcDeleteFlow(_flowHandle);
        _flowHandle = NULL;
    }
    if(_clientHandle)
    {
        _gtc->TcDeregisterClient(_clientHandle);
        _clientHandle = NULL;
    }
    if ((0 == dscp) && (-2 == _pcp) && (-1 == pcp))
    {
        // TODO (pwestin): why is this not done before deleting old filter and
        //                 flow? This scenario should probably be documented in
        //                 the function declaration.
        return 0;
    }

    TCI_CLIENT_FUNC_LIST QoSFunctions;
    QoSFunctions.ClAddFlowCompleteHandler = NULL;
    QoSFunctions.ClDeleteFlowCompleteHandler = NULL;
    QoSFunctions.ClModifyFlowCompleteHandler = NULL;
    QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler;
    // Register the client with Traffic control interface.
    HANDLE ClientHandle;
    ULONG result = _gtc->TcRegisterClient(CURRENT_TCI_VERSION, NULL,
                                          &QoSFunctions,&ClientHandle);
    if(result != NO_ERROR)
    {
        // This is likely caused by the application not being run as
        // administrator.
      WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                   "TcRegisterClient returned %d", result);
        return result;
    }

    // Find traffic control-enabled network interfaces that matches this
    // socket's IP address.
    ULONG BufferSize = 0;
    result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, NULL);

    if(result != NO_ERROR && result != ERROR_INSUFFICIENT_BUFFER)
    {
        _gtc->TcDeregisterClient(ClientHandle);
        return result;
    }

    if(result != ERROR_INSUFFICIENT_BUFFER)
    {
        // Empty buffer contains all control-enabled network interfaces. I.e.
        // QoS is not enabled.
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "QOS faild since QOS is not installed on the interface");

        _gtc->TcDeregisterClient(ClientHandle);
        return -1;
    }

    PTC_IFC_DESCRIPTOR pInterfaceBuffer =
        (PTC_IFC_DESCRIPTOR)malloc(BufferSize);
    if(pInterfaceBuffer == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "Out ot memory failure");
        _gtc->TcDeregisterClient(ClientHandle);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize,
                                         pInterfaceBuffer);

    if(result != NO_ERROR)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "Critical: error enumerating interfaces when passing in correct\
 buffer size: %d", result);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    PTC_IFC_DESCRIPTOR oneinterface;
    HANDLE ifcHandle, iFilterHandle, iflowHandle;
    bool addrFound = false;
    ULONG filterSourceAddress = ULONG_MAX;

    // Find the interface corresponding to the local address.
    for(oneinterface = pInterfaceBuffer;
        oneinterface != (PTC_IFC_DESCRIPTOR)
            (((int8_t*)pInterfaceBuffer) + BufferSize);
        oneinterface = (PTC_IFC_DESCRIPTOR)
            ((int8_t *)oneinterface + oneinterface->Length))
    {

        char interfaceName[500];
        WideCharToMultiByte(CP_ACP, 0, oneinterface->pInterfaceName, -1,
                            interfaceName, sizeof(interfaceName), 0, 0 );

        PNETWORK_ADDRESS_LIST addresses =
            &(oneinterface->AddressListDesc.AddressList);
        for(LONG i = 0; i < addresses->AddressCount ; i++)
        {
            // Only look at TCP/IP addresses.
            if(addresses->Address[i].AddressType != NDIS_PROTOCOL_ID_TCP_IP)
            {
                continue;
            }

            NETWORK_ADDRESS_IP* pIpAddr =
                (NETWORK_ADDRESS_IP*)&(addresses->Address[i].Address);
            struct in_addr in;
            in.S_un.S_addr = pIpAddr->in_addr;
            if(pIpAddr->in_addr == name->sin_addr.S_un.S_addr)
            {
                filterSourceAddress = pIpAddr->in_addr;
                addrFound = true;
            }
        }
        if(!addrFound)
        {
            continue;
        } else
        {
            break;
        }
    }
    if(!addrFound)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "QOS faild since address is not found");
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return -1;
    }
    result = _gtc->TcOpenInterfaceW(oneinterface->pInterfaceName, ClientHandle,
                                    NULL, &ifcHandle);
    if(result != NO_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "Error opening interface: %d", result);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    // Create flow if one doesn't exist.
    if (!_flow)
    {
        bool addPCP = ((pcp >= 0) || ((-1 == pcp) && (_pcp >= 0)));
        int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        _flow = (PTC_GEN_FLOW)malloc(allocSize);

        _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
        _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED;

        _flow->ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
        _flow->ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;

        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        dsClass->DSField = 0;
        dsClass->ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS;
        dsClass->ObjectHdr.ObjectLength = sizeof(QOS_DS_CLASS);

        if (addPCP)
        {
            QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
            trafficClass->TrafficClass = 0;
            trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS;
            trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS);
        }

        _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
    } else if (-1 != pcp) {
        // Reallocate memory since pcp has changed.
        PTC_GEN_FLOW oldFlow = _flow;
        bool addPCP = (pcp >= 0);
        int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        _flow = (PTC_GEN_FLOW)malloc(allocSize);

        // Copy old flow.
        _flow->ReceivingFlowspec = oldFlow->ReceivingFlowspec;
        _flow->SendingFlowspec = oldFlow->SendingFlowspec;
        // The DS info is always the first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        QOS_DS_CLASS* oldDsClass = (QOS_DS_CLASS*)oldFlow->TcObjects;
        dsClass->DSField = oldDsClass->DSField;
        dsClass->ObjectHdr.ObjectType = oldDsClass->ObjectHdr.ObjectType;
        dsClass->ObjectHdr.ObjectLength = oldDsClass->ObjectHdr.ObjectLength;

        if (addPCP)
        {
            QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
            trafficClass->TrafficClass = 0;
            trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS;
            trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS);
        }

        _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        free(oldFlow);
    }

    // Setup send and receive flow and DS object.
    if (dscp >= 0)
    {
        if (!send || (0 == dscp))
        {
            _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.PeakBandwidth =
                (0 == dscp ? QOS_NOT_SPECIFIED : POSITIVE_INFINITY_RATE);
            _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
            _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
            // 128000 * 10 is 10mbit/s.
            _flow->SendingFlowspec.TokenRate =
                (0 == dscp ? QOS_NOT_SPECIFIED : 128000 * 10);
        }
        else
        {
            _flow->SendingFlowspec.DelayVariation = send->DelayVariation;
            _flow->SendingFlowspec.Latency = send->Latency;
            _flow->SendingFlowspec.MaxSduSize = send->MaxSduSize;
            _flow->SendingFlowspec.MinimumPolicedSize =
                send->MinimumPolicedSize;
            _flow->SendingFlowspec.PeakBandwidth = send->PeakBandwidth;
            _flow->SendingFlowspec.PeakBandwidth = POSITIVE_INFINITY_RATE;
            _flow->SendingFlowspec.ServiceType = send->ServiceType;
            _flow->SendingFlowspec.TokenBucketSize = send->TokenBucketSize;
            _flow->SendingFlowspec.TokenRate = send->TokenRate;
        }

        if (!recv  || (0 == dscp))
        {
            _flow->ReceivingFlowspec.DelayVariation =
                _flow->SendingFlowspec.DelayVariation;
            _flow->ReceivingFlowspec.Latency = _flow->SendingFlowspec.Latency;
            _flow->ReceivingFlowspec.MaxSduSize =
                _flow->SendingFlowspec.MaxSduSize;
            _flow->ReceivingFlowspec.MinimumPolicedSize =
                _flow->SendingFlowspec.MinimumPolicedSize;
            _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
            _flow->ReceivingFlowspec.ServiceType =
                0 == dscp ? SERVICETYPE_BESTEFFORT : SERVICETYPE_CONTROLLEDLOAD;
            _flow->ReceivingFlowspec.TokenBucketSize =
                _flow->SendingFlowspec.TokenBucketSize;
            _flow->ReceivingFlowspec.TokenRate =
                _flow->SendingFlowspec.TokenRate;
        } else {
            _flow->ReceivingFlowspec.DelayVariation = recv->DelayVariation;
            _flow->ReceivingFlowspec.Latency = recv->Latency;
            _flow->ReceivingFlowspec.MaxSduSize = recv->MaxSduSize;
            _flow->ReceivingFlowspec.MinimumPolicedSize =
                recv->MinimumPolicedSize;
            _flow->ReceivingFlowspec.PeakBandwidth = recv->PeakBandwidth;
            _flow->ReceivingFlowspec.ServiceType = recv->ServiceType;
            _flow->ReceivingFlowspec.TokenBucketSize = recv->TokenBucketSize;
            _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
        }

        // Setup DS (for DSCP value).
        // DS is always the first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        dsClass->DSField = dscp;
    }

    // Setup PCP (802.1p priority in 802.1Q/VLAN tagging)
    if (pcp >= 0)
    {
        // DS is always first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
        trafficClass->TrafficClass = pcp;
    }

    result = _gtc->TcAddFlow(ifcHandle, NULL, 0, _flow, &iflowHandle);
    if(result != NO_ERROR)
    {
        _gtc->TcCloseInterface(ifcHandle);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return -1;
    }

    IP_PATTERN filterPattern, mask;

    ZeroMemory((int8_t*)&filterPattern, sizeof(IP_PATTERN));
    ZeroMemory((int8_t*)&mask, sizeof(IP_PATTERN));

    filterPattern.ProtocolId = IPPROTO_UDP;
    // "name" fields already in network order.
    filterPattern.S_un.S_un_ports.s_srcport = name->sin_port;
    filterPattern.SrcAddr = filterSourceAddress;

    // Unsigned max of a type corresponds to a bitmask with all bits set to 1.
    // I.e. the filter should allow all ProtocolIds, any source port and any
    // IP address
    mask.ProtocolId = UCHAR_MAX;
    mask.S_un.S_un_ports.s_srcport = USHRT_MAX;
    mask.SrcAddr = ULONG_MAX;

    TC_GEN_FILTER filter;

    filter.AddressType = NDIS_PROTOCOL_ID_TCP_IP;
    filter.Mask = (LPVOID)&mask;
    filter.Pattern = (LPVOID)&filterPattern;
    filter.PatternSize = sizeof(IP_PATTERN);

    result = _gtc->TcAddFilter(iflowHandle, &filter, &iFilterHandle);
    if(result != NO_ERROR)
    {
        _gtc->TcDeleteFlow(iflowHandle);
        _gtc->TcCloseInterface(ifcHandle);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    _flowHandle = iflowHandle;
    _filterHandle = iFilterHandle;
    _clientHandle = ClientHandle;
    if (-1 != pcp)
    {
        _pcp = pcp;
    }

    _gtc->TcCloseInterface(ifcHandle);
    free(pInterfaceBuffer);

    return 0;
}

int32_t UdpSocket2Windows::CreateFlowSpec(int32_t serviceType,
                                          int32_t tokenRate,
                                          int32_t bucketSize,
                                          int32_t peekBandwith,
                                          int32_t minPolicedSize,
                                          int32_t maxSduSize,
                                          FLOWSPEC* f)
{
    if (!f)
    {
        return -1;
    }

    f->ServiceType        = serviceType;
    f->TokenRate          = tokenRate;
    f->TokenBucketSize    = QOS_NOT_SPECIFIED;
    f->PeakBandwidth      = QOS_NOT_SPECIFIED;
    f->DelayVariation     = QOS_NOT_SPECIFIED;
    f->Latency            = QOS_NOT_SPECIFIED;
    f->MaxSduSize         = QOS_NOT_SPECIFIED;
    f->MinimumPolicedSize = QOS_NOT_SPECIFIED;
    return 0;
}

bool UdpSocket2Windows::NewOutstandingCall()
{
    assert(!_outstandingCallsDisabled);

    ++_outstandingCalls;
    return true;
}

void UdpSocket2Windows::OutstandingCallCompleted()
{
    _ptrDestRWLock->AcquireLockShared();
    ++_outstandingCallComplete;
    if((--_outstandingCalls == 0) && _outstandingCallsDisabled)
    {
        // When there are no outstanding calls and new outstanding calls are
        // disabled it is time to terminate.
        _terminate = true;
    }
    _ptrDestRWLock->ReleaseLockShared();

    if((--_outstandingCallComplete == 0) &&
        (_terminate))
    {
        // Only one thread will enter here. The thread with the last outstanding
        // call.
        CriticalSectionScoped cs(_ptrDeleteCrit);
        _safeTodelete = true;
        _ptrDeleteCond->Wake();
    }
}

void UdpSocket2Windows::DisableNewOutstandingCalls()
{
    _ptrDestRWLock->AcquireLockExclusive();
    if(_outstandingCallsDisabled)
    {
        // Outstandning calls are already disabled.
        _ptrDestRWLock->ReleaseLockExclusive();
        return;
    }
    _outstandingCallsDisabled = true;
    const bool noOutstandingCalls = (_outstandingCalls.Value() == 0);
    _ptrDestRWLock->ReleaseLockExclusive();

    RemoveSocketFromManager();

    if(noOutstandingCalls)
    {
        CriticalSectionScoped cs(_ptrDeleteCrit);
        _safeTodelete = true;
        _ptrDeleteCond->Wake();
    }
}

void UdpSocket2Windows::WaitForOutstandingCalls()
{
    CriticalSectionScoped cs(_ptrDeleteCrit);
    while(!_safeTodelete)
    {
        _ptrDeleteCond->SleepCS(*_ptrDeleteCrit);
    }
}

void UdpSocket2Windows::RemoveSocketFromManager()
{
    // New outstanding calls should be disabled at this point.
    assert(_outstandingCallsDisabled);

    if(_addedToMgr)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                     "calling UdpSocketManager::RemoveSocket()");
        if(_mgr->RemoveSocket(this))
        {
            _addedToMgr=false;
        }
    }
}

bool UdpSocket2Windows::AquireSocket()
{
    _ptrSocketRWLock->AcquireLockShared();
    const bool returnValue = _socket != INVALID_SOCKET;
    if(!returnValue)
    {
        _ptrSocketRWLock->ReleaseLockShared();
    }
    return returnValue;
}

void UdpSocket2Windows::ReleaseSocket()
{
    _ptrSocketRWLock->ReleaseLockShared();
}

bool UdpSocket2Windows::InvalidateSocket()
{
    _ptrSocketRWLock->AcquireLockExclusive();
    if(_socket == INVALID_SOCKET)
    {
        _ptrSocketRWLock->ReleaseLockExclusive();
        return true;
    }
    // Give the socket back to the system. All socket calls will fail from now
    // on.
    if(closesocket(_socket) == SOCKET_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::InvalidateSocket() WSAerror: %d",
                     (int32_t)this, WSAGetLastError());
    }
    _socket = INVALID_SOCKET;
    _ptrSocketRWLock->ReleaseLockExclusive();
    return true;
}

}  // namespace test
}  // namespace webrtc
