15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2005, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/win32socketserver.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/byteorder.h" 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/common.h" 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h" 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/winping.h" 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/win32window.h" 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <ws2tcpip.h> // NOLINT 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace talk_base { 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Win32Socket 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// TODO: Move this to a common place where PhysicalSocketServer can 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// share it. 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Standard MTUs 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint16 PACKET_MAXIMUMS[] = { 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 65535, // Theoretical maximum, Hyperchannel 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 32000, // Nothing 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 17914, // 16Mb IBM Token Ring 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8166, // IEEE 802.4 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 4464 // IEEE 802.5 (4Mb max) 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4352, // FDDI 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 2048, // Wideband Network 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2002, // IEEE 802.5 (4Mb recommended) 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 1536, // Expermental Ethernet Networks 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 1500, // Ethernet, Point-to-Point (default) 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1492, // IEEE 802.3 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1006, // SLIP, ARPANET 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 576, // X.25 Networks 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 544, // DEC IP Portal 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // 512, // NETBIOS 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 508, // IEEE 802/Source-Rt Bridge, ARCNET 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 296, // Point-to-Point (low delay) 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 68, // Official minimum 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 0, // End of list marker 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int IP_HEADER_SIZE = 20u; 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int ICMP_HEADER_SIZE = 8u; 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int ICMP_PING_TIMEOUT_MILLIS = 10000u; 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// TODO: Enable for production builds also? Use FormatMessage? 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef _DEBUG 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgLPCSTR WSAErrorToString(int error, LPCSTR *description_result) { 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPCSTR string = "Unspecified"; 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPCSTR description = "Unspecified description"; 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (error) { 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case ERROR_SUCCESS: 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "SUCCESS"; 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Operation succeeded"; 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAEWOULDBLOCK: 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAEWOULDBLOCK"; 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Using a non-blocking socket, will notify later"; 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAEACCES: 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAEACCES"; 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Access denied, or sharing violation"; 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAEADDRNOTAVAIL: 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAEADDRNOTAVAIL"; 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Address is not valid in this context"; 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAENETDOWN: 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAENETDOWN"; 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Network is down"; 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAENETUNREACH: 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAENETUNREACH"; 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Network is up, but unreachable"; 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAENETRESET: 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSANETRESET"; 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Connection has been reset due to keep-alive activity"; 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAECONNABORTED: 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAECONNABORTED"; 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Aborted by host"; 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAECONNRESET: 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAECONNRESET"; 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Connection reset by host"; 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAETIMEDOUT: 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAETIMEDOUT"; 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Timed out, host failed to respond"; 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAECONNREFUSED: 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAECONNREFUSED"; 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Host actively refused connection"; 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAEHOSTDOWN: 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAEHOSTDOWN"; 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Host is down"; 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAEHOSTUNREACH: 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAEHOSTUNREACH"; 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "Host is unreachable"; 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WSAHOST_NOT_FOUND: 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org string = "WSAHOST_NOT_FOUND"; 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org description = "No such host is known"; 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (description_result) { 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *description_result = description; 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return string; 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid ReportWSAError(LPCSTR context, int error, const SocketAddress& address) { 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPCSTR description_string; 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPCSTR error_string = WSAErrorToString(error, &description_string); 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << context << " = " << error 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " (" << error_string << ":" << description_string << ") [" 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << address.ToString() << "]"; 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid ReportWSAError(LPCSTR context, int error, const SocketAddress& address) {} 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org///////////////////////////////////////////////////////////////////////////// 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Win32Socket::EventSink 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org///////////////////////////////////////////////////////////////////////////// 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define WM_SOCKETNOTIFY (WM_USER + 50) 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define WM_DNSNOTIFY (WM_USER + 51) 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstruct Win32Socket::DnsLookup { 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org HANDLE handle; 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint16 port; 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer[MAXGETHOSTSTRUCT]; 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass Win32Socket::EventSink : public Win32Window { 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org explicit EventSink(Win32Socket * parent) : parent_(parent) { } 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void Dispose(); 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LRESULT& result); 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org virtual void OnNcDestroy(); 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private: 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result); 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result); 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Win32Socket * parent_; 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::EventSink::Dispose() { 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org parent_ = NULL; 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (::IsWindow(handle())) { 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ::DestroyWindow(handle()); 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete this; 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam, 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPARAM lParam, LRESULT& result) { 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (uMsg) { 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WM_SOCKETNOTIFY: 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WM_TIMER: 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return OnSocketNotify(uMsg, wParam, lParam, result); 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case WM_DNSNOTIFY: 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return OnDnsNotify(wParam, lParam, result); 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam, 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPARAM lParam, LRESULT& result) { 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org result = 0; 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int wsa_event = WSAGETSELECTEVENT(lParam); 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int wsa_error = WSAGETSELECTERROR(lParam); 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Treat connect timeouts as close notifications 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (uMsg == WM_TIMER) { 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org wsa_event = FD_CLOSE; 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org wsa_error = WSAETIMEDOUT; 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (parent_) 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org parent_->OnSocketNotify(static_cast<SOCKET>(wParam), wsa_event, wsa_error); 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam, 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LRESULT& result) { 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org result = 0; 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int error = WSAGETASYNCERROR(lParam); 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (parent_) 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org parent_->OnDnsNotify(reinterpret_cast<HANDLE>(wParam), error); 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::EventSink::OnNcDestroy() { 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (parent_) { 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "EventSink hwnd is being destroyed, but the event sink" 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org " hasn't yet been disposed."; 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete this; 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org///////////////////////////////////////////////////////////////////////////// 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Win32Socket 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org///////////////////////////////////////////////////////////////////////////// 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWin32Socket::Win32Socket() 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED), connect_time_(0), 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org closing_(false), close_error_(0), sink_(NULL), dns_(NULL) { 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWin32Socket::~Win32Socket() { 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::CreateT(int family, int type) { 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int proto = (SOCK_DGRAM == type) ? IPPROTO_UDP : IPPROTO_TCP; 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_ = ::WSASocket(family, type, proto, NULL, NULL, 0); 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket_ == INVALID_SOCKET) { 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((SOCK_DGRAM == type) && !SetAsync(FD_READ | FD_WRITE)) { 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Attach(SOCKET s) { 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(socket_ == INVALID_SOCKET); 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket_ != INVALID_SOCKET) 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(s != INVALID_SOCKET); 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (s == INVALID_SOCKET) 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_ = s; 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTED; 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!SetAsync(FD_READ | FD_WRITE | FD_CLOSE)) 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::SetTimeout(int ms) { 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (sink_) 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ::SetTimer(sink_->handle(), 1, ms, 0); 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgSocketAddress Win32Socket::GetLocalAddress() const { 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage addr = {0}; 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socklen_t addrlen = sizeof(addr); 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int result = ::getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org &addrlen); 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddress address; 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (result >= 0) { 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddressFromSockAddrStorage(addr, &address); 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << socket_; 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return address; 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgSocketAddress Win32Socket::GetRemoteAddress() const { 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage addr = {0}; 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socklen_t addrlen = sizeof(addr); 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int result = ::getpeername(socket_, reinterpret_cast<sockaddr*>(&addr), 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org &addrlen); 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddress address; 3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (result >= 0) { 3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddressFromSockAddrStorage(addr, &address); 3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" 3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << socket_; 3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return address; 3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Bind(const SocketAddress& addr) { 3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(socket_ != INVALID_SOCKET); 3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket_ == INVALID_SOCKET) 3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage saddr; 3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len = addr.ToSockAddrStorage(&saddr); 3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int err = ::bind(socket_, 3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<sockaddr*>(&saddr), 3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(len)); 3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return err; 3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Connect(const SocketAddress& addr) { 3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (state_ != CS_CLOSED) { 3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetError(EALREADY); 3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!addr.IsUnresolvedIP()) { 3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return DoConnect(addr); 3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_F(LS_INFO) << "async dns lookup (" << addr.hostname() << ")"; 3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DnsLookup * dns = new DnsLookup; 3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!sink_) { 3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Explicitly create the sink ourselves here; we can't rely on SetAsync 3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // because we don't have a socket_ yet. 3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CreateSink(); 3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO: Replace with IPv6 compatible lookup. 3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY, 3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr.hostname().c_str(), dns->buffer, 3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sizeof(dns->buffer)); 3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!dns->handle) { 3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError(); 3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete dns; 3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dns->port = addr.port(); 3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dns_ = dns; 3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTING; 3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::DoConnect(const SocketAddress& addr) { 3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((socket_ == INVALID_SOCKET) && !CreateT(addr.family(), SOCK_STREAM)) { 3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!SetAsync(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE)) { 3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage saddr = {0}; 3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len = addr.ToSockAddrStorage(&saddr); 3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org connect_time_ = Time(); 3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int result = connect(socket_, 3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<SOCKADDR*>(&saddr), 3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(len)); 3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (result != SOCKET_ERROR) { 3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTED; 3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int code = WSAGetLastError(); 3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (code == WSAEWOULDBLOCK) { 3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTING; 3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 3905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ReportWSAError("WSAAsync:connect", code, addr); 3915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = code; 3925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 3935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 3945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr_ = addr; 3975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 3995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::GetError() const { 4025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return error_; 4035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::SetError(int error) { 4065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = error; 4075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgSocket::ConnState Win32Socket::GetState() const { 4105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return state_; 4115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::GetOption(Option opt, int* value) { 4145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int slevel; 4155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int sopt; 4165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (TranslateOption(opt, &slevel, &sopt) == -1) 4175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 4185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char* p = reinterpret_cast<char*>(value); 4205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int optlen = sizeof(value); 4215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ::getsockopt(socket_, slevel, sopt, p, &optlen); 4225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::SetOption(Option opt, int value) { 4255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int slevel; 4265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int sopt; 4275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (TranslateOption(opt, &slevel, &sopt) == -1) 4285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 4295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* p = reinterpret_cast<const char*>(&value); 4315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ::setsockopt(socket_, slevel, sopt, p, sizeof(value)); 4325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Send(const void* buffer, size_t length) { 4355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int sent = ::send(socket_, 4365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<const char*>(buffer), 4375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(length), 4385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 0); 4395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return sent; 4415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::SendTo(const void* buffer, size_t length, 4445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SocketAddress& addr) { 4455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage saddr; 4465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t addr_len = addr.ToSockAddrStorage(&saddr); 4475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int sent = ::sendto(socket_, reinterpret_cast<const char*>(buffer), 4485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(length), 0, 4495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<sockaddr*>(&saddr), 4505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(addr_len)); 4515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return sent; 4535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Recv(void* buffer, size_t length) { 4565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int received = ::recv(socket_, static_cast<char*>(buffer), 4575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(length), 0); 4585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (closing_ && received <= static_cast<int>(length)) 4605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PostClosed(); 4615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return received; 4625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::RecvFrom(void* buffer, size_t length, 4655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddress* out_addr) { 4665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage saddr; 4675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socklen_t addr_len = sizeof(saddr); 4685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int received = ::recvfrom(socket_, static_cast<char*>(buffer), 4695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(length), 0, 4705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org reinterpret_cast<sockaddr*>(&saddr), &addr_len); 4715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (received != SOCKET_ERROR) 4735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddressFromSockAddrStorage(saddr, out_addr); 4745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (closing_ && received <= static_cast<int>(length)) 4755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PostClosed(); 4765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return received; 4775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Listen(int backlog) { 4805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int err = ::listen(socket_, backlog); 4815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!SetAsync(FD_ACCEPT)) 4825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SOCKET_ERROR; 4835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (err == 0) 4865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTING; 4875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return err; 4885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWin32Socket* Win32Socket::Accept(SocketAddress* out_addr) { 4915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sockaddr_storage saddr; 4925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socklen_t addr_len = sizeof(saddr); 4935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SOCKET s = ::accept(socket_, reinterpret_cast<sockaddr*>(&saddr), &addr_len); 4945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 4955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (s == INVALID_SOCKET) 4965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 4975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (out_addr) 4985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddressFromSockAddrStorage(saddr, out_addr); 4995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Win32Socket* socket = new Win32Socket; 5005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 == socket->Attach(s)) 5015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return socket; 5025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete socket; 5035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 5045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::Close() { 5075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int err = 0; 5085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket_ != INVALID_SOCKET) { 5095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org err = ::closesocket(socket_); 5105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_ = INVALID_SOCKET; 5115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org closing_ = false; 5125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org close_error_ = 0; 5135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 5145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (dns_) { 5165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WSACancelAsyncRequest(dns_->handle); 5175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete dns_; 5185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dns_ = NULL; 5195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (sink_) { 5215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sink_->Dispose(); 5225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sink_ = NULL; 5235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org addr_.Clear(); 5255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CLOSED; 5265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return err; 5275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::EstimateMTU(uint16* mtu) { 5305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddress addr = GetRemoteAddress(); 5315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (addr.IsAny()) { 5325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = ENOTCONN; 5335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 5345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WinPing ping; 5375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ping.IsValid()) { 5385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = EINVAL; // can't think of a better error ID 5395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 5405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { 5435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int32 size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE; 5445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, 5455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ICMP_PING_TIMEOUT_MILLIS, 1, false); 5465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (result == WinPing::PING_FAIL) { 5475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = EINVAL; // can't think of a better error ID 5485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 5495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (result != WinPing::PING_TOO_LARGE) { 5515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *mtu = PACKET_MAXIMUMS[level]; 5525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 5535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 5575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 5585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::CreateSink() { 5615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(NULL == sink_); 5625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Create window 5645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sink_ = new EventSink(this); 5655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sink_->Create(NULL, L"EventSink", 0, 0, 0, 0, 10, 10); 5665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::SetAsync(int events) { 5695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == sink_) { 5705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CreateSink(); 5715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(NULL != sink_); 5725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // start the async select 5755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (WSAAsyncSelect(socket_, sink_->handle(), WM_SOCKETNOTIFY, events) 5765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org == SOCKET_ERROR) { 5775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UpdateLastError(); 5785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 5795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 5805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 5835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32Socket::HandleClosed(int close_error) { 5865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // WM_CLOSE will be received before all data has been read, so we need to 5875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // hold on to it until the read buffer has been drained. 5885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char ch; 5895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org closing_ = true; 5905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org close_error_ = close_error; 5915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return (::recv(socket_, &ch, 1, MSG_PEEK) <= 0); 5925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::PostClosed() { 5955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If we see that the buffer is indeed drained, then send the close. 5965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org closing_ = false; 5975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY, 5985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org socket_, WSAMAKESELECTREPLY(FD_CLOSE, close_error_)); 5995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 6005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::UpdateLastError() { 6025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = WSAGetLastError(); 6035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 6045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint Win32Socket::TranslateOption(Option opt, int* slevel, int* sopt) { 6065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (opt) { 6075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case OPT_DONTFRAGMENT: 6085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *slevel = IPPROTO_IP; 6095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *sopt = IP_DONTFRAGMENT; 6105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case OPT_RCVBUF: 6125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *slevel = SOL_SOCKET; 6135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *sopt = SO_RCVBUF; 6145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case OPT_SNDBUF: 6165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *slevel = SOL_SOCKET; 6175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *sopt = SO_SNDBUF; 6185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case OPT_NODELAY: 6205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *slevel = IPPROTO_TCP; 6215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *sopt = TCP_NODELAY; 6225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org default: 6245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 6255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return -1; 6265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return 0; 6285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 6295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::OnSocketNotify(SOCKET socket, int event, int error) { 6315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Ignore events if we're already closed. 6325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket != socket_) 6335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 6345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = error; 6365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (event) { 6375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FD_CONNECT: 6385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error != ERROR_SUCCESS) { 6395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ReportWSAError("WSAAsync:connect notify", error, addr_); 6405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef _DEBUG 6415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int32 duration = TimeSince(connect_time_); 6425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "WSAAsync:connect error (" << duration 6435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " ms), faking close"; 6445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 6455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CLOSED; 6465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If you get an error connecting, close doesn't really do anything 6475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // and it certainly doesn't send back any close notification, but 6485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // we really only maintain a few states, so it is easiest to get 6495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // back into a known state by pretending that a close happened, even 6505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // though the connect event never did occur. 6515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalCloseEvent(this, error); 6525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 6535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef _DEBUG 6545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int32 duration = TimeSince(connect_time_); 6555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "WSAAsync:connect (" << duration << " ms)"; 6565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 6575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CONNECTED; 6585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalConnectEvent(this); 6595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FD_ACCEPT: 6635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FD_READ: 6645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error != ERROR_SUCCESS) { 6655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ReportWSAError("WSAAsync:read notify", error, addr_); 6665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 6675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalReadEvent(this); 6685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FD_WRITE: 6725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error != ERROR_SUCCESS) { 6735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ReportWSAError("WSAAsync:write notify", error, addr_); 6745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 6755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalWriteEvent(this); 6765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FD_CLOSE: 6805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (HandleClosed(error)) { 6815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ReportWSAError("WSAAsync:close notify", error, addr_); 6825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state_ = CS_CLOSED; 6835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalCloseEvent(this, error); 6845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 6865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 6885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32Socket::OnDnsNotify(HANDLE task, int error) { 6905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!dns_ || dns_->handle != task) 6915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 6925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 ip = 0; 6945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error == 0) { 6955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org hostent* pHost = reinterpret_cast<hostent*>(dns_->buffer); 6965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 net_ip = *reinterpret_cast<uint32*>(pHost->h_addr_list[0]); 6975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ip = NetworkToHost32(net_ip); 6985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_F(LS_INFO) << "(" << IPAddress(ip).ToSensitiveString() 7015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << ", " << error << ")"; 7025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error == 0) { 7045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SocketAddress address(ip, dns_->port); 7055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error = DoConnect(address); 7065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 7075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Close(); 7085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error) { 7115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org error_ = error; 7125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalCloseEvent(this, error_); 7135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 7145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete dns_; 7155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dns_ = NULL; 7165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 7205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Win32SocketServer 7215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Provides cricket base services on top of a win32 gui thread 7225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/////////////////////////////////////////////////////////////////////////////// 7235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic UINT s_wm_wakeup_id = 0; 7255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst TCHAR Win32SocketServer::kWindowName[] = L"libjingle Message Window"; 7265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWin32SocketServer::Win32SocketServer(MessageQueue* message_queue) 7285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org : message_queue_(message_queue), 7295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org wnd_(this), 7305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org posted_(false), 7315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org hdlg_(NULL) { 7325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (s_wm_wakeup_id == 0) 7335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org s_wm_wakeup_id = RegisterWindowMessage(L"WM_WAKEUP"); 7345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!wnd_.Create(NULL, kWindowName, 0, 0, 0, 0, 0, 0)) { 7355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_GLE(LS_ERROR) << "Failed to create message window."; 7365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWin32SocketServer::~Win32SocketServer() { 7405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (wnd_.handle() != NULL) { 7415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KillTimer(wnd_.handle(), 1); 7425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org wnd_.Destroy(); 7435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgSocket* Win32SocketServer::CreateSocket(int type) { 7475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return CreateSocket(AF_INET, type); 7485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgSocket* Win32SocketServer::CreateSocket(int family, int type) { 7515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return CreateAsyncSocket(family, type); 7525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgAsyncSocket* Win32SocketServer::CreateAsyncSocket(int type) { 7555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return CreateAsyncSocket(AF_INET, type); 7565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgAsyncSocket* Win32SocketServer::CreateAsyncSocket(int family, int type) { 7595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Win32Socket* socket = new Win32Socket; 7605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (socket->CreateT(family, type)) { 7615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return socket; 7625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete socket; 7645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 7655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32SocketServer::SetMessageQueue(MessageQueue* queue) { 7685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org message_queue_ = queue; 7695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32SocketServer::Wait(int cms, bool process_io) { 7725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org BOOL b; 7735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (process_io) { 7745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Spin the Win32 message pump at least once, and as long as requested. 7755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This is the Thread::ProcessMessages case. 7765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 start = Time(); 7775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org do { 7785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org MSG msg; 7795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetTimer(wnd_.handle(), 0, cms, NULL); 7805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Get the next available message. If we have a modeless dialog, give 7815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // give the message to IsDialogMessage, which will return true if it 7825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // was a message for the dialog that it handled internally. 7835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Otherwise, dispatch as usual via Translate/DispatchMessage. 7845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org b = GetMessage(&msg, NULL, 0, 0); 7855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (b == -1) { 7865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_GLE(LS_ERROR) << "GetMessage failed."; 7875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if(b) { 7895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!hdlg_ || !IsDialogMessage(hdlg_, &msg)) { 7905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org TranslateMessage(&msg); 7915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DispatchMessage(&msg); 7925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KillTimer(wnd_.handle(), 0); 7955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } while (b && TimeSince(start) < cms); 7965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (cms != 0) { 7975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Sit and wait forever for a WakeUp. This is the Thread::Send case. 7985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(cms == -1); 7995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org MSG msg; 8005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org b = GetMessage(&msg, NULL, s_wm_wakeup_id, s_wm_wakeup_id); 8015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { 8025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CritScope scope(&cs_); 8035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org posted_ = false; 8045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 8065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // No-op (cms == 0 && !process_io). This is the Pump case. 8075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org b = TRUE; 8085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return (b != FALSE); 8105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32SocketServer::WakeUp() { 8135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (wnd_.handle()) { 8145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Set the "message pending" flag, if not already set. 8155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { 8165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CritScope scope(&cs_); 8175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (posted_) 8185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org posted_ = true; 8205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PostMessage(wnd_.handle(), s_wm_wakeup_id, 0, 0); 8235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid Win32SocketServer::Pump() { 8275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Clear the "message pending" flag. 8285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org { 8295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CritScope scope(&cs_); 8305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org posted_ = false; 8315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Dispatch all the messages that are currently in our queue. If new messages 8345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // are posted during the dispatch, they will be handled in the next Pump. 8355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // We use max(1, ...) to make sure we try to dispatch at least once, since 8365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // this allow us to process "sent" messages, not included in the size() count. 8375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Message msg; 8385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t max_messages_to_process = _max<size_t>(1, message_queue_->size()); 8395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org max_messages_to_process > 0 && message_queue_->Get(&msg, 0, false); 8405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org --max_messages_to_process) { 8415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org message_queue_->Dispatch(&msg); 8425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Anything remaining? 8455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int delay = message_queue_->GetDelay(); 8465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (delay == -1) { 8475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org KillTimer(wnd_.handle(), 1); 8485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 8495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetTimer(wnd_.handle(), 1, delay, NULL); 8505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool Win32SocketServer::MessageWindow::OnMessage(UINT wm, WPARAM wp, 8545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LPARAM lp, LRESULT& lr) { 8555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool handled = false; 8565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (wm == s_wm_wakeup_id || (wm == WM_TIMER && wp == 1)) { 8575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ss_->Pump(); 8585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org lr = 0; 8595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org handled = true; 8605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return handled; 8625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace talk_base 865