1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/win32socketserver.h" 12ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org 13ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include <algorithm> 14ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include <ws2tcpip.h> // NOLINT 15ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org 16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/byteorder.h" 17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h" 18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h" 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/win32window.h" 20ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org#include "webrtc/base/winping.h" 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc { 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Win32Socket 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// TODO: Move this to a common place where PhysicalSocketServer can 29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// share it. 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Standard MTUs 310c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmstatic const uint16_t PACKET_MAXIMUMS[] = { 320c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 65535, // Theoretical maximum, Hyperchannel 330c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 32000, // Nothing 340c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 17914, // 16Mb IBM Token Ring 350c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 8166, // IEEE 802.4 360c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 4464 // IEEE 802.5 (4Mb max) 370c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 4352, // FDDI 380c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 2048, // Wideband Network 390c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 2002, // IEEE 802.5 (4Mb recommended) 400c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 1536, // Expermental Ethernet Networks 410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 1500, // Ethernet, Point-to-Point (default) 420c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 1492, // IEEE 802.3 430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 1006, // SLIP, ARPANET 440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 576, // X.25 Networks 450c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 544, // DEC IP Portal 460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström // 512, // NETBIOS 470c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 508, // IEEE 802/Source-Rt Bridge, ARCNET 480c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 296, // Point-to-Point (low delay) 490c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 68, // Official minimum 500c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström 0, // End of list marker 51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const int IP_HEADER_SIZE = 20u; 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const int ICMP_HEADER_SIZE = 8u; 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const int ICMP_PING_TIMEOUT_MILLIS = 10000u; 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// TODO: Enable for production builds also? Use FormatMessage? 58a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG) 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgLPCSTR WSAErrorToString(int error, LPCSTR *description_result) { 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPCSTR string = "Unspecified"; 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPCSTR description = "Unspecified description"; 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (error) { 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case ERROR_SUCCESS: 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "SUCCESS"; 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Operation succeeded"; 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAEWOULDBLOCK: 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAEWOULDBLOCK"; 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Using a non-blocking socket, will notify later"; 70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAEACCES: 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAEACCES"; 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Access denied, or sharing violation"; 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAEADDRNOTAVAIL: 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAEADDRNOTAVAIL"; 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Address is not valid in this context"; 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAENETDOWN: 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAENETDOWN"; 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Network is down"; 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAENETUNREACH: 84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAENETUNREACH"; 85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Network is up, but unreachable"; 86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAENETRESET: 88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSANETRESET"; 89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Connection has been reset due to keep-alive activity"; 90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAECONNABORTED: 92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAECONNABORTED"; 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Aborted by host"; 94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAECONNRESET: 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAECONNRESET"; 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Connection reset by host"; 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAETIMEDOUT: 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAETIMEDOUT"; 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Timed out, host failed to respond"; 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAECONNREFUSED: 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAECONNREFUSED"; 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Host actively refused connection"; 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAEHOSTDOWN: 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAEHOSTDOWN"; 109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Host is down"; 110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAEHOSTUNREACH: 112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAEHOSTUNREACH"; 113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "Host is unreachable"; 114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WSAHOST_NOT_FOUND: 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org string = "WSAHOST_NOT_FOUND"; 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org description = "No such host is known"; 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (description_result) { 121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *description_result = description; 122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return string; 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid ReportWSAError(LPCSTR context, int error, const SocketAddress& address) { 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPCSTR description_string; 128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPCSTR error_string = WSAErrorToString(error, &description_string); 129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_INFO) << context << " = " << error 130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << " (" << error_string << ":" << description_string << ") [" 131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << address.ToString() << "]"; 132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else 134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid ReportWSAError(LPCSTR context, int error, const SocketAddress& address) {} 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Win32Socket::EventSink 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define WM_SOCKETNOTIFY (WM_USER + 50) 142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define WM_DNSNOTIFY (WM_USER + 51) 143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct Win32Socket::DnsLookup { 145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HANDLE handle; 1460c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t port; 147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char buffer[MAXGETHOSTSTRUCT]; 148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass Win32Socket::EventSink : public Win32Window { 151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org explicit EventSink(Win32Socket * parent) : parent_(parent) { } 153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void Dispose(); 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, 157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LRESULT& result); 158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual void OnNcDestroy(); 159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private: 161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result); 162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result); 163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Win32Socket * parent_; 165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::EventSink::Dispose() { 168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org parent_ = NULL; 169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (::IsWindow(handle())) { 170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ::DestroyWindow(handle()); 171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete this; 173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam, 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPARAM lParam, LRESULT& result) { 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (uMsg) { 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WM_SOCKETNOTIFY: 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WM_TIMER: 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return OnSocketNotify(uMsg, wParam, lParam, result); 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case WM_DNSNOTIFY: 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return OnDnsNotify(wParam, lParam, result); 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam, 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPARAM lParam, LRESULT& result) { 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org result = 0; 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int wsa_event = WSAGETSELECTEVENT(lParam); 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int wsa_error = WSAGETSELECTERROR(lParam); 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Treat connect timeouts as close notifications 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (uMsg == WM_TIMER) { 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wsa_event = FD_CLOSE; 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wsa_error = WSAETIMEDOUT; 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (parent_) 202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org parent_->OnSocketNotify(static_cast<SOCKET>(wParam), wsa_event, wsa_error); 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam, 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LRESULT& result) { 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org result = 0; 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int error = WSAGETASYNCERROR(lParam); 211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (parent_) 212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org parent_->OnDnsNotify(reinterpret_cast<HANDLE>(wParam), error); 213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::EventSink::OnNcDestroy() { 217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (parent_) { 218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_ERROR) << "EventSink hwnd is being destroyed, but the event sink" 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org " hasn't yet been disposed."; 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete this; 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Win32Socket 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org///////////////////////////////////////////////////////////////////////////// 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWin32Socket::Win32Socket() 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED), connect_time_(0), 231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org closing_(false), close_error_(0), sink_(NULL), dns_(NULL) { 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWin32Socket::~Win32Socket() { 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::CreateT(int family, int type) { 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int proto = (SOCK_DGRAM == type) ? IPPROTO_UDP : IPPROTO_TCP; 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_ = ::WSASocket(family, type, proto, NULL, NULL, 0); 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket_ == INVALID_SOCKET) { 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((SOCK_DGRAM == type) && !SetAsync(FD_READ | FD_WRITE)) { 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Attach(SOCKET s) { 253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(socket_ == INVALID_SOCKET); 254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket_ != INVALID_SOCKET) 255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(s != INVALID_SOCKET); 258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (s == INVALID_SOCKET) 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_ = s; 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTED; 263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!SetAsync(FD_READ | FD_WRITE | FD_CLOSE)) 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::SetTimeout(int ms) { 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (sink_) 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ::SetTimer(sink_->handle(), 1, ms, 0); 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocketAddress Win32Socket::GetLocalAddress() const { 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage addr = {0}; 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socklen_t addrlen = sizeof(addr); 278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int result = ::getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &addrlen); 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress address; 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result >= 0) { 282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddressFromSockAddrStorage(addr, &address); 283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_WARNING) << "GetLocalAddress: unable to get local addr, socket=" 285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << socket_; 286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return address; 288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocketAddress Win32Socket::GetRemoteAddress() const { 291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage addr = {0}; 292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socklen_t addrlen = sizeof(addr); 293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int result = ::getpeername(socket_, reinterpret_cast<sockaddr*>(&addr), 294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &addrlen); 295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress address; 296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result >= 0) { 297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddressFromSockAddrStorage(addr, &address); 298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_WARNING) << "GetRemoteAddress: unable to get remote addr, socket=" 300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << socket_; 301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return address; 303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Bind(const SocketAddress& addr) { 306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(socket_ != INVALID_SOCKET); 307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket_ == INVALID_SOCKET) 308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage saddr; 311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t len = addr.ToSockAddrStorage(&saddr); 312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int err = ::bind(socket_, 313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<sockaddr*>(&saddr), 314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(len)); 315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return err; 317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Connect(const SocketAddress& addr) { 320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (state_ != CS_CLOSED) { 321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetError(EALREADY); 322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!addr.IsUnresolvedIP()) { 326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return DoConnect(addr); 327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_F(LS_INFO) << "async dns lookup (" << addr.hostname() << ")"; 330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DnsLookup * dns = new DnsLookup; 331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!sink_) { 332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Explicitly create the sink ourselves here; we can't rely on SetAsync 333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // because we don't have a socket_ yet. 334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CreateSink(); 335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Replace with IPv6 compatible lookup. 337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY, 338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addr.hostname().c_str(), dns->buffer, 339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sizeof(dns->buffer)); 340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!dns->handle) { 342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError(); 343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete dns; 344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dns->port = addr.port(); 350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dns_ = dns; 351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTING; 352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::DoConnect(const SocketAddress& addr) { 356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((socket_ == INVALID_SOCKET) && !CreateT(addr.family(), SOCK_STREAM)) { 357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!SetAsync(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE)) { 360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage saddr = {0}; 364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t len = addr.ToSockAddrStorage(&saddr); 365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org connect_time_ = Time(); 366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int result = connect(socket_, 367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<SOCKADDR*>(&saddr), 368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(len)); 369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result != SOCKET_ERROR) { 370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTED; 371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int code = WSAGetLastError(); 373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (code == WSAEWOULDBLOCK) { 374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTING; 375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ReportWSAError("WSAAsync:connect", code, addr); 377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = code; 378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addr_ = addr; 383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::GetError() const { 388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return error_; 389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::SetError(int error) { 392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = error; 393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket::ConnState Win32Socket::GetState() const { 396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return state_; 397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::GetOption(Option opt, int* value) { 400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int slevel; 401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int sopt; 402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (TranslateOption(opt, &slevel, &sopt) == -1) 403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* p = reinterpret_cast<char*>(value); 406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int optlen = sizeof(value); 407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ::getsockopt(socket_, slevel, sopt, p, &optlen); 408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::SetOption(Option opt, int value) { 411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int slevel; 412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int sopt; 413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (TranslateOption(opt, &slevel, &sopt) == -1) 414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* p = reinterpret_cast<const char*>(&value); 417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ::setsockopt(socket_, slevel, sopt, p, sizeof(value)); 418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Send(const void* buffer, size_t length) { 421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int sent = ::send(socket_, 422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<const char*>(buffer), 423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(length), 424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 0); 425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return sent; 427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::SendTo(const void* buffer, size_t length, 430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& addr) { 431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage saddr; 432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org size_t addr_len = addr.ToSockAddrStorage(&saddr); 433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int sent = ::sendto(socket_, reinterpret_cast<const char*>(buffer), 434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(length), 0, 435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<sockaddr*>(&saddr), 436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(addr_len)); 437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return sent; 439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Recv(void* buffer, size_t length) { 442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int received = ::recv(socket_, static_cast<char*>(buffer), 443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(length), 0); 444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (closing_ && received <= static_cast<int>(length)) 446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org PostClosed(); 447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return received; 448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::RecvFrom(void* buffer, size_t length, 451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress* out_addr) { 452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage saddr; 453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socklen_t addr_len = sizeof(saddr); 454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int received = ::recvfrom(socket_, static_cast<char*>(buffer), 455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(length), 0, 456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<sockaddr*>(&saddr), &addr_len); 457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (received != SOCKET_ERROR) 459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddressFromSockAddrStorage(saddr, out_addr); 460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (closing_ && received <= static_cast<int>(length)) 461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org PostClosed(); 462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return received; 463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Listen(int backlog) { 466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int err = ::listen(socket_, backlog); 467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!SetAsync(FD_ACCEPT)) 468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return SOCKET_ERROR; 469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (err == 0) 472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTING; 473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return err; 474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWin32Socket* Win32Socket::Accept(SocketAddress* out_addr) { 477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sockaddr_storage saddr; 478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socklen_t addr_len = sizeof(saddr); 479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SOCKET s = ::accept(socket_, reinterpret_cast<sockaddr*>(&saddr), &addr_len); 480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (s == INVALID_SOCKET) 482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (out_addr) 484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddressFromSockAddrStorage(saddr, out_addr); 485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Win32Socket* socket = new Win32Socket; 486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (0 == socket->Attach(s)) 487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return socket; 488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete socket; 489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::Close() { 493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int err = 0; 494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket_ != INVALID_SOCKET) { 495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org err = ::closesocket(socket_); 496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_ = INVALID_SOCKET; 497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org closing_ = false; 498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org close_error_ = 0; 499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (dns_) { 502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org WSACancelAsyncRequest(dns_->handle); 503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete dns_; 504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dns_ = NULL; 505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (sink_) { 507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sink_->Dispose(); 508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sink_ = NULL; 509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addr_.Clear(); 511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CLOSED; 512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return err; 513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 5150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmint Win32Socket::EstimateMTU(uint16_t* mtu) { 516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress addr = GetRemoteAddress(); 5178ac544e811439f79b2ec0c676f383ddc51ef2ed5tfarina if (addr.IsAnyIP()) { 518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = ENOTCONN; 519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org WinPing ping; 523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!ping.IsValid()) { 524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = EINVAL; // can't think of a better error ID 525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) { 5290c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int32_t size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE; 530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org WinPing::PingResult result = ping.Ping(addr.ipaddr(), size, 531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ICMP_PING_TIMEOUT_MILLIS, 1, false); 532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result == WinPing::PING_FAIL) { 533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = EINVAL; // can't think of a better error ID 534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (result != WinPing::PING_TOO_LARGE) { 537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *mtu = PACKET_MAXIMUMS[level]; 538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(false); 543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::CreateSink() { 547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(NULL == sink_); 548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create window 550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sink_ = new EventSink(this); 551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org sink_->Create(NULL, L"EventSink", 0, 0, 0, 0, 10, 10); 552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::SetAsync(int events) { 555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (NULL == sink_) { 556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CreateSink(); 557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(NULL != sink_); 558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // start the async select 561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (WSAAsyncSelect(socket_, sink_->handle(), WM_SOCKETNOTIFY, events) 562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org == SOCKET_ERROR) { 563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org UpdateLastError(); 564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32Socket::HandleClosed(int close_error) { 572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // WM_CLOSE will be received before all data has been read, so we need to 573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // hold on to it until the read buffer has been drained. 574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char ch; 575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org closing_ = true; 576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org close_error_ = close_error; 577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return (::recv(socket_, &ch, 1, MSG_PEEK) <= 0); 578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::PostClosed() { 581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // If we see that the buffer is indeed drained, then send the close. 582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org closing_ = false; 583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY, 584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_, WSAMAKESELECTREPLY(FD_CLOSE, close_error_)); 585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 586f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::UpdateLastError() { 588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = WSAGetLastError(); 589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint Win32Socket::TranslateOption(Option opt, int* slevel, int* sopt) { 592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (opt) { 593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case OPT_DONTFRAGMENT: 594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *slevel = IPPROTO_IP; 595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *sopt = IP_DONTFRAGMENT; 596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case OPT_RCVBUF: 598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *slevel = SOL_SOCKET; 599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *sopt = SO_RCVBUF; 600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case OPT_SNDBUF: 602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *slevel = SOL_SOCKET; 603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *sopt = SO_SNDBUF; 604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case OPT_NODELAY: 606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *slevel = IPPROTO_TCP; 607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *sopt = TCP_NODELAY; 608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case OPT_DSCP: 610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_WARNING) << "Socket::OPT_DSCP not supported."; 611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org default: 613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(false); 614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::OnSocketNotify(SOCKET socket, int event, int error) { 620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Ignore events if we're already closed. 621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket != socket_) 622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = error; 625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (event) { 626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case FD_CONNECT: 627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error != ERROR_SUCCESS) { 628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ReportWSAError("WSAAsync:connect notify", error, addr_); 629a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG) 6300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int32_t duration = TimeSince(connect_time_); 631f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_INFO) << "WSAAsync:connect error (" << duration 632f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << " ms), faking close"; 633f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 634f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CLOSED; 635f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // If you get an error connecting, close doesn't really do anything 636f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // and it certainly doesn't send back any close notification, but 637f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // we really only maintain a few states, so it is easiest to get 638f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // back into a known state by pretending that a close happened, even 639f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // though the connect event never did occur. 640f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error); 641f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 642a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG) 6430c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int32_t duration = TimeSince(connect_time_); 644f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG(LS_INFO) << "WSAAsync:connect (" << duration << " ms)"; 645f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 646f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CONNECTED; 647f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalConnectEvent(this); 648f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 651f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case FD_ACCEPT: 652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case FD_READ: 653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error != ERROR_SUCCESS) { 654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ReportWSAError("WSAAsync:read notify", error, addr_); 655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalReadEvent(this); 657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case FD_WRITE: 661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error != ERROR_SUCCESS) { 662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ReportWSAError("WSAAsync:write notify", error, addr_); 663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalWriteEvent(this); 665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case FD_CLOSE: 669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (HandleClosed(error)) { 670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ReportWSAError("WSAAsync:close notify", error, addr_); 671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org state_ = CS_CLOSED; 672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error); 673f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org break; 675f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32Socket::OnDnsNotify(HANDLE task, int error) { 679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!dns_ || dns_->handle != task) 680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 6820c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ip = 0; 683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error == 0) { 684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org hostent* pHost = reinterpret_cast<hostent*>(dns_->buffer); 6850c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t net_ip = *reinterpret_cast<uint32_t*>(pHost->h_addr_list[0]); 686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ip = NetworkToHost32(net_ip); 687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_F(LS_INFO) << "(" << IPAddress(ip).ToSensitiveString() 690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org << ", " << error << ")"; 691f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error == 0) { 693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress address(ip, dns_->port); 694f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error = DoConnect(address); 695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Close(); 697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 698f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 699f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (error) { 700f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org error_ = error; 701f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalCloseEvent(this, error_); 702f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 703f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete dns_; 704f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org dns_ = NULL; 705f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 706f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 707f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 708f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 709f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Win32SocketServer 710f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Provides cricket base services on top of a win32 gui thread 711f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 712f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 713f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic UINT s_wm_wakeup_id = 0; 714f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst TCHAR Win32SocketServer::kWindowName[] = L"libjingle Message Window"; 715f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 716f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWin32SocketServer::Win32SocketServer(MessageQueue* message_queue) 717f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : message_queue_(message_queue), 718f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wnd_(this), 719f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org posted_(false), 720f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org hdlg_(NULL) { 721f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (s_wm_wakeup_id == 0) 722f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org s_wm_wakeup_id = RegisterWindowMessage(L"WM_WAKEUP"); 723f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!wnd_.Create(NULL, kWindowName, 0, 0, 0, 0, 0, 0)) { 724f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_GLE(LS_ERROR) << "Failed to create message window."; 725f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 726f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 727f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 728f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgWin32SocketServer::~Win32SocketServer() { 729f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (wnd_.handle() != NULL) { 730f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org KillTimer(wnd_.handle(), 1); 731f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wnd_.Destroy(); 732f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 733f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 734f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 735f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* Win32SocketServer::CreateSocket(int type) { 736f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CreateSocket(AF_INET, type); 737f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 738f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 739f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* Win32SocketServer::CreateSocket(int family, int type) { 740f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CreateAsyncSocket(family, type); 741f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 742f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 743f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* Win32SocketServer::CreateAsyncSocket(int type) { 744f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return CreateAsyncSocket(AF_INET, type); 745f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 746f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 747f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* Win32SocketServer::CreateAsyncSocket(int family, int type) { 748f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Win32Socket* socket = new Win32Socket; 749f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (socket->CreateT(family, type)) { 750f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return socket; 751f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 752f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete socket; 753f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 754f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 755f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 756f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32SocketServer::SetMessageQueue(MessageQueue* queue) { 757f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org message_queue_ = queue; 758f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 759f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 760f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32SocketServer::Wait(int cms, bool process_io) { 761f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org BOOL b; 762f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (process_io) { 763f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Spin the Win32 message pump at least once, and as long as requested. 764f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // This is the Thread::ProcessMessages case. 7650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t start = Time(); 766f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org do { 767f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MSG msg; 768f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetTimer(wnd_.handle(), 0, cms, NULL); 769f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Get the next available message. If we have a modeless dialog, give 770f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // give the message to IsDialogMessage, which will return true if it 771f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // was a message for the dialog that it handled internally. 772f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Otherwise, dispatch as usual via Translate/DispatchMessage. 773f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org b = GetMessage(&msg, NULL, 0, 0); 774f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (b == -1) { 775f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LOG_GLE(LS_ERROR) << "GetMessage failed."; 776f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 777f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if(b) { 778f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!hdlg_ || !IsDialogMessage(hdlg_, &msg)) { 779f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org TranslateMessage(&msg); 780f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DispatchMessage(&msg); 781f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 782f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 783f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org KillTimer(wnd_.handle(), 0); 784f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } while (b && TimeSince(start) < cms); 785f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (cms != 0) { 786f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Sit and wait forever for a WakeUp. This is the Thread::Send case. 787f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(cms == -1); 788f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MSG msg; 789f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org b = GetMessage(&msg, NULL, s_wm_wakeup_id, s_wm_wakeup_id); 790f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 791f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CritScope scope(&cs_); 792f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org posted_ = false; 793f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 794f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 795f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // No-op (cms == 0 && !process_io). This is the Pump case. 796f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org b = TRUE; 797f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 798f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return (b != FALSE); 799f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 800f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 801f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32SocketServer::WakeUp() { 802f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (wnd_.handle()) { 803f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Set the "message pending" flag, if not already set. 804f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 805f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CritScope scope(&cs_); 806f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (posted_) 807f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return; 808f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org posted_ = true; 809f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 810f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 811f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org PostMessage(wnd_.handle(), s_wm_wakeup_id, 0, 0); 812f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 813f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 814f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 815f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid Win32SocketServer::Pump() { 816f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Clear the "message pending" flag. 817f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 818f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CritScope scope(&cs_); 819f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org posted_ = false; 820f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 821f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 822f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Dispatch all the messages that are currently in our queue. If new messages 823f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // are posted during the dispatch, they will be handled in the next Pump. 824f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // We use max(1, ...) to make sure we try to dispatch at least once, since 825f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // this allow us to process "sent" messages, not included in the size() count. 826f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Message msg; 827ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org for (size_t max_messages_to_process = 828ff689be3c0c59c1be29aaa0697aa0f762566d6c6andresp@webrtc.org std::max<size_t>(1, message_queue_->size()); 829f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org max_messages_to_process > 0 && message_queue_->Get(&msg, 0, false); 830f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org --max_messages_to_process) { 831f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org message_queue_->Dispatch(&msg); 832f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 833f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 834f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Anything remaining? 835f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int delay = message_queue_->GetDelay(); 836f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (delay == -1) { 837f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org KillTimer(wnd_.handle(), 1); 838f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 839f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetTimer(wnd_.handle(), 1, delay, NULL); 840f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 841f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 842f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 843f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Win32SocketServer::MessageWindow::OnMessage(UINT wm, WPARAM wp, 844f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org LPARAM lp, LRESULT& lr) { 845f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool handled = false; 846f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (wm == s_wm_wakeup_id || (wm == WM_TIMER && wp == 1)) { 847f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ss_->Pump(); 848f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org lr = 0; 849f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org handled = true; 850f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 851f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return handled; 852f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 853f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 854f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} // namespace rtc 855