Deleted udp_socket_windows and all references to it.
This fixes a couple of Coverity issues, and doesn't impact any tested platforms. BUG=Coverity:14423 TEST=trybots Review URL: https://webrtc-codereview.appspot.com/564012 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2247 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -1,283 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "udp_socket_manager_windows.h"
|
|
||||||
#include "udp_socket_windows.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
WebRtc_UWord32 UdpSocketManagerWindows::_numOfActiveManagers = 0;
|
|
||||||
|
|
||||||
UdpSocketManagerWindows::UdpSocketManagerWindows()
|
|
||||||
: UdpSocketManager(),
|
|
||||||
_id(-1)
|
|
||||||
{
|
|
||||||
const char* threadName = "UdpSocketManagerWindows_Thread";
|
|
||||||
_critSectList = CriticalSectionWrapper::CreateCriticalSection();
|
|
||||||
_thread = ThreadWrapper::CreateThread(UdpSocketManagerWindows::Run,
|
|
||||||
this, kRealtimePriority, threadName);
|
|
||||||
FD_ZERO(&_readFds);
|
|
||||||
FD_ZERO(&_writeFds);
|
|
||||||
FD_ZERO(&_exceptFds);
|
|
||||||
_numOfActiveManagers++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::Init(WebRtc_Word32 id,
|
|
||||||
WebRtc_UWord8& numOfWorkThreads) {
|
|
||||||
CriticalSectionScoped cs(_critSectList);
|
|
||||||
if ((_id != -1) || (_numOfWorkThreads != 0)) {
|
|
||||||
assert(_id == -1);
|
|
||||||
assert(_numOfWorkThreads == 0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_id = id;
|
|
||||||
_numOfWorkThreads = numOfWorkThreads;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UdpSocketManagerWindows::~UdpSocketManagerWindows()
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
if(_thread != NULL)
|
|
||||||
{
|
|
||||||
delete _thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_critSectList != NULL)
|
|
||||||
{
|
|
||||||
_critSectList->Enter();
|
|
||||||
|
|
||||||
while(!_socketMap.empty())
|
|
||||||
{
|
|
||||||
std::map<SOCKET, UdpSocketWindows*>::iterator it =
|
|
||||||
_socketMap.begin();
|
|
||||||
UdpSocketWindows* s = static_cast<UdpSocketWindows*>(it->second);
|
|
||||||
_socketMap.erase(it);
|
|
||||||
delete s;
|
|
||||||
}
|
|
||||||
_removeList.erase(_removeList.begin(), _removeList.end());
|
|
||||||
|
|
||||||
while(!_addList.empty())
|
|
||||||
{
|
|
||||||
std::list<UdpSocketWindows*>::iterator it = _addList.begin();
|
|
||||||
UdpSocketWindows* s = static_cast<UdpSocketWindows*>(*it);
|
|
||||||
_addList.erase(it);
|
|
||||||
delete s;
|
|
||||||
}
|
|
||||||
_critSectList->Leave();
|
|
||||||
|
|
||||||
delete _critSectList;
|
|
||||||
}
|
|
||||||
|
|
||||||
_numOfActiveManagers--;
|
|
||||||
|
|
||||||
if (_numOfActiveManagers == 0)
|
|
||||||
WSACleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketManagerWindows::ChangeUniqueId(const WebRtc_Word32 id)
|
|
||||||
{
|
|
||||||
_id = id;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::Start()
|
|
||||||
{
|
|
||||||
unsigned int id;
|
|
||||||
if (_thread == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return _thread->Start(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::Stop()
|
|
||||||
{
|
|
||||||
if (_thread == NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return _thread->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::Process()
|
|
||||||
{
|
|
||||||
bool doSelect = false;
|
|
||||||
// Timeout = 1 second.
|
|
||||||
timeval timeout;
|
|
||||||
timeout.tv_sec = 0;
|
|
||||||
timeout.tv_usec = 10000;
|
|
||||||
|
|
||||||
FD_ZERO(&_readFds);
|
|
||||||
FD_ZERO(&_writeFds);
|
|
||||||
FD_ZERO(&_exceptFds);
|
|
||||||
|
|
||||||
_critSectList->Enter();
|
|
||||||
// Remove sockets that have been registered for removal.
|
|
||||||
while(!_removeList.empty())
|
|
||||||
{
|
|
||||||
SOCKET id = *_removeList.begin();
|
|
||||||
std::map<SOCKET, UdpSocketWindows*>::iterator it = _socketMap.find(id);
|
|
||||||
if(it != _socketMap.end())
|
|
||||||
{
|
|
||||||
UdpSocketWindows* s = static_cast<UdpSocketWindows*>(it->second);
|
|
||||||
_socketMap.erase(it);
|
|
||||||
_removeList.pop_front();
|
|
||||||
delete s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add sockets that have been registered for being added.
|
|
||||||
while (!_addList.empty())
|
|
||||||
{
|
|
||||||
UdpSocketWindows* s = *_addList.begin();
|
|
||||||
if(s)
|
|
||||||
{
|
|
||||||
_socketMap[s->GetFd()] = s;
|
|
||||||
}
|
|
||||||
_addList.pop_front();
|
|
||||||
}
|
|
||||||
_critSectList->Leave();
|
|
||||||
|
|
||||||
std::map<SOCKET, UdpSocketWindows*>::iterator it = _socketMap.begin();
|
|
||||||
while(it != _socketMap.end())
|
|
||||||
{
|
|
||||||
UdpSocketWindows* s = it->second;
|
|
||||||
if (s->WantsIncoming())
|
|
||||||
{
|
|
||||||
doSelect = true;
|
|
||||||
FD_SET(it->first, &_readFds);
|
|
||||||
}
|
|
||||||
if(!s->IsWritable())
|
|
||||||
{
|
|
||||||
FD_SET(it->first, &_writeFds);
|
|
||||||
doSelect = true;
|
|
||||||
}
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 num = 0;
|
|
||||||
if (doSelect)
|
|
||||||
{
|
|
||||||
num = select(0, &_readFds, &_writeFds, &_exceptFds, &timeout);
|
|
||||||
if (num == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
Sleep(10);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
Sleep(10);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
it = _socketMap.begin();
|
|
||||||
while (it != _socketMap.end() && num > 0)
|
|
||||||
{
|
|
||||||
if (FD_ISSET(it->first, &_readFds))
|
|
||||||
{
|
|
||||||
static_cast<UdpSocketWindows*>(it->second)->HasIncoming();
|
|
||||||
num--;
|
|
||||||
}
|
|
||||||
if (FD_ISSET(it->first, &_writeFds))
|
|
||||||
{
|
|
||||||
// Socket available for writing.
|
|
||||||
static_cast<UdpSocketWindows*>(it->second)->SetWritable();
|
|
||||||
num--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::Run(ThreadObj obj)
|
|
||||||
{
|
|
||||||
UdpSocketManagerWindows* mgr = static_cast<UdpSocketManagerWindows*>(obj);
|
|
||||||
return mgr->Process();
|
|
||||||
};
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::AddSocket(UdpSocketWrapper* s)
|
|
||||||
{
|
|
||||||
UdpSocketWindows* winSock = static_cast<UdpSocketWindows*>(s);
|
|
||||||
|
|
||||||
_critSectList->Enter();
|
|
||||||
std::map<SOCKET, UdpSocketWindows*>::iterator it =
|
|
||||||
_socketMap.find(winSock->GetFd());
|
|
||||||
if (it != _socketMap.end())
|
|
||||||
{
|
|
||||||
if (!_removeList.empty())
|
|
||||||
{
|
|
||||||
// File descriptors are re-used so it's possible that a socket has
|
|
||||||
// been added with the same file descriptor as a socket that is to
|
|
||||||
// be removed. I.e. the socket that is to be removed is no longer
|
|
||||||
// in use, delete it.
|
|
||||||
// TODO (hellner): removing items from _socketMap may cause race
|
|
||||||
// condition. Fix this.
|
|
||||||
std::list<SOCKET>::iterator removeIt = _removeList.begin();
|
|
||||||
while(removeIt != _removeList.end())
|
|
||||||
{
|
|
||||||
if (*removeIt == winSock->GetFd())
|
|
||||||
{
|
|
||||||
it = _socketMap.find(*removeIt);
|
|
||||||
UdpSocketWindows* delete_socket = it->second;
|
|
||||||
_socketMap.erase(it);
|
|
||||||
_removeList.erase(removeIt);
|
|
||||||
delete delete_socket;
|
|
||||||
_addList.push_back(winSock);
|
|
||||||
_critSectList->Leave();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
removeIt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_critSectList->Leave();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_addList.push_back(winSock);
|
|
||||||
_critSectList->Leave();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketManagerWindows::RemoveSocket(UdpSocketWrapper* s)
|
|
||||||
{
|
|
||||||
UdpSocketWindows* winSock = static_cast<UdpSocketWindows*>(s);
|
|
||||||
|
|
||||||
_critSectList->Enter();
|
|
||||||
// If socket is in the add list its safe to just remove it from the list.
|
|
||||||
if (!_addList.empty())
|
|
||||||
{
|
|
||||||
std::list<UdpSocketWindows*>::iterator it = _addList.begin();
|
|
||||||
while(it != _addList.end())
|
|
||||||
{
|
|
||||||
UdpSocketWindows* tempSocket = (*it);
|
|
||||||
if (tempSocket->GetFd() == winSock->GetFd())
|
|
||||||
{
|
|
||||||
_addList.erase(it);
|
|
||||||
delete winSock;
|
|
||||||
_critSectList->Leave();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the socket is not even added to the UdpSocketManagerWindows it's
|
|
||||||
// safe to delete the socket.
|
|
||||||
std::map<SOCKET, UdpSocketWindows*>::iterator findIt =
|
|
||||||
_socketMap.find(winSock->GetFd());
|
|
||||||
if (findIt == _socketMap.end())
|
|
||||||
{
|
|
||||||
delete winSock;
|
|
||||||
_critSectList->Leave();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_removeList.push_back(winSock->GetFd());
|
|
||||||
_critSectList->Leave();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} // namespace webrtc
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WINDOWS_H_
|
|
||||||
#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WINDOWS_H_
|
|
||||||
|
|
||||||
#define FD_SETSIZE 1024
|
|
||||||
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
// Don't change the include order.
|
|
||||||
// TODO (hellner): all header files should be compilable separately. Fix this.
|
|
||||||
#include "udp_socket_manager_wrapper.h"
|
|
||||||
#include "thread_wrapper.h"
|
|
||||||
#include "critical_section_wrapper.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
class UdpSocketWindows;
|
|
||||||
|
|
||||||
class UdpSocketManagerWindows : public UdpSocketManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UdpSocketManagerWindows();
|
|
||||||
virtual ~UdpSocketManagerWindows();
|
|
||||||
|
|
||||||
virtual bool Init(WebRtc_Word32 id,
|
|
||||||
WebRtc_UWord8& numOfWorkThreads);
|
|
||||||
|
|
||||||
virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id);
|
|
||||||
|
|
||||||
virtual bool Start();
|
|
||||||
virtual bool Stop();
|
|
||||||
|
|
||||||
virtual bool AddSocket(UdpSocketWrapper* s);
|
|
||||||
virtual bool RemoveSocket(UdpSocketWrapper* s);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static bool Run(ThreadObj obj);
|
|
||||||
bool Process();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WebRtc_Word32 _id;
|
|
||||||
ThreadWrapper* _thread;
|
|
||||||
|
|
||||||
fd_set _readFds;
|
|
||||||
fd_set _writeFds;
|
|
||||||
fd_set _exceptFds;
|
|
||||||
|
|
||||||
CriticalSectionWrapper* _critSectList;
|
|
||||||
|
|
||||||
std::map<SOCKET, UdpSocketWindows*> _socketMap;
|
|
||||||
std::list<UdpSocketWindows*> _addList;
|
|
||||||
std::list<SOCKET> _removeList;
|
|
||||||
|
|
||||||
static WebRtc_UWord32 _numOfActiveManagers;
|
|
||||||
};
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WINDOWS_H_
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* Use of this source code is governed by a BSD-style license
|
||||||
* that can be found in the LICENSE file in the root of the source
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "fix_interlocked_exchange_pointer_win.h"
|
#include "fix_interlocked_exchange_pointer_win.h"
|
||||||
#include "udp_socket_manager_windows.h"
|
|
||||||
#include "udp_socket2_manager_windows.h"
|
#include "udp_socket2_manager_windows.h"
|
||||||
#else
|
#else
|
||||||
#include "udp_socket_manager_posix.h"
|
#include "udp_socket_manager_posix.h"
|
||||||
@@ -24,14 +23,7 @@ namespace webrtc {
|
|||||||
UdpSocketManager* UdpSocketManager::CreateInstance()
|
UdpSocketManager* UdpSocketManager::CreateInstance()
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#if (defined(USE_WINSOCK2))
|
return static_cast<UdpSocketManager*>(new UdpSocket2ManagerWindows());
|
||||||
return static_cast<UdpSocketManager*>(
|
|
||||||
new UdpSocket2ManagerWindows());
|
|
||||||
#else
|
|
||||||
numOfWorkThreads = 1;
|
|
||||||
return static_cast<UdpSocketManager*>(
|
|
||||||
new UdpSocketManagerWindows());
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
return new UdpSocketManagerPosix();
|
return new UdpSocketManagerPosix();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,722 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "udp_socket_windows.h"
|
|
||||||
|
|
||||||
// Disable deprication warning from traffic.h
|
|
||||||
#pragma warning(disable : 4995)
|
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <Qos.h>
|
|
||||||
// Don't change include order for these header files.
|
|
||||||
#include <Winsock2.h>
|
|
||||||
#include <Ntddndis.h>
|
|
||||||
#include <traffic.h>
|
|
||||||
|
|
||||||
#include "traffic_control_windows.h"
|
|
||||||
#include "udp_socket_manager_wrapper.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
typedef struct _QOS_DESTADDR
|
|
||||||
{
|
|
||||||
QOS_OBJECT_HDR ObjectHdr;
|
|
||||||
const struct sockaddr* SocketAddress;
|
|
||||||
ULONG SocketAddressLength;
|
|
||||||
} QOS_DESTADDR, *LPQOS_DESTADDR;
|
|
||||||
|
|
||||||
typedef const QOS_DESTADDR* LPCQOS_DESTADDR;
|
|
||||||
|
|
||||||
#define QOS_GENERAL_ID_BASE 2000
|
|
||||||
#define QOS_OBJECT_DESTADDR (0x00000004 + QOS_GENERAL_ID_BASE)
|
|
||||||
|
|
||||||
#define MAX_PACKET_SIZE 2048
|
|
||||||
|
|
||||||
class UDPPacket
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UDPPacket()
|
|
||||||
{
|
|
||||||
_length = 0;
|
|
||||||
}
|
|
||||||
WebRtc_Word32 Set(const WebRtc_Word8* buf, WebRtc_Word32 length)
|
|
||||||
{
|
|
||||||
if(length > MAX_PACKET_SIZE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
_length = length;
|
|
||||||
memcpy(_buffer,buf,length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
WebRtc_Word32 Set(const WebRtc_Word8* buf, WebRtc_Word32 length,
|
|
||||||
const SocketAddress* addr)
|
|
||||||
{
|
|
||||||
if(length > MAX_PACKET_SIZE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_length = length;
|
|
||||||
memcpy(&_remoteAddr,addr,sizeof(SocketAddress));
|
|
||||||
memcpy(_buffer,buf,length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketAddress _remoteAddr;
|
|
||||||
char _buffer[MAX_PACKET_SIZE];
|
|
||||||
WebRtc_Word32 _length;
|
|
||||||
};
|
|
||||||
|
|
||||||
UdpSocketWindows::UdpSocketWindows(const WebRtc_Word32 id,
|
|
||||||
UdpSocketManager* mgr, bool ipV6Enable)
|
|
||||||
: _id(id),
|
|
||||||
_qos(true)
|
|
||||||
{
|
|
||||||
_wantsIncoming = false;
|
|
||||||
_error = 0;
|
|
||||||
_mgr = mgr;
|
|
||||||
_addedToMgr = false;
|
|
||||||
|
|
||||||
_obj = NULL;
|
|
||||||
_incomingCb = NULL;
|
|
||||||
_socket = INVALID_SOCKET;
|
|
||||||
_terminate=false;
|
|
||||||
|
|
||||||
_clientHandle = INVALID_HANDLE_VALUE;
|
|
||||||
_flowHandle = INVALID_HANDLE_VALUE;
|
|
||||||
_filterHandle = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
|
|
||||||
"UdpSocketWindows::UdpSocketWindows()");
|
|
||||||
|
|
||||||
_gtc = NULL;
|
|
||||||
|
|
||||||
// Check if QoS is supported.
|
|
||||||
WSAPROTOCOL_INFO pProtocolInfo;
|
|
||||||
DWORD dwBufLen = 0;
|
|
||||||
BOOL bProtocolFound = FALSE;
|
|
||||||
WSAPROTOCOL_INFO* lpProtocolBuf = NULL;
|
|
||||||
|
|
||||||
// Set dwBufLen to the size needed to retreive all the requested information
|
|
||||||
// from WSAEnumProtocols.
|
|
||||||
WebRtc_Word32 nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
|
|
||||||
lpProtocolBuf = (WSAPROTOCOL_INFO*)malloc(dwBufLen);
|
|
||||||
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
|
|
||||||
|
|
||||||
WebRtc_Word32 iProtocol;
|
|
||||||
if (ipV6Enable)
|
|
||||||
{
|
|
||||||
iProtocol = AF_INET6;
|
|
||||||
} else {
|
|
||||||
iProtocol = AF_INET;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (WebRtc_Word32 i = 0; i < nRet; i++)
|
|
||||||
{
|
|
||||||
if (iProtocol == lpProtocolBuf[i].iAddressFamily && IPPROTO_UDP ==
|
|
||||||
lpProtocolBuf[i].iProtocol)
|
|
||||||
{
|
|
||||||
if ((XP1_QOS_SUPPORTED ==
|
|
||||||
(XP1_QOS_SUPPORTED & lpProtocolBuf[i].dwServiceFlags1)))
|
|
||||||
{
|
|
||||||
pProtocolInfo = lpProtocolBuf[i];
|
|
||||||
bProtocolFound = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bProtocolFound)
|
|
||||||
{
|
|
||||||
_socket = INVALID_SOCKET;
|
|
||||||
_qos = false;
|
|
||||||
free(lpProtocolBuf);
|
|
||||||
_error = SOCKET_ERROR_NO_QOS;
|
|
||||||
}else {
|
|
||||||
_socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
|
|
||||||
FROM_PROTOCOL_INFO,&pProtocolInfo, 0,
|
|
||||||
WSA_FLAG_OVERLAPPED);
|
|
||||||
free(lpProtocolBuf);
|
|
||||||
if (_socket != INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
_qos = false;
|
|
||||||
_error = SOCKET_ERROR_NO_QOS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// QoS not supported.
|
|
||||||
if(ipV6Enable)
|
|
||||||
{
|
|
||||||
_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
}
|
|
||||||
// Non-blocking mode.
|
|
||||||
WebRtc_Word32 iMode = 1;
|
|
||||||
ioctlsocket(_socket, FIONBIO, (u_long FAR*) &iMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
UdpSocketWindows::~UdpSocketWindows()
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
|
|
||||||
"UdpSocketWindows::~UdpSocketWindows()");
|
|
||||||
if (_gtc)
|
|
||||||
{
|
|
||||||
TrafficControlWindows::Release(_gtc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketWindows::ChangeUniqueId(const WebRtc_Word32 id)
|
|
||||||
{
|
|
||||||
_id = id;
|
|
||||||
if (_gtc)
|
|
||||||
{
|
|
||||||
_gtc->ChangeUniqueId(id);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketWindows::ValidHandle()
|
|
||||||
{
|
|
||||||
return GetFd() != INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketWindows::SetCallback(CallbackObj obj, IncomingSocketCallback cb)
|
|
||||||
{
|
|
||||||
_obj = obj;
|
|
||||||
_incomingCb = cb;
|
|
||||||
|
|
||||||
if (_mgr->AddSocket(this))
|
|
||||||
{
|
|
||||||
_addedToMgr = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketWindows::SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname,
|
|
||||||
const WebRtc_Word8* optval,
|
|
||||||
WebRtc_Word32 optlen)
|
|
||||||
{
|
|
||||||
if(0 == setsockopt(_socket, level, optname,
|
|
||||||
reinterpret_cast<const char*>(optval), optlen))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketWindows::Bind(const SocketAddress& name)
|
|
||||||
{
|
|
||||||
const struct sockaddr* socketName =
|
|
||||||
reinterpret_cast<const struct sockaddr*>(&name);
|
|
||||||
|
|
||||||
if (0 == bind(_socket, socketName, sizeof(SocketAddress)))
|
|
||||||
{
|
|
||||||
_localAddr = name;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketWindows::SendTo(const WebRtc_Word8* buf,
|
|
||||||
WebRtc_Word32 len,
|
|
||||||
const SocketAddress& to)
|
|
||||||
{
|
|
||||||
// Don't try to send this packet if there are older packets queued up.
|
|
||||||
if(!_notSentPackets.Empty())
|
|
||||||
{
|
|
||||||
UDPPacket* packet = new UDPPacket();
|
|
||||||
packet->Set(buf, len, &to);
|
|
||||||
if(!_notSentPackets.Empty())
|
|
||||||
{
|
|
||||||
_notSentPackets.PushBack(packet);
|
|
||||||
return len;
|
|
||||||
}else {
|
|
||||||
// No old packets queued up. Free to try to send.
|
|
||||||
delete packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 retVal;
|
|
||||||
retVal = sendto(_socket, reinterpret_cast<const char*>(buf), len, 0,
|
|
||||||
reinterpret_cast<const struct sockaddr*>(&to),
|
|
||||||
sizeof(SocketAddress));
|
|
||||||
|
|
||||||
if(retVal == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
if (_error == WSAEWOULDBLOCK)
|
|
||||||
{
|
|
||||||
UDPPacket* packet = new UDPPacket();
|
|
||||||
packet->Set(buf,len, &to);
|
|
||||||
_notSentPackets.PushBack(packet);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UdpSocketWindows::HasIncoming()
|
|
||||||
{
|
|
||||||
char buf[MAX_PACKET_SIZE];
|
|
||||||
SocketAddress from;
|
|
||||||
int fromlen = sizeof(from);
|
|
||||||
WebRtc_Word32 retval = recvfrom(_socket, buf,
|
|
||||||
sizeof(buf), 0,
|
|
||||||
reinterpret_cast<struct sockaddr*>(&from),
|
|
||||||
&fromlen);
|
|
||||||
|
|
||||||
switch(retval)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
// The connection has been gracefully closed.
|
|
||||||
break;
|
|
||||||
case SOCKET_ERROR:
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if(_wantsIncoming && _incomingCb)
|
|
||||||
_incomingCb(_obj, reinterpret_cast<WebRtc_Word8*>(buf),
|
|
||||||
retval, &from);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UdpSocketWindows::SetWritable()
|
|
||||||
{
|
|
||||||
// Try to send packets that have been queued up.
|
|
||||||
while(!_notSentPackets.Empty())
|
|
||||||
{
|
|
||||||
UDPPacket* packet = (UDPPacket*)_notSentPackets.First()->GetItem();
|
|
||||||
if(!packet)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(sendto(
|
|
||||||
_socket, packet->_buffer,
|
|
||||||
packet->_length,
|
|
||||||
0,
|
|
||||||
reinterpret_cast<const struct sockaddr*>(
|
|
||||||
&(packet->_remoteAddr)),
|
|
||||||
sizeof(SocketAddress)) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
if (_error == WSAEWOULDBLOCK)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete packet;
|
|
||||||
_notSentPackets.PopFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UdpSocketWindows::SetQos(WebRtc_Word32 serviceType,
|
|
||||||
WebRtc_Word32 tokenRate,
|
|
||||||
WebRtc_Word32 bucketSize,
|
|
||||||
WebRtc_Word32 peekBandwith,
|
|
||||||
WebRtc_Word32 minPolicedSize,
|
|
||||||
WebRtc_Word32 maxSduSize,
|
|
||||||
const SocketAddress &stRemName,
|
|
||||||
WebRtc_Word32 overrideDSCP)
|
|
||||||
{
|
|
||||||
if(_qos == false)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"UdpSocket2Windows::SetQos(), socket not capable of QOS");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QOS Qos;
|
|
||||||
WebRtc_Word32 result;
|
|
||||||
DWORD BytesRet;
|
|
||||||
|
|
||||||
if(overrideDSCP != 0)
|
|
||||||
{
|
|
||||||
FLOWSPEC f;
|
|
||||||
WebRtc_Word32 err = CreateFlowSpec(serviceType, tokenRate, bucketSize,
|
|
||||||
peekBandwith, minPolicedSize,
|
|
||||||
maxSduSize, &f);
|
|
||||||
if(err == -1)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return SetTOSByte(overrideDSCP, &f, &f) == 0;
|
|
||||||
}
|
|
||||||
memset(&Qos, QOS_NOT_SPECIFIED, sizeof(QOS));
|
|
||||||
|
|
||||||
Qos.SendingFlowspec.ServiceType = serviceType;
|
|
||||||
Qos.SendingFlowspec.TokenRate = tokenRate;
|
|
||||||
Qos.SendingFlowspec.TokenBucketSize = bucketSize;
|
|
||||||
Qos.SendingFlowspec.PeakBandwidth = peekBandwith;
|
|
||||||
Qos.SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.SendingFlowspec.MinimumPolicedSize = minPolicedSize;
|
|
||||||
Qos.SendingFlowspec.MaxSduSize = maxSduSize;
|
|
||||||
|
|
||||||
// Only ServiceType is needed for receiving.
|
|
||||||
Qos.ReceivingFlowspec.ServiceType = serviceType;
|
|
||||||
Qos.ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
|
|
||||||
Qos.ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
|
|
||||||
|
|
||||||
Qos.ProviderSpecific.len = 0;
|
|
||||||
Qos.ProviderSpecific.buf = NULL;
|
|
||||||
WebRtc_Word8* p = (WebRtc_Word8*)malloc(sizeof(QOS_DESTADDR) +
|
|
||||||
sizeof(QOS_DS_CLASS));
|
|
||||||
|
|
||||||
QOS_DESTADDR* QosDestaddr = (QOS_DESTADDR*)p;
|
|
||||||
ZeroMemory((WebRtc_Word8 *)QosDestaddr, sizeof(QOS_DESTADDR));
|
|
||||||
QosDestaddr->ObjectHdr.ObjectType = QOS_OBJECT_DESTADDR;
|
|
||||||
QosDestaddr->ObjectHdr.ObjectLength = sizeof(QOS_DESTADDR);
|
|
||||||
QosDestaddr->SocketAddress = (SOCKADDR*)&stRemName;
|
|
||||||
QosDestaddr->SocketAddressLength = sizeof(SocketAddress);
|
|
||||||
Qos.ProviderSpecific.len = QosDestaddr->ObjectHdr.ObjectLength;
|
|
||||||
Qos.ProviderSpecific.buf = (char*)p;
|
|
||||||
|
|
||||||
// Socket must be bound for this call to be successfull. If socket is not
|
|
||||||
// bound WSAGetLastError() will return 10022.
|
|
||||||
result = WSAIoctl(GetFd(),SIO_SET_QOS, &Qos,sizeof(QOS),NULL, 0, &BytesRet,
|
|
||||||
NULL,NULL);
|
|
||||||
if (result == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
_error = WSAGetLastError();
|
|
||||||
free(p);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
free(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketWindows::SetTOS(WebRtc_Word32 serviceType)
|
|
||||||
{
|
|
||||||
WebRtc_Word32 res = SetTOSByte(serviceType, NULL, NULL);
|
|
||||||
|
|
||||||
if (res == -1)
|
|
||||||
{
|
|
||||||
OSVERSIONINFO OsVersion;
|
|
||||||
OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
||||||
GetVersionEx (&OsVersion);
|
|
||||||
|
|
||||||
if ((OsVersion.dwMajorVersion == 4))
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketWindows::CreateFlowSpec(WebRtc_Word32 serviceType,
|
|
||||||
WebRtc_Word32 tokenRate,
|
|
||||||
WebRtc_Word32 bucketSize,
|
|
||||||
WebRtc_Word32 peekBandwith,
|
|
||||||
WebRtc_Word32 minPolicedSize,
|
|
||||||
WebRtc_Word32 maxSduSize,
|
|
||||||
FLOWSPEC *f)
|
|
||||||
{
|
|
||||||
if(!f)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
f->ServiceType = serviceType;
|
|
||||||
f->TokenRate = tokenRate;
|
|
||||||
f->TokenBucketSize = bucketSize;
|
|
||||||
f->PeakBandwidth = peekBandwith;
|
|
||||||
f->DelayVariation = QOS_NOT_SPECIFIED;
|
|
||||||
f->Latency = QOS_NOT_SPECIFIED;
|
|
||||||
f->MinimumPolicedSize = minPolicedSize;
|
|
||||||
f->MaxSduSize = maxSduSize;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebRtc_Word32 UdpSocketWindows::SetTOSByte(WebRtc_Word32 serviceType,
|
|
||||||
FLOWSPEC* send, FLOWSPEC* recv)
|
|
||||||
{
|
|
||||||
if(_socket == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!_gtc)
|
|
||||||
{
|
|
||||||
_gtc = TrafficControlWindows::GetInstance(_id);
|
|
||||||
}
|
|
||||||
if (!_gtc)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TCI_CLIENT_FUNC_LIST QoSFunctions;
|
|
||||||
QoSFunctions.ClAddFlowCompleteHandler = NULL;
|
|
||||||
QoSFunctions.ClDeleteFlowCompleteHandler = NULL;
|
|
||||||
QoSFunctions.ClModifyFlowCompleteHandler = NULL;
|
|
||||||
QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler;
|
|
||||||
// Register the client with Traffic control interface.
|
|
||||||
HANDLE ClientHandle;
|
|
||||||
ULONG result = _gtc->TcRegisterClient(CURRENT_TCI_VERSION, NULL,
|
|
||||||
&QoSFunctions,&ClientHandle);
|
|
||||||
if(result != NO_ERROR)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"TcRegisterClient returned %d", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find traffic control-enabled network interfaces.
|
|
||||||
ULONG BufferSize = 0;
|
|
||||||
result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, NULL);
|
|
||||||
|
|
||||||
if(result != NO_ERROR && result != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"Error enumerating interfaces, %d", result);
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(result != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
{
|
|
||||||
// Empty buffer contains all control-enabled network interfaces. I.e.
|
|
||||||
// ToS is not enabled.
|
|
||||||
WEBRTC_TRACE(
|
|
||||||
kTraceError,
|
|
||||||
kTraceTransport,
|
|
||||||
_id,
|
|
||||||
"Error enumerating interfaces: passed in 0 and received\
|
|
||||||
NO_ERROR when expecting INSUFFICIENT_BUFFER, %d");
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PTC_IFC_DESCRIPTOR pInterfaceBuffer =
|
|
||||||
(PTC_IFC_DESCRIPTOR)malloc(BufferSize);
|
|
||||||
if(pInterfaceBuffer == NULL)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"Out ot memory failure");
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize,
|
|
||||||
pInterfaceBuffer);
|
|
||||||
|
|
||||||
if(result != NO_ERROR)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(
|
|
||||||
kTraceError,
|
|
||||||
kTraceTransport,
|
|
||||||
_id,
|
|
||||||
"Critical: error enumerating interfaces when passing in correct\
|
|
||||||
buffer size: %d", result);
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PTC_IFC_DESCRIPTOR oneinterface;
|
|
||||||
HANDLE ifcHandle, iFilterHandle, iflowHandle;
|
|
||||||
bool addrFound = false;
|
|
||||||
ULONG filterSourceAddress = ULONG_MAX;
|
|
||||||
|
|
||||||
const struct sockaddr_in* name;
|
|
||||||
name = reinterpret_cast<const struct sockaddr_in*>(&_localAddr);
|
|
||||||
|
|
||||||
// Find the interface corresponding to the local address.
|
|
||||||
for(oneinterface = pInterfaceBuffer;
|
|
||||||
oneinterface != (PTC_IFC_DESCRIPTOR)
|
|
||||||
(((WebRtc_Word8*)pInterfaceBuffer) + BufferSize);
|
|
||||||
oneinterface = (PTC_IFC_DESCRIPTOR)
|
|
||||||
((WebRtc_Word8*)oneinterface + oneinterface->Length))
|
|
||||||
{
|
|
||||||
|
|
||||||
char interfaceName[500];
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, oneinterface->pInterfaceName, -1,
|
|
||||||
interfaceName, sizeof(interfaceName), 0, 0);
|
|
||||||
|
|
||||||
PNETWORK_ADDRESS_LIST addresses =
|
|
||||||
&(oneinterface->AddressListDesc.AddressList);
|
|
||||||
for(LONG i = 0; i < addresses->AddressCount; i++)
|
|
||||||
{
|
|
||||||
// Only look at TCP/IP addresses.
|
|
||||||
if(addresses->Address[i].AddressType != NDIS_PROTOCOL_ID_TCP_IP)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NETWORK_ADDRESS_IP* pIpAddr =
|
|
||||||
(NETWORK_ADDRESS_IP*)&(addresses->Address[i].Address);
|
|
||||||
|
|
||||||
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
|
|
||||||
"Examining Interface %s", interfaceName);
|
|
||||||
if(pIpAddr->in_addr == name->sin_addr.S_un.S_addr)
|
|
||||||
{
|
|
||||||
filterSourceAddress = pIpAddr->in_addr;
|
|
||||||
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
|
|
||||||
"Found ip addr: %s", inet_ntoa(name->sin_addr));
|
|
||||||
addrFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!addrFound)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!addrFound)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "IP Address not found");
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
result = _gtc->TcOpenInterfaceW(oneinterface->pInterfaceName, ClientHandle,
|
|
||||||
NULL, &ifcHandle);
|
|
||||||
|
|
||||||
if(result != NO_ERROR)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"Error opening interface: %d", result);
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FLOWSPEC defaultSend, defaultRecv;
|
|
||||||
if(send == NULL)
|
|
||||||
{
|
|
||||||
defaultSend.DelayVariation = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.Latency = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.MaxSduSize = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.MinimumPolicedSize = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.PeakBandwidth = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.ServiceType = SERVICETYPE_BESTEFFORT;
|
|
||||||
defaultSend.TokenBucketSize = QOS_NOT_SPECIFIED;
|
|
||||||
defaultSend.TokenRate = 10000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
defaultSend = *send;
|
|
||||||
}
|
|
||||||
if(recv == NULL)
|
|
||||||
{
|
|
||||||
defaultRecv = defaultSend;
|
|
||||||
defaultRecv.ServiceType = SERVICETYPE_CONTROLLEDLOAD;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
defaultRecv = *recv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PTC_GEN_FLOW flow =
|
|
||||||
(PTC_GEN_FLOW)malloc(sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS));
|
|
||||||
|
|
||||||
flow->ReceivingFlowspec = defaultRecv;
|
|
||||||
flow->SendingFlowspec = defaultSend;
|
|
||||||
|
|
||||||
QOS_DS_CLASS dsClass;
|
|
||||||
|
|
||||||
ZeroMemory((WebRtc_Word8*)&dsClass, sizeof(QOS_DS_CLASS));
|
|
||||||
|
|
||||||
dsClass.DSField = serviceType;
|
|
||||||
|
|
||||||
dsClass.ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS;
|
|
||||||
dsClass.ObjectHdr.ObjectLength = sizeof(dsClass);
|
|
||||||
|
|
||||||
memcpy(flow->TcObjects, (void*)&dsClass, sizeof(QOS_DS_CLASS));
|
|
||||||
flow->TcObjectsLength = sizeof(dsClass);
|
|
||||||
|
|
||||||
result = _gtc->TcAddFlow(ifcHandle, NULL, 0, flow, &iflowHandle);
|
|
||||||
if(result != NO_ERROR)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"Error adding flow: %d", result);
|
|
||||||
_gtc->TcCloseInterface(ifcHandle);
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(flow);
|
|
||||||
IP_PATTERN filterPattern, mask;
|
|
||||||
|
|
||||||
ZeroMemory((WebRtc_Word8*)&filterPattern, sizeof(IP_PATTERN));
|
|
||||||
ZeroMemory((WebRtc_Word8*)&mask, sizeof(IP_PATTERN));
|
|
||||||
|
|
||||||
filterPattern.ProtocolId = IPPROTO_UDP;
|
|
||||||
// "name" fields are in network order.
|
|
||||||
filterPattern.S_un.S_un_ports.s_srcport = name->sin_port;
|
|
||||||
filterPattern.SrcAddr = filterSourceAddress;
|
|
||||||
|
|
||||||
// Unsigned max of a type corresponds to a bitmask with all bits set to 1.
|
|
||||||
// I.e. the filter should allow all ProtocolIds, any source port and any
|
|
||||||
// IP address.
|
|
||||||
mask.ProtocolId = UCHAR_MAX;
|
|
||||||
mask.S_un.S_un_ports.s_srcport = USHRT_MAX;
|
|
||||||
mask.SrcAddr = ULONG_MAX;
|
|
||||||
|
|
||||||
TC_GEN_FILTER filter;
|
|
||||||
filter.AddressType = NDIS_PROTOCOL_ID_TCP_IP;
|
|
||||||
filter.Mask = (LPVOID)&mask;
|
|
||||||
filter.Pattern = (LPVOID)&filterPattern;
|
|
||||||
filter.PatternSize = sizeof(IP_PATTERN);
|
|
||||||
if(_filterHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
_gtc->TcDeleteFilter(_filterHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = _gtc->TcAddFilter(iflowHandle, &filter, &iFilterHandle);
|
|
||||||
if(result != NO_ERROR)
|
|
||||||
{
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
|
|
||||||
"Error adding filter: %d", result);
|
|
||||||
_gtc->TcDeleteFlow(iflowHandle);
|
|
||||||
_gtc->TcCloseInterface(ifcHandle);
|
|
||||||
_gtc->TcDeregisterClient(ClientHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
_flowHandle = iflowHandle;
|
|
||||||
_filterHandle = iFilterHandle;
|
|
||||||
_clientHandle = ClientHandle;
|
|
||||||
|
|
||||||
_gtc->TcCloseInterface(ifcHandle);
|
|
||||||
free(pInterfaceBuffer);
|
|
||||||
|
|
||||||
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
|
|
||||||
"Successfully created flow and filter.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace webrtc
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WINDOWS_H_
|
|
||||||
#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WINDOWS_H_
|
|
||||||
|
|
||||||
#include <Winsock2.h>
|
|
||||||
|
|
||||||
#include "list_wrapper.h"
|
|
||||||
#include "udp_socket_manager_wrapper.h"
|
|
||||||
#include "udp_socket_wrapper.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
class TrafficControlWindows;
|
|
||||||
|
|
||||||
class UdpSocketWindows : public UdpSocketWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UdpSocketWindows(const WebRtc_Word32 id, UdpSocketManager* mgr,
|
|
||||||
bool ipV6Enable = false);
|
|
||||||
virtual ~UdpSocketWindows();
|
|
||||||
|
|
||||||
virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id);
|
|
||||||
|
|
||||||
virtual bool ValidHandle();
|
|
||||||
|
|
||||||
virtual bool SetCallback(CallbackObj obj, IncomingSocketCallback cb);
|
|
||||||
|
|
||||||
virtual bool Bind(const SocketAddress& name);
|
|
||||||
|
|
||||||
virtual bool SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname,
|
|
||||||
const WebRtc_Word8* optval, WebRtc_Word32 optlen);
|
|
||||||
|
|
||||||
virtual WebRtc_Word32 SendTo(const WebRtc_Word8* buf, WebRtc_Word32 len,
|
|
||||||
const SocketAddress& to);
|
|
||||||
|
|
||||||
virtual SOCKET GetFd() {return _socket;}
|
|
||||||
virtual WebRtc_Word32 GetError() {return _error;}
|
|
||||||
|
|
||||||
virtual bool SetQos(WebRtc_Word32 serviceType, WebRtc_Word32 tokenRate,
|
|
||||||
WebRtc_Word32 bucketSize, WebRtc_Word32 peekBandwith,
|
|
||||||
WebRtc_Word32 minPolicedSize, WebRtc_Word32 maxSduSize,
|
|
||||||
const SocketAddress& stRemName,
|
|
||||||
WebRtc_Word32 overrideDSCP = 0);
|
|
||||||
|
|
||||||
virtual WebRtc_Word32 SetTOS(const WebRtc_Word32 serviceType);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void HasIncoming();
|
|
||||||
// Socket is free to process pending packets.
|
|
||||||
void SetWritable();
|
|
||||||
bool IsWritable() {return _notSentPackets.Empty();}
|
|
||||||
bool WantsIncoming() {return _wantsIncoming;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class UdpSocketManagerWindows;
|
|
||||||
|
|
||||||
WebRtc_Word32 CreateFlowSpec(WebRtc_Word32 serviceType,
|
|
||||||
WebRtc_Word32 tokenRate,
|
|
||||||
WebRtc_Word32 bucketSize,
|
|
||||||
WebRtc_Word32 peekBandwith,
|
|
||||||
WebRtc_Word32 minPolicedSize,
|
|
||||||
WebRtc_Word32 maxSduSize, FLOWSPEC* f);
|
|
||||||
|
|
||||||
WebRtc_Word32 SetTOSByte(WebRtc_Word32 serviceType, FLOWSPEC* send,
|
|
||||||
FLOWSPEC* recv);
|
|
||||||
|
|
||||||
WebRtc_Word32 _id;
|
|
||||||
IncomingSocketCallback _incomingCb;
|
|
||||||
|
|
||||||
CallbackObj _obj;
|
|
||||||
bool _qos;
|
|
||||||
WebRtc_Word32 _error;
|
|
||||||
|
|
||||||
volatile bool _addedToMgr;
|
|
||||||
|
|
||||||
SocketAddress _remoteAddr;
|
|
||||||
SocketAddress _localAddr;
|
|
||||||
SOCKET _socket;
|
|
||||||
UdpSocketManager* _mgr;
|
|
||||||
|
|
||||||
ListWrapper _notSentPackets;
|
|
||||||
bool _terminate;
|
|
||||||
|
|
||||||
// QoS handles.
|
|
||||||
HANDLE _clientHandle;
|
|
||||||
HANDLE _flowHandle;
|
|
||||||
HANDLE _filterHandle;
|
|
||||||
|
|
||||||
// TOS implementation.
|
|
||||||
TrafficControlWindows* _gtc;
|
|
||||||
};
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WINDOWS_H_
|
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
#include "udp_socket_manager_wrapper.h"
|
#include "udp_socket_manager_wrapper.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include "udp_socket_windows.h"
|
|
||||||
#include "udp_socket2_windows.h"
|
#include "udp_socket2_windows.h"
|
||||||
#else
|
#else
|
||||||
#include "udp_socket_posix.h"
|
#include "udp_socket_posix.h"
|
||||||
@@ -58,21 +57,12 @@ void UdpSocketWrapper::SetEventToNull()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WINSOCK2
|
|
||||||
UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const WebRtc_Word32 id,
|
UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const WebRtc_Word32 id,
|
||||||
UdpSocketManager* mgr,
|
UdpSocketManager* mgr,
|
||||||
CallbackObj obj,
|
CallbackObj obj,
|
||||||
IncomingSocketCallback cb,
|
IncomingSocketCallback cb,
|
||||||
bool ipV6Enable,
|
bool ipV6Enable,
|
||||||
bool disableGQOS)
|
bool disableGQOS)
|
||||||
#else
|
|
||||||
UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const WebRtc_Word32 id,
|
|
||||||
UdpSocketManager* mgr,
|
|
||||||
CallbackObj obj,
|
|
||||||
IncomingSocketCallback cb,
|
|
||||||
bool ipV6Enable,
|
|
||||||
bool /*disableGQOS*/)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
|
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
|
||||||
@@ -101,12 +91,7 @@ UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const WebRtc_Word32 id,
|
|||||||
_initiated = true;
|
_initiated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WINSOCK2
|
|
||||||
s = new UdpSocket2Windows(id, mgr, ipV6Enable, disableGQOS);
|
s = new UdpSocket2Windows(id, mgr, ipV6Enable, disableGQOS);
|
||||||
#else
|
|
||||||
#pragma message("Error: No non-Winsock2 implementation for WinCE")
|
|
||||||
s = new UdpSocketWindows(id, mgr, ipV6Enable);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (!_initiated)
|
if (!_initiated)
|
||||||
|
|||||||
@@ -40,12 +40,8 @@
|
|||||||
'udp_socket_manager_posix.cc',
|
'udp_socket_manager_posix.cc',
|
||||||
'udp_socket_manager_posix.h',
|
'udp_socket_manager_posix.h',
|
||||||
# Windows
|
# Windows
|
||||||
'udp_socket_manager_windows.cc',
|
|
||||||
'udp_socket_manager_windows.h',
|
|
||||||
'udp_socket2_manager_windows.cc',
|
'udp_socket2_manager_windows.cc',
|
||||||
'udp_socket2_manager_windows.h',
|
'udp_socket2_manager_windows.h',
|
||||||
'udp_socket_windows.cc',
|
|
||||||
'udp_socket_windows.h',
|
|
||||||
'udp_socket2_windows.cc',
|
'udp_socket2_windows.cc',
|
||||||
'udp_socket2_windows.h',
|
'udp_socket2_windows.h',
|
||||||
'traffic_control_windows.cc',
|
'traffic_control_windows.cc',
|
||||||
@@ -63,12 +59,8 @@
|
|||||||
}],
|
}],
|
||||||
['OS!="win"', {
|
['OS!="win"', {
|
||||||
'sources!': [
|
'sources!': [
|
||||||
'udp_socket_manager_windows.cc',
|
|
||||||
'udp_socket_manager_windows.h',
|
|
||||||
'udp_socket2_manager_windows.cc',
|
'udp_socket2_manager_windows.cc',
|
||||||
'udp_socket2_manager_windows.h',
|
'udp_socket2_manager_windows.h',
|
||||||
'udp_socket_windows.cc',
|
|
||||||
'udp_socket_windows.h',
|
|
||||||
'udp_socket2_windows.cc',
|
'udp_socket2_windows.cc',
|
||||||
'udp_socket2_windows.h',
|
'udp_socket2_windows.h',
|
||||||
'traffic_control_windows.cc',
|
'traffic_control_windows.cc',
|
||||||
@@ -85,11 +77,6 @@
|
|||||||
'OTHER_CPLUSPLUSFLAGS': [ '-fno-strict-aliasing' ],
|
'OTHER_CPLUSPLUSFLAGS': [ '-fno-strict-aliasing' ],
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
['OS=="win"', {
|
|
||||||
'defines': [
|
|
||||||
'USE_WINSOCK2',
|
|
||||||
],
|
|
||||||
}],
|
|
||||||
] # conditions
|
] # conditions
|
||||||
},
|
},
|
||||||
], # targets
|
], # targets
|
||||||
|
|||||||
Reference in New Issue
Block a user