1999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org/* 2999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * 4999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * Use of this source code is governed by a BSD-style license 5999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * that can be found in the LICENSE file in the root of the source 6999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * tree. An additional intellectual property rights grant can be found 7999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * in the file PATENTS. All contributing project authors may 8999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org */ 10999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 11999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include "webrtc/test/channel_transport/udp_socket2_win.h" 12999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 13999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include <assert.h> 14999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include <stdlib.h> 15999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include <winsock2.h> 16999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 174591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include "webrtc/base/format_macros.h" 1898f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/sleep.h" 19999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include "webrtc/test/channel_transport/traffic_control_win.h" 20999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#include "webrtc/test/channel_transport/udp_socket2_manager_win.h" 21999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 22999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#pragma warning(disable : 4311) 23999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 24999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgnamespace webrtc { 25999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgnamespace test { 26999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 27999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgtypedef struct _QOS_DESTADDR 28999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 29999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_OBJECT_HDR ObjectHdr; 30999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const struct sockaddr* SocketAddress; 31999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ULONG SocketAddressLength; 32999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} QOS_DESTADDR, *LPQOS_DESTADDR; 33999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 34999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgtypedef const QOS_DESTADDR* LPCQOS_DESTADDR; 35999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 36999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// TODO (patrikw): seems to be defined in ws2ipdef.h as 3. How come it's 37999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// redefined here (as a different value)? 38999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#define IP_TOS 8 39999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 40999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#define QOS_GENERAL_ID_BASE 2000 41999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org#define QOS_OBJECT_DESTADDR (0x00000004 + QOS_GENERAL_ID_BASE) 42999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 43a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgUdpSocket2Windows::UdpSocket2Windows(const int32_t id, 44999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org UdpSocketManager* mgr, bool ipV6Enable, 45999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool disableGQOS) 46999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org : _id(id), 47999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _qos(true), 48999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _iProtocol(0), 49999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _outstandingCalls(0), 50999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _outstandingCallComplete(0), 51999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _terminate(false), 52999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _addedToMgr(false), 53999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _safeTodelete(false), 54999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _outstandingCallsDisabled(false), 55999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _clientHandle(NULL), 56999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flowHandle(NULL), 57999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _filterHandle(NULL), 58999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow(NULL), 59999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc(NULL), 60999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _pcp(-2), 61999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _receiveBuffers(0) 62999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 63999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id, 64999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::UdpSocket2Windows()"); 65999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 66999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _wantsIncoming = false; 67999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr = static_cast<UdpSocket2ManagerWindows *>(mgr); 68999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 69999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _obj = NULL; 70999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _incomingCb = NULL; 71999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket = INVALID_SOCKET; 72999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _pCrit = CriticalSectionWrapper::CreateCriticalSection(); 73999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrCbRWLock = RWLockWrapper::CreateRWLock(); 74999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock = RWLockWrapper::CreateRWLock(); 75999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock = RWLockWrapper::CreateRWLock(); 76999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDeleteCrit = CriticalSectionWrapper::CreateCriticalSection(); 77999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDeleteCond = ConditionVariableWrapper::CreateConditionVariable(); 78999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 79999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Check if QoS is supported. 80999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org BOOL bProtocolFound = FALSE; 81999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAPROTOCOL_INFO *lpProtocolBuf = NULL; 82999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAPROTOCOL_INFO pProtocolInfo; 83999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 84999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!disableGQOS) 85999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 86999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DWORD dwBufLen = 0; 87999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Set dwBufLen to the size needed to retreive all the requested 88999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // information from WSAEnumProtocols. 89a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); 90999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org lpProtocolBuf = (WSAPROTOCOL_INFO*)malloc(dwBufLen); 91999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); 92999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 93999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (ipV6Enable) 94999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 95999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _iProtocol=AF_INET6; 96999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 97999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _iProtocol=AF_INET; 98999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 99999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 100a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org for (int32_t i=0; i<nRet; i++) 101999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 102999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_iProtocol == lpProtocolBuf[i].iAddressFamily && 103999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org IPPROTO_UDP == lpProtocolBuf[i].iProtocol) 104999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 105999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if ((XP1_QOS_SUPPORTED == 106999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (XP1_QOS_SUPPORTED & lpProtocolBuf[i].dwServiceFlags1))) 107999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 108999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pProtocolInfo = lpProtocolBuf[i]; 109999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bProtocolFound = TRUE; 110999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org break; 111999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 112999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 113999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 114999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 115999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 116999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!bProtocolFound) 117999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 118999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(lpProtocolBuf); 119999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _qos=false; 120999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 121999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 122999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 123999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 124999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS,\ 125999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org !bProtocolFound"); 126999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 127999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 128999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, 129999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org FROM_PROTOCOL_INFO,&pProtocolInfo, 0, 130999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSA_FLAG_OVERLAPPED); 131999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(lpProtocolBuf); 132999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 133999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_socket != INVALID_SOCKET) 134999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 135999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return; 136999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 137999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _qos = false; 138999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 139999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 140999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 141999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 142999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS"); 143999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 144999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 145999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // QoS not supported. 146999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(ipV6Enable) 147999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 148999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0 , 0, 149999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSA_FLAG_OVERLAPPED); 150999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org }else 151999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 152999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0 , 0, 153999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSA_FLAG_OVERLAPPED); 154999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 155999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_socket == INVALID_SOCKET) 156999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 157999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 158999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 159999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 160999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 161999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::UdpSocket2Windows(), INVALID_SOCKET,\ 162999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAerror: %d", 163999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAGetLastError()); 164999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 165999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 166999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Disable send buffering on the socket to improve CPU usage. 167999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // This is done by setting SO_SNDBUF to 0. 168a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t nZero = 0; 169a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t nRet = setsockopt(_socket, SOL_SOCKET, SO_SNDBUF, 170a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (char*)&nZero, sizeof(nZero)); 171999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if( nRet == SOCKET_ERROR ) 172999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 173999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 174999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 175999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 176999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 177999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR,\ 178999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAerror: %d", 179999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAGetLastError()); 180999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 181999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 182999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 183999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgUdpSocket2Windows::~UdpSocket2Windows() 184999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 185999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id, 186999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::~UdpSocket2Windows()"); 187999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 188999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WaitForOutstandingCalls(); 189999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 190999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _ptrCbRWLock; 191999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _ptrDeleteCrit; 192999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _ptrDeleteCond; 193999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _ptrDestRWLock; 194999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _ptrSocketRWLock; 195999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 196999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_pCrit) 197999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete _pCrit; 198999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 199999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_flow) 200999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 201999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(_flow); 202999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow = NULL; 203999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 204999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 205999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_gtc) 206999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 207999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_filterHandle) 208999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 209999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeleteFilter(_filterHandle); 210999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 211999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_flowHandle) 212999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 213999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeleteFlow(_flowHandle); 214999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 215999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org TrafficControlWindows::Release( _gtc); 216999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 217999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 218999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 219999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::ValidHandle() 220999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 221999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return GetFd() != INVALID_SOCKET; 222999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 223999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 224999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::SetCallback(CallbackObj obj, IncomingSocketCallback cb) 225999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 226999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrCbRWLock->AcquireLockExclusive(); 227999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _obj = obj; 228999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _incomingCb = cb; 229999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrCbRWLock->ReleaseLockExclusive(); 230999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 231999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 232a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org "UdpSocket2Windows(%d)::SetCallback ",(int32_t)this); 233999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_addedToMgr) 234999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 235999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 236999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::SetCallback alreadey added", 237a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t) this); 238999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 239999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 240999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 241999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (_mgr->AddSocket(this)) 242999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 243999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 244999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceDebug, kTraceTransport, _id, 245999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::SetCallback socket added to manager", 246a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this); 247999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _addedToMgr = true; 248999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 249999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 250999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 251999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 252999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::SetCallback error adding me to mgr", 253a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t) this); 254999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 255999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 256999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 257a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgbool UdpSocket2Windows::SetSockopt(int32_t level, int32_t optname, 258a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org const int8_t* optval, int32_t optlen) 259999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 260999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool returnValue = true; 261999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!AquireSocket()) 262999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 263999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 264999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 265999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(0 != setsockopt(_socket, level, optname, 266999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<const char*>(optval), optlen )) 267999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 268999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 269999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::SetSockopt(), WSAerror:%d", 270999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAGetLastError()); 271999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org returnValue = false; 272999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 273999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 274999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return returnValue; 275999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 276999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 277a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgbool UdpSocket2Windows::StartReceiving(uint32_t receiveBuffers) 278999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 279999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 280a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org "UdpSocket2Windows(%d)::StartReceiving(%d)", (int32_t)this, 281a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org receiveBuffers); 282999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 283999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _wantsIncoming = true; 284999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 285a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t numberOfReceiveBuffersToCreate = 286999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org receiveBuffers - _receiveBuffers.Value(); 287999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org numberOfReceiveBuffersToCreate = (numberOfReceiveBuffersToCreate < 0) ? 288999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 0 : numberOfReceiveBuffersToCreate; 289999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 290a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t error = 0; 291a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org for(int32_t i = 0; 292999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org i < numberOfReceiveBuffersToCreate; 293999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org i++) 294999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 295999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(PostRecv()) 296999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 297999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 298999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::StartReceiving() i=%d", i); 299999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org error = -1; 300999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org break; 301999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 302999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ++_receiveBuffers; 303999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 304999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(error == -1) 305999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 306999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 307999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 308999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 309999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 310999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "Socket receiving using:%d number of buffers", 311999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _receiveBuffers.Value()); 312999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 313999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 314999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 315999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::StopReceiving() 316999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 317999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 318999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::StopReceiving()"); 319999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _wantsIncoming = false; 320999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 321999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 322999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 323999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::Bind(const SocketAddress& name) 324999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 325999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const struct sockaddr* addr = 326999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<const struct sockaddr*>(&name); 327999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool returnValue = true; 328999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!AquireSocket()) 329999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 330999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 331999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 332999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (0 != bind(_socket, addr, sizeof(SocketAddress))) 333999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 334999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 335999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::Bind() WSAerror: %d", 336999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAGetLastError()); 337999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org returnValue = false; 338999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 339999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 340999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return returnValue; 341999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 342999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 3434591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t UdpSocket2Windows::SendTo(const int8_t* buf, size_t len, 344a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org const SocketAddress& to) 345999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 346a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t retVal = 0; 347a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t error = 0; 348999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PerIoContext* pIoContext = _mgr->PopIoContext(); 349999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIoContext == 0) 350999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 351999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 352999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::SendTo(), pIoContext==0", 353a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t) this); 354999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 355999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 356999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // sizeof(pIoContext->buffer) is smaller than the highest number that 3574591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org // can be represented by a size_t. 3584591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org if(len >= sizeof(pIoContext->buffer)) 359999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 360999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 361999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 362999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 363999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 3644591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "UdpSocket2Windows(%d)::SendTo(), len= %" PRIuS 3654591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org " > buffer_size = %d", 366a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t) this, 367999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org len,sizeof(pIoContext->buffer)); 368999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org len = sizeof(pIoContext->buffer); 369999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 370999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 371999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org memcpy(pIoContext->buffer,buf,len); 372999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->wsabuf.buf = pIoContext->buffer; 3734591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org pIoContext->wsabuf.len = static_cast<ULONG>(len); 374999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->fromLen=sizeof(SocketAddress); 375999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->ioOperation = OP_WRITE; 376999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->nTotalBytes = len; 377999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->nSentBytes=0; 378999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 379999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DWORD numOfbytesSent = 0; 380999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const struct sockaddr* addr = reinterpret_cast<const struct sockaddr*>(&to); 381999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 382999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!AquireSocket()) 383999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 384999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIoContext); 385999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 386999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 387999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Assume that the WSASendTo call will be successfull to make sure that 388999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // _outstandingCalls is positive. Roll back if WSASendTo failed. 389999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!NewOutstandingCall()) 390999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 391999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIoContext); 392999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 393999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 394999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 395999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org retVal = WSASendTo(_socket, &pIoContext->wsabuf, 1, &numOfbytesSent, 396999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 0, addr, sizeof(SocketAddress), 397999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &(pIoContext->overlapped), 0); 398999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 399999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 400999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if( retVal == SOCKET_ERROR ) 401999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 402999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org error = WSAGetLastError(); 403999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(error != ERROR_IO_PENDING) 404999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 405999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 406999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::SendTo() WSAerror: %d",error); 407999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 408999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 409999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(retVal == 0 || (retVal == SOCKET_ERROR && error == ERROR_IO_PENDING)) 410999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 4114591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org return static_cast<int32_t>(len); 412999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 4136ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org error = _mgr->PushIoContext(pIoContext); 4146ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org if(error) 415999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 416999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 417999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 418999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 419999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 420999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::SendTo(), error:%d pushing ioContext", 421a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this, error); 422999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 423999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 424999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Roll back. 425999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OutstandingCallCompleted(); 426999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 427999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 428999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 429999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::IOCompleted(PerIoContext* pIOContext, 430a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org uint32_t ioSize, uint32_t error) 431999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 432999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIOContext == NULL || error == ERROR_OPERATION_ABORTED) 433999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 434999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if ((pIOContext != NULL) && 43512411ef40e08c5e28ccde54ab3418c96676ffcbcpbos !pIOContext->ioInitiatedByPlatformThread && 436999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (error == ERROR_OPERATION_ABORTED) && 437999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (pIOContext->ioOperation == OP_READ) && 438999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _outstandingCallsDisabled) 439999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 44012411ef40e08c5e28ccde54ab3418c96676ffcbcpbos // !pIOContext->initiatedIOByPlatformThread indicate that the I/O 44112411ef40e08c5e28ccde54ab3418c96676ffcbcpbos // was not initiated by a PlatformThread thread. 442999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // This may happen if the thread that initiated receiving (e.g. 443999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // by calling StartListen())) is deleted before any packets have 444999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // been received. 445999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // In this case there is no packet in the PerIoContext. Re-use it 446999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // to post a new PostRecv(..). 447999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Note 1: the PerIoContext will henceforth be posted by a thread 448999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // that is controlled by the socket implementation. 449999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Note 2: This is more likely to happen to RTCP packets as 450999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // they are less frequent than RTP packets. 451999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Note 3: _outstandingCallsDisabled being false indicates 452999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // that the socket isn't being shut down. 453999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Note 4: This should only happen buffers set to receive packets 454999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // (OP_READ). 455999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 456999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIOContext == NULL) 457999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 458999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 459999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 460999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 461999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 462999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::IOCompleted(%d,%d,%d), %d", 463a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)pIOContext, 464999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ioSize, 465999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org error, 466a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org pIOContext ? (int32_t)pIOContext->ioOperation : -1); 467999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 468999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 469999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceDebug, 470999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 471999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 472999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::IOCompleted() Operation aborted"); 473999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 474999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIOContext) 475999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 476a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t remainingReceiveBuffers = --_receiveBuffers; 477999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(remainingReceiveBuffers < 0) 478999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 479999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org assert(false); 480999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 4816ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org int32_t err = _mgr->PushIoContext(pIOContext); 4826ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org if(err) 483999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 484999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 485999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 486999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 487999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 488999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::IOCompleted(), err = %d, when\ 489999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pushing ioContext after error", 490999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org err); 491999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 492999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 493999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OutstandingCallCompleted(); 494999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return; 495999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 496d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org } // if (pIOContext == NULL || error == ERROR_OPERATION_ABORTED) 497999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 498999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIOContext->ioOperation == OP_WRITE) 499999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 500999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIOContext); 501999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 502999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org else if(pIOContext->ioOperation == OP_READ) 503999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 504999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!error && ioSize != 0) 505999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 506999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrCbRWLock->AcquireLockShared(); 507999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_wantsIncoming && _incomingCb) 508999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 509999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _incomingCb(_obj, 510a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org reinterpret_cast<const int8_t*>( 511999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIOContext->wsabuf.buf), 512999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ioSize, 513999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &pIOContext->from); 514999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 515999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrCbRWLock->ReleaseLockShared(); 516999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 517a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t err = PostRecv(pIOContext); 518999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(err == 0) 519999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 520999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // The PerIoContext was posted by a thread controlled by the socket 521999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // implementation. 52212411ef40e08c5e28ccde54ab3418c96676ffcbcpbos pIOContext->ioInitiatedByPlatformThread = true; 523999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 524999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OutstandingCallCompleted(); 525999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return; 526999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 527999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Unknown operation. Should not happen. Return pIOContext to avoid 528999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // memory leak. 529999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org assert(false); 530999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIOContext); 531999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 532999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OutstandingCallCompleted(); 533999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Don't touch any members after OutstandingCallCompleted() since the socket 534999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // may be deleted at this point. 535999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 536999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 537a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::PostRecv() 538999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 539999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PerIoContext* pIoContext=_mgr->PopIoContext(); 540999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIoContext == 0) 541999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 542999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 543999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::PostRecv(), pIoContext == 0", 544a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this); 545999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 546999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 547999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // This function may have been called by thread not controlled by the socket 548999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // implementation. 54912411ef40e08c5e28ccde54ab3418c96676ffcbcpbos pIoContext->ioInitiatedByPlatformThread = false; 550999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return PostRecv(pIoContext); 551999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 552999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 553a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::PostRecv(PerIoContext* pIoContext) 554999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 555999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIoContext==0) 556999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 557999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 558999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::PostRecv(?), pIoContext==0", 559a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this); 560999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 561999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 562999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 563999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DWORD numOfRecivedBytes = 0; 564999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DWORD flags = 0; 565999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->wsabuf.buf = pIoContext->buffer; 566999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->wsabuf.len = sizeof(pIoContext->buffer); 567999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->fromLen = sizeof(SocketAddress); 568999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pIoContext->ioOperation = OP_READ; 569a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t rxError = 0; 570a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t nRet = 0; 571a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t postingSucessfull = false; 572999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 573999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!AquireSocket()) 574999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 575999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIoContext); 576999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 577999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 578999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 579999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Assume that the WSARecvFrom() call will be successfull to make sure that 580999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // _outstandingCalls is positive. Roll back if WSARecvFrom() failed. 581999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!NewOutstandingCall()) 582999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 583999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _mgr->PushIoContext(pIoContext); 584999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 585999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 586999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 587a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org for(int32_t tries = 0; tries < 10; tries++) 588999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 589999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org nRet = WSARecvFrom( 590999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket, 591999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &(pIoContext->wsabuf), 592999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1, 593999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &numOfRecivedBytes, 594999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &flags, 595999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<struct sockaddr*>(&(pIoContext->from)), 596999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &(pIoContext->fromLen), 597999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &(pIoContext->overlapped), 598999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 0); 599999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 600999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if( nRet == SOCKET_ERROR) 601999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 602999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org rxError = WSAGetLastError(); 603999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(rxError != ERROR_IO_PENDING) 604999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 605999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 606999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 607999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 608999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 609999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::PostRecv(?), WSAerror:%d when\ 610999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org posting new recieve,trie:%d", 611a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this, 612999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org rxError, 613999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org tries); 614999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Tell the OS that this is a good place to context switch if 615999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // it wants to. 616fcb7c38b15319aa021ba55bc3a06a3269ac3ea6fhta@webrtc.org SleepMs(0); 617999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 618999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 619999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if((rxError == ERROR_IO_PENDING) || (nRet == 0)) 620999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 621999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org postingSucessfull = true; 622999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org break; 623999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 624999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 625999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 626999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 627999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(postingSucessfull) 628999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 629999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return 0; 630999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 631a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t remainingReceiveBuffers = --_receiveBuffers; 632999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(remainingReceiveBuffers < 0) 633999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 634999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org assert(false); 635999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 6366ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org int32_t error = _mgr->PushIoContext(pIoContext); 6376ac22e6b47f9a6ed70b0a376984b39b9a745dd94henrike@webrtc.org if(error) 638999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 639999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 640999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 641999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 642999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 643999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::PostRecv(?), error:%d when PushIoContext", 644a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this, 645999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org error); 646999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 647999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Roll back. 648999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OutstandingCallCompleted(); 649999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 650999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 651999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 652999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::CloseBlocking() 653999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 654999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org LINGER lingerStruct; 655999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 656999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org lingerStruct.l_onoff = 1; 657999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org lingerStruct.l_linger = 0; 658999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(AquireSocket()) 659999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 660999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org setsockopt(_socket, SOL_SOCKET, SO_LINGER, 661999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<const char*>(&lingerStruct), 662999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org sizeof(lingerStruct)); 663999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 664999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 665999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 666999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _wantsIncoming = false; 667999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Reclaims the socket and prevents it from being used again. 668999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org InvalidateSocket(); 669999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DisableNewOutstandingCalls(); 670999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WaitForOutstandingCalls(); 671999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org delete this; 672999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 673999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 674a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgbool UdpSocket2Windows::SetQos(int32_t serviceType, 675a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t tokenRate, 676a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t bucketSize, 677a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t peekBandwith, 678a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t minPolicedSize, 679a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t maxSduSize, 680999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const SocketAddress &stRemName, 681a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t overrideDSCP) 682999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 683999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_qos == false) 684999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 685999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 686999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::SetQos(), socket not capable of QOS"); 687999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 688999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 689999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(overrideDSCP != 0) 690999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 691999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org FLOWSPEC f; 692a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t err = CreateFlowSpec(serviceType, tokenRate, bucketSize, 693a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org peekBandwith, minPolicedSize, 694a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org maxSduSize, &f); 695999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(err == -1) 696999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 697999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 698999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 699999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 700999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org SocketAddress socketName; 701999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org struct sockaddr_in* name = 702999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<struct sockaddr_in*>(&socketName); 703999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org int nameLength = sizeof(SocketAddress); 704999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(AquireSocket()) 705999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 706999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org getsockname(_socket, (struct sockaddr*)name, &nameLength); 707999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 708999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 709999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 710999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(serviceType == 0) 711999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 712999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Disable TOS byte setting. 713999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return SetTrafficControl(0, -1, name, &f, &f) == 0; 714999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 715999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return SetTrafficControl(overrideDSCP, -1, name, &f, &f) == 0; 716999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 717999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 718999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS Qos; 719999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org DWORD BytesRet; 720999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DESTADDR QosDestaddr; 721999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 722999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org memset (&Qos, QOS_NOT_SPECIFIED, sizeof(QOS)); 723999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 724999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.ServiceType = serviceType; 725999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.TokenRate = tokenRate; 726999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; 727999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; 728999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; 729999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.Latency = QOS_NOT_SPECIFIED; 730999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 731999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; 732999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 733999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Only ServiceType is needed for receiving. 734999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.ServiceType = serviceType; 735999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; 736999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; 737999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; 738999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED; 739999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; 740999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 741999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; 742999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 743999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ProviderSpecific.len = 0; 744999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 745999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ProviderSpecific.buf = NULL; 746999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 747a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org ZeroMemory((int8_t *)&QosDestaddr, sizeof(QosDestaddr)); 748999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 749999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OSVERSIONINFOEX osvie; 750999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org osvie.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 751999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org GetVersionEx((LPOSVERSIONINFO)&osvie); 752999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 753999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Operating system Version number dwMajorVersion dwMinorVersion 754999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows 7 6.1 6 1 755999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows Server 2008 R2 6.1 6 1 756999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows Server 2008 6.0 6 0 757999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows Vista 6.0 6 0 758999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows Server 2003 R2 5.2 5 2 759999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows Server 2003 5.2 5 2 760999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows XP 5.1 5 1 761999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org// Windows 2000 5.0 5 0 762999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 763999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // SERVICE_NO_QOS_SIGNALING and QOS_DESTADDR should not be used if version 764999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // is 6.0 or greater. 765999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(osvie.dwMajorVersion >= 6) 766999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 767999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 768999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.ServiceType = serviceType; 769999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 770999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 771999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.SendingFlowspec.MinimumPolicedSize = 772999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_NOT_SPECIFIED | SERVICE_NO_QOS_SIGNALING; 773999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ReceivingFlowspec.ServiceType = 774999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org serviceType | SERVICE_NO_QOS_SIGNALING; 775999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 776999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QosDestaddr.ObjectHdr.ObjectType = QOS_OBJECT_DESTADDR; 777999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QosDestaddr.ObjectHdr.ObjectLength = sizeof(QosDestaddr); 778999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QosDestaddr.SocketAddress = (SOCKADDR *)&stRemName; 779999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (AF_INET6 == _iProtocol) 780999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 781999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QosDestaddr.SocketAddressLength = sizeof(SocketAddressInVersion6); 782999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 783999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QosDestaddr.SocketAddressLength = sizeof(SocketAddressIn); 784999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 785999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 786999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ProviderSpecific.len = QosDestaddr.ObjectHdr.ObjectLength; 787999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org Qos.ProviderSpecific.buf = (char*)&QosDestaddr; 788999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 789999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 790999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!AquireSocket()) { 791999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 792999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 793999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // To set QoS with SIO_SET_QOS the socket must be locally bound first 794999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // or the call will fail with error code 10022. 795a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t result = WSAIoctl(GetFd(), SIO_SET_QOS, &Qos, sizeof(QOS), 796999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org NULL, 0, &BytesRet, NULL,NULL); 797999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 798999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (result == SOCKET_ERROR) 799999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 800999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 801999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows::SetQos() WSAerror : %d", 802999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WSAGetLastError()); 803999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return false; 804999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 805999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 806999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 807999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 808a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::SetTOS(int32_t serviceType) 809999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 810999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org SocketAddress socketName; 811999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 812999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org struct sockaddr_in* name = 813999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<struct sockaddr_in*>(&socketName); 814999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org int nameLength = sizeof(SocketAddress); 815999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(AquireSocket()) 816999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 817999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org getsockname(_socket, (struct sockaddr*)name, &nameLength); 818999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 819999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 820999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 821a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t res = SetTrafficControl(serviceType, -1, name); 822999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (res == -1) 823999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 824999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OSVERSIONINFO OsVersion; 825999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 826999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org GetVersionEx (&OsVersion); 827999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 828999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if ((OsVersion.dwMajorVersion == 4)) // NT 4.0 829999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 830999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(SetSockopt(IPPROTO_IP,IP_TOS , 831a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int8_t*)&serviceType, 4) != 0) 832999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 833999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 834999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 835999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 836999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 837999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return res; 838999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 839999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 840a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::SetPCP(int32_t pcp) 841999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 842999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org SocketAddress socketName; 843999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org struct sockaddr_in* name = 844999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org reinterpret_cast<struct sockaddr_in*>(&socketName); 845999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org int nameLength = sizeof(SocketAddress); 846999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(AquireSocket()) 847999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 848999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org getsockname(_socket, (struct sockaddr*)name, &nameLength); 849999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ReleaseSocket(); 850999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 851999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return SetTrafficControl(-1, pcp, name); 852999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 853999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 854a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::SetTrafficControl( 855a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t dscp, 856a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t pcp, 857999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const struct sockaddr_in* name, 858999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org FLOWSPEC* send, FLOWSPEC* recv) 859999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 860999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (pcp == _pcp) 861999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 862999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // No change. 863999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pcp = -1; 864999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 865999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if ((-1 == pcp) && (-1 == dscp)) 866999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 867999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return 0; 868999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 869999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!_gtc) 870999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 871999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc = TrafficControlWindows::GetInstance(_id); 872999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 873999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!_gtc) 874999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 875999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 876999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 877999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_filterHandle) 878999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 879999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeleteFilter(_filterHandle); 880999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _filterHandle = NULL; 881999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 882999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_flowHandle) 883999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 884999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeleteFlow(_flowHandle); 885999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flowHandle = NULL; 886999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 887999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_clientHandle) 888999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 889999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(_clientHandle); 890999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _clientHandle = NULL; 891999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 892999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if ((0 == dscp) && (-2 == _pcp) && (-1 == pcp)) 893999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 894999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // TODO (pwestin): why is this not done before deleting old filter and 895999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // flow? This scenario should probably be documented in 896999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // the function declaration. 897999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return 0; 898999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 899999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 900999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org TCI_CLIENT_FUNC_LIST QoSFunctions; 901999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QoSFunctions.ClAddFlowCompleteHandler = NULL; 902999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QoSFunctions.ClDeleteFlowCompleteHandler = NULL; 903999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QoSFunctions.ClModifyFlowCompleteHandler = NULL; 904999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler; 905999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Register the client with Traffic control interface. 906999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org HANDLE ClientHandle; 907999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ULONG result = _gtc->TcRegisterClient(CURRENT_TCI_VERSION, NULL, 908999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &QoSFunctions,&ClientHandle); 909999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR) 910999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 911999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // This is likely caused by the application not being run as 912999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // administrator. 913999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 914999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "TcRegisterClient returned %d", result); 915999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return result; 916999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 917999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 918999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Find traffic control-enabled network interfaces that matches this 919999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // socket's IP address. 920999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ULONG BufferSize = 0; 921999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, NULL); 922999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 923999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR && result != ERROR_INSUFFICIENT_BUFFER) 924999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 925999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 926999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return result; 927999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 928999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 929999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != ERROR_INSUFFICIENT_BUFFER) 930999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 931999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Empty buffer contains all control-enabled network interfaces. I.e. 932999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // QoS is not enabled. 933999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 934999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "QOS faild since QOS is not installed on the interface"); 935999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 936999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 937999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 938999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 939999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 940999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PTC_IFC_DESCRIPTOR pInterfaceBuffer = 941999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (PTC_IFC_DESCRIPTOR)malloc(BufferSize); 942999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pInterfaceBuffer == NULL) 943999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 944999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 945999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "Out ot memory failure"); 946999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 947999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return ERROR_NOT_ENOUGH_MEMORY; 948999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 949999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 950999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, 951999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org pInterfaceBuffer); 952999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 953999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR) 954999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 955999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE( 956999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceError, 957999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org kTraceTransport, 958999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _id, 959999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "Critical: error enumerating interfaces when passing in correct\ 960999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org buffer size: %d", result); 961999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 962999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 963999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return result; 964999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 965999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 966999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PTC_IFC_DESCRIPTOR oneinterface; 967999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org HANDLE ifcHandle, iFilterHandle, iflowHandle; 968999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool addrFound = false; 969999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ULONG filterSourceAddress = ULONG_MAX; 970999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 971999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Find the interface corresponding to the local address. 972999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org for(oneinterface = pInterfaceBuffer; 973999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org oneinterface != (PTC_IFC_DESCRIPTOR) 974a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (((int8_t*)pInterfaceBuffer) + BufferSize); 975999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org oneinterface = (PTC_IFC_DESCRIPTOR) 976a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org ((int8_t *)oneinterface + oneinterface->Length)) 977999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 978999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 979999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org char interfaceName[500]; 980999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WideCharToMultiByte(CP_ACP, 0, oneinterface->pInterfaceName, -1, 981999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org interfaceName, sizeof(interfaceName), 0, 0 ); 982999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 983999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PNETWORK_ADDRESS_LIST addresses = 984999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org &(oneinterface->AddressListDesc.AddressList); 985999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org for(LONG i = 0; i < addresses->AddressCount ; i++) 986999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 987999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Only look at TCP/IP addresses. 988999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(addresses->Address[i].AddressType != NDIS_PROTOCOL_ID_TCP_IP) 989999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 990999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org continue; 991999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 992999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 993999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org NETWORK_ADDRESS_IP* pIpAddr = 994999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (NETWORK_ADDRESS_IP*)&(addresses->Address[i].Address); 995999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org struct in_addr in; 996999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org in.S_un.S_addr = pIpAddr->in_addr; 997999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(pIpAddr->in_addr == name->sin_addr.S_un.S_addr) 998999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 999999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filterSourceAddress = pIpAddr->in_addr; 1000999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org addrFound = true; 1001999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1002999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1003999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!addrFound) 1004999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1005999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org continue; 1006999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else 1007999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1008999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org break; 1009999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1010999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1011999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!addrFound) 1012999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1013999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 1014999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "QOS faild since address is not found"); 1015999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 1016999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 1017999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 1018999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1019999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org result = _gtc->TcOpenInterfaceW(oneinterface->pInterfaceName, ClientHandle, 1020999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org NULL, &ifcHandle); 1021999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR) 1022999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1023999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 1024999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "Error opening interface: %d", result); 1025999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 1026999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 1027999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return result; 1028999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1029999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1030999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Create flow if one doesn't exist. 1031999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!_flow) 1032999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1033999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool addPCP = ((pcp >= 0) || ((-1 == pcp) && (_pcp >= 0))); 1034999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) + 1035999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); 1036999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow = (PTC_GEN_FLOW)malloc(allocSize); 1037999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1038999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; 1039999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED; 1040999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; 1041999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 1042999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; 1043999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; 1044999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; 1045999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED; 1046999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1047999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; 1048999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED; 1049999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; 1050999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 1051999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; 1052999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; 1053999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; 1054999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; 1055999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1056999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; 1057999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->DSField = 0; 1058999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS; 1059999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->ObjectHdr.ObjectLength = sizeof(QOS_DS_CLASS); 1060999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1061999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (addPCP) 1062999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1063999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); 1064999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->TrafficClass = 0; 1065999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS; 1066999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS); 1067999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1068999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1069999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) + 1070999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); 1071999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else if (-1 != pcp) { 1072999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Reallocate memory since pcp has changed. 1073999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org PTC_GEN_FLOW oldFlow = _flow; 1074999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org bool addPCP = (pcp >= 0); 1075999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) + 1076999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); 1077999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow = (PTC_GEN_FLOW)malloc(allocSize); 1078999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1079999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Copy old flow. 1080999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec = oldFlow->ReceivingFlowspec; 1081999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec = oldFlow->SendingFlowspec; 1082999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // The DS info is always the first object. 1083999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; 1084999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DS_CLASS* oldDsClass = (QOS_DS_CLASS*)oldFlow->TcObjects; 1085999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->DSField = oldDsClass->DSField; 1086999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->ObjectHdr.ObjectType = oldDsClass->ObjectHdr.ObjectType; 1087999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->ObjectHdr.ObjectLength = oldDsClass->ObjectHdr.ObjectLength; 1088999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1089999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (addPCP) 1090999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1091999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); 1092999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->TrafficClass = 0; 1093999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS; 1094999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS); 1095999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1096999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1097999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) + 1098999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); 1099999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(oldFlow); 1100999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1101999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1102999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Setup send and receive flow and DS object. 1103999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (dscp >= 0) 1104999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1105999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!send || (0 == dscp)) 1106999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1107999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; 1108999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED; 1109999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; 1110999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; 1111999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.PeakBandwidth = 1112999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (0 == dscp ? QOS_NOT_SPECIFIED : POSITIVE_INFINITY_RATE); 1113999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; 1114999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; 1115999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // 128000 * 10 is 10mbit/s. 1116999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenRate = 1117999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (0 == dscp ? QOS_NOT_SPECIFIED : 128000 * 10); 1118999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1119999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org else 1120999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1121999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.DelayVariation = send->DelayVariation; 1122999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.Latency = send->Latency; 1123999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MaxSduSize = send->MaxSduSize; 1124999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MinimumPolicedSize = 1125999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org send->MinimumPolicedSize; 1126999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.PeakBandwidth = send->PeakBandwidth; 1127999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.PeakBandwidth = POSITIVE_INFINITY_RATE; 1128999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.ServiceType = send->ServiceType; 1129999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenBucketSize = send->TokenBucketSize; 1130999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenRate = send->TokenRate; 1131999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1132999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1133999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!recv || (0 == dscp)) 1134999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1135999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.DelayVariation = 1136999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.DelayVariation; 1137999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.Latency = _flow->SendingFlowspec.Latency; 1138999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MaxSduSize = 1139999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MaxSduSize; 1140999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MinimumPolicedSize = 1141999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.MinimumPolicedSize; 1142999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; 1143999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.ServiceType = 1144999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 0 == dscp ? SERVICETYPE_BESTEFFORT : SERVICETYPE_CONTROLLEDLOAD; 1145999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenBucketSize = 1146999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenBucketSize; 1147999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenRate = 1148999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->SendingFlowspec.TokenRate; 1149999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } else { 1150999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.DelayVariation = recv->DelayVariation; 1151999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.Latency = recv->Latency; 1152999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MaxSduSize = recv->MaxSduSize; 1153999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.MinimumPolicedSize = 1154999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org recv->MinimumPolicedSize; 1155999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.PeakBandwidth = recv->PeakBandwidth; 1156999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.ServiceType = recv->ServiceType; 1157999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenBucketSize = recv->TokenBucketSize; 1158999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; 1159999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1160999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1161999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Setup DS (for DSCP value). 1162999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // DS is always the first object. 1163999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; 1164999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org dsClass->DSField = dscp; 1165999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1166999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1167999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Setup PCP (802.1p priority in 802.1Q/VLAN tagging) 1168999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (pcp >= 0) 1169999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1170999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // DS is always first object. 1171999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; 1172999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); 1173999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org trafficClass->TrafficClass = pcp; 1174999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1175999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1176999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org result = _gtc->TcAddFlow(ifcHandle, NULL, 0, _flow, &iflowHandle); 1177999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR) 1178999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1179999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcCloseInterface(ifcHandle); 1180999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 1181999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 1182999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 1183999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1184999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1185999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org IP_PATTERN filterPattern, mask; 1186999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1187a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org ZeroMemory((int8_t*)&filterPattern, sizeof(IP_PATTERN)); 1188a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org ZeroMemory((int8_t*)&mask, sizeof(IP_PATTERN)); 1189999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1190999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filterPattern.ProtocolId = IPPROTO_UDP; 1191999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // "name" fields already in network order. 1192999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filterPattern.S_un.S_un_ports.s_srcport = name->sin_port; 1193999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filterPattern.SrcAddr = filterSourceAddress; 1194999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1195999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Unsigned max of a type corresponds to a bitmask with all bits set to 1. 1196999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // I.e. the filter should allow all ProtocolIds, any source port and any 1197999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // IP address 1198999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org mask.ProtocolId = UCHAR_MAX; 1199999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org mask.S_un.S_un_ports.s_srcport = USHRT_MAX; 1200999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org mask.SrcAddr = ULONG_MAX; 1201999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1202999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org TC_GEN_FILTER filter; 1203999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1204999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filter.AddressType = NDIS_PROTOCOL_ID_TCP_IP; 1205999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filter.Mask = (LPVOID)&mask; 1206999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filter.Pattern = (LPVOID)&filterPattern; 1207999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org filter.PatternSize = sizeof(IP_PATTERN); 1208999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1209999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org result = _gtc->TcAddFilter(iflowHandle, &filter, &iFilterHandle); 1210999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(result != NO_ERROR) 1211999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1212999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeleteFlow(iflowHandle); 1213999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcCloseInterface(ifcHandle); 1214999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcDeregisterClient(ClientHandle); 1215999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 1216999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return result; 1217999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1218999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1219999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _flowHandle = iflowHandle; 1220999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _filterHandle = iFilterHandle; 1221999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _clientHandle = ClientHandle; 1222999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (-1 != pcp) 1223999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1224999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _pcp = pcp; 1225999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1226999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1227999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _gtc->TcCloseInterface(ifcHandle); 1228999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org free(pInterfaceBuffer); 1229999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1230999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return 0; 1231999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1232999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1233a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.orgint32_t UdpSocket2Windows::CreateFlowSpec(int32_t serviceType, 1234a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t tokenRate, 1235a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t bucketSize, 1236a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t peekBandwith, 1237a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t minPolicedSize, 1238a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org int32_t maxSduSize, 1239a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org FLOWSPEC* f) 1240999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1241999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if (!f) 1242999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1243999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return -1; 1244999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1245999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1246999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->ServiceType = serviceType; 1247999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->TokenRate = tokenRate; 1248999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->TokenBucketSize = QOS_NOT_SPECIFIED; 1249999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->PeakBandwidth = QOS_NOT_SPECIFIED; 1250999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->DelayVariation = QOS_NOT_SPECIFIED; 1251999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->Latency = QOS_NOT_SPECIFIED; 1252999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->MaxSduSize = QOS_NOT_SPECIFIED; 1253999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org f->MinimumPolicedSize = QOS_NOT_SPECIFIED; 1254999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return 0; 1255999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1256999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1257999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::NewOutstandingCall() 1258999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1259999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org assert(!_outstandingCallsDisabled); 1260999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1261999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ++_outstandingCalls; 1262999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 1263999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1264999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1265999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::OutstandingCallCompleted() 1266999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1267999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock->AcquireLockShared(); 1268999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org ++_outstandingCallComplete; 1269999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if((--_outstandingCalls == 0) && _outstandingCallsDisabled) 1270999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1271999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // When there are no outstanding calls and new outstanding calls are 1272999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // disabled it is time to terminate. 1273999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _terminate = true; 1274999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1275999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock->ReleaseLockShared(); 1276999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1277999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if((--_outstandingCallComplete == 0) && 1278999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org (_terminate)) 1279999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1280999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Only one thread will enter here. The thread with the last outstanding 1281999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // call. 1282999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org CriticalSectionScoped cs(_ptrDeleteCrit); 1283999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _safeTodelete = true; 1284999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDeleteCond->Wake(); 1285999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1286999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1287999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1288999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::DisableNewOutstandingCalls() 1289999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1290999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock->AcquireLockExclusive(); 1291999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_outstandingCallsDisabled) 1292999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1293999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Outstandning calls are already disabled. 1294999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock->ReleaseLockExclusive(); 1295999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return; 1296999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1297999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _outstandingCallsDisabled = true; 1298999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const bool noOutstandingCalls = (_outstandingCalls.Value() == 0); 1299999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDestRWLock->ReleaseLockExclusive(); 1300999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1301999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org RemoveSocketFromManager(); 1302999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1303999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(noOutstandingCalls) 1304999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1305999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org CriticalSectionScoped cs(_ptrDeleteCrit); 1306999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _safeTodelete = true; 1307999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDeleteCond->Wake(); 1308999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1309999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1310999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1311999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::WaitForOutstandingCalls() 1312999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1313999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org CriticalSectionScoped cs(_ptrDeleteCrit); 1314999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org while(!_safeTodelete) 1315999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1316999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrDeleteCond->SleepCS(*_ptrDeleteCrit); 1317999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1318999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1319999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1320999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::RemoveSocketFromManager() 1321999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1322999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // New outstanding calls should be disabled at this point. 1323999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org assert(_outstandingCallsDisabled); 1324999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1325999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_addedToMgr) 1326999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1327999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, 1328999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "calling UdpSocketManager::RemoveSocket()"); 1329999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_mgr->RemoveSocket(this)) 1330999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1331999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _addedToMgr=false; 1332999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1333999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1334999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1335999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1336999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::AquireSocket() 1337999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1338999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->AcquireLockShared(); 1339999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org const bool returnValue = _socket != INVALID_SOCKET; 1340999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(!returnValue) 1341999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1342999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->ReleaseLockShared(); 1343999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1344999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return returnValue; 1345999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1346999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1347999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgvoid UdpSocket2Windows::ReleaseSocket() 1348999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1349999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->ReleaseLockShared(); 1350999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1351999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1352999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.orgbool UdpSocket2Windows::InvalidateSocket() 1353999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org{ 1354999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->AcquireLockExclusive(); 1355999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(_socket == INVALID_SOCKET) 1356999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1357999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->ReleaseLockExclusive(); 1358999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 1359999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1360999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // Give the socket back to the system. All socket calls will fail from now 1361999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org // on. 1362999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org if(closesocket(_socket) == SOCKET_ERROR) 1363999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org { 1364999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org WEBRTC_TRACE(kTraceError, kTraceTransport, _id, 1365999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org "UdpSocket2Windows(%d)::InvalidateSocket() WSAerror: %d", 1366a5f1787f63cb580a50f5a7be98600102454594e2pbos@webrtc.org (int32_t)this, WSAGetLastError()); 1367999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org } 1368999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _socket = INVALID_SOCKET; 1369999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org _ptrSocketRWLock->ReleaseLockExclusive(); 1370999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org return true; 1371999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} 1372999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org 1373999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} // namespace test 1374999e900fb6ed324bad5cb59b856936257824f43fpwestin@webrtc.org} // namespace webrtc 1375