/*
 *  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->ioInitiatedByPlatformThread &&
            (error == ERROR_OPERATION_ABORTED) &&
            (pIOContext->ioOperation == OP_READ) &&
            _outstandingCallsDisabled)
        {
            // !pIOContext->initiatedIOByPlatformThread indicate that the I/O
            // was not initiated by a PlatformThread 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->ioInitiatedByPlatformThread = 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->ioInitiatedByPlatformThread = 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
