Deleted unused method EstimateMTU, and the WinPing class.

BUG=None

Review-Url: https://codereview.webrtc.org/2866183004
Cr-Commit-Position: refs/heads/master@{#18077}
This commit is contained in:
nisse
2017-05-10 01:56:54 -07:00
committed by Commit bot
parent e0308bb54a
commit e077ee472a
15 changed files with 0 additions and 631 deletions

View File

@ -611,8 +611,6 @@ rtc_static_library("rtc_base") {
"win32securityerrors.cc",
"win32window.cc",
"win32window.h",
"winping.cc",
"winping.h",
]
libs += [

View File

@ -100,10 +100,6 @@ AsyncSocket::ConnState AsyncSocketAdapter::GetState() const {
return socket_->GetState();
}
int AsyncSocketAdapter::EstimateMTU(uint16_t* mtu) {
return socket_->EstimateMTU(mtu);
}
int AsyncSocketAdapter::GetOption(Option opt, int* value) {
return socket_->GetOption(opt, value);
}

View File

@ -66,7 +66,6 @@ class AsyncSocketAdapter : public AsyncSocket, public sigslot::has_slots<> {
int GetError() const override;
void SetError(int error) override;
ConnState GetState() const override;
int EstimateMTU(uint16_t* mtu) override;
int GetOption(Option opt, int* value) override;
int SetOption(Option opt, int value) override;

View File

@ -230,7 +230,6 @@ class NATSocket : public AsyncSocket, public sigslot::has_slots<> {
ConnState GetState() const override {
return connected_ ? CS_CONNECTED : CS_CLOSED;
}
int EstimateMTU(uint16_t* mtu) override { return socket_->EstimateMTU(mtu); }
int GetOption(Option opt, int* value) override {
return socket_->GetOption(opt, value);
}

View File

@ -47,7 +47,6 @@
#include "webrtc/base/networkmonitor.h"
#include "webrtc/base/nullsocketserver.h"
#include "webrtc/base/timeutils.h"
#include "webrtc/base/winping.h"
#include "webrtc/base/win32socketinit.h"
#if defined(WEBRTC_POSIX)
@ -472,70 +471,6 @@ int PhysicalSocket::Close() {
return err;
}
int PhysicalSocket::EstimateMTU(uint16_t* mtu) {
SocketAddress addr = GetRemoteAddress();
if (addr.IsAnyIP()) {
SetError(ENOTCONN);
return -1;
}
#if defined(WEBRTC_WIN)
// Gets the interface MTU (TTL=1) for the interface used to reach |addr|.
WinPing ping;
if (!ping.IsValid()) {
SetError(EINVAL); // can't think of a better error ID
return -1;
}
int header_size = ICMP_HEADER_SIZE;
if (addr.family() == AF_INET6) {
header_size += IPV6_HEADER_SIZE;
} else if (addr.family() == AF_INET) {
header_size += IP_HEADER_SIZE;
}
for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
int32_t size = PACKET_MAXIMUMS[level] - header_size;
WinPing::PingResult result = ping.Ping(addr.ipaddr(), size,
ICMP_PING_TIMEOUT_MILLIS,
1, false);
if (result == WinPing::PING_FAIL) {
SetError(EINVAL); // can't think of a better error ID
return -1;
} else if (result != WinPing::PING_TOO_LARGE) {
*mtu = PACKET_MAXIMUMS[level];
return 0;
}
}
RTC_NOTREACHED();
return -1;
#elif defined(WEBRTC_MAC)
// No simple way to do this on Mac OS X.
// SIOCGIFMTU would work if we knew which interface would be used, but
// figuring that out is pretty complicated. For now we'll return an error
// and let the caller pick a default MTU.
SetError(EINVAL);
return -1;
#elif defined(WEBRTC_LINUX)
// Gets the path MTU.
int value;
socklen_t vlen = sizeof(value);
int err = getsockopt(s_, IPPROTO_IP, IP_MTU, &value, &vlen);
if (err < 0) {
UpdateLastError();
return err;
}
RTC_DCHECK((0 <= value) && (value <= 65536));
*mtu = value;
return 0;
#elif defined(__native_client__)
// Most socket operations, including this, will fail in NaCl's sandbox.
error_ = EACCES;
return -1;
#endif
}
SOCKET PhysicalSocket::DoAccept(SOCKET socket,
sockaddr* addr,
socklen_t* addrlen) {

View File

@ -151,8 +151,6 @@ class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
int Close() override;
int EstimateMTU(uint16_t* mtu) override;
SocketServer* socketserver() { return ss_; }
protected:

View File

@ -171,11 +171,6 @@ class Socket {
};
virtual ConnState GetState() const = 0;
// Fills in the given uint16_t with the current estimate of the MTU along the
// path to the address to which this socket is connected. NOTE: This method
// can block for up to 10 seconds on Windows.
virtual int EstimateMTU(uint16_t* mtu) = 0;
enum Option {
OPT_DONTFRAGMENT,
OPT_RCVBUF, // receive buffer size

View File

@ -1013,30 +1013,6 @@ void SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
int current_nd, desired_nd = 1;
ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
// Skip the esimate MTU test for IPv6 for now.
if (loopback.family() != AF_INET6) {
// Try estimating MTU.
std::unique_ptr<AsyncSocket> mtu_socket(
ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
mtu_socket->Bind(SocketAddress(loopback, 0));
uint16_t mtu;
// should fail until we connect
ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
mtu_socket->Connect(SocketAddress(loopback, 0));
#if defined(WEBRTC_WIN)
// now it should succeed
ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
ASSERT_GE(mtu, 1492); // should be at least the 1492 "plateau" on localhost
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
// except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
#else
// and the behavior seems unpredictable on Linux,
// failing on the build machine
// but succeeding on my Ubiquity instance.
#endif
}
}
void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) {

View File

@ -384,13 +384,6 @@ int VirtualSocket::SetOption(Option opt, int value) {
return 0; // 0 is success to emulate setsockopt()
}
int VirtualSocket::EstimateMTU(uint16_t* mtu) {
if (CS_CONNECTED != state_)
return ENOTCONN;
else
return 65536;
}
void VirtualSocket::OnMessage(Message* pmsg) {
if (pmsg->message_id == MSG_ID_PACKET) {
RTC_DCHECK(nullptr != pmsg->pdata);

View File

@ -311,7 +311,6 @@ class VirtualSocket : public AsyncSocket,
ConnState GetState() const override;
int GetOption(Option opt, int* value) override;
int SetOption(Option opt, int value) override;
int EstimateMTU(uint16_t* mtu) override;
void OnMessage(Message* pmsg) override;
bool was_any() { return was_any_; }

View File

@ -13,7 +13,6 @@
#include "webrtc/base/gunit.h"
#include "webrtc/base/nethelpers.h"
#include "webrtc/base/win32.h"
#include "webrtc/base/winping.h"
#if !defined(WEBRTC_WIN)
#error Only for Windows
@ -36,29 +35,6 @@ TEST_F(Win32Test, FileTimeToUInt64Test) {
EXPECT_EQ(expected, ToUInt64(ft));
}
TEST_F(Win32Test, WinPingTest) {
WinPing ping;
ASSERT_TRUE(ping.IsValid());
// Test valid ping cases.
WinPing::PingResult result = ping.Ping(IPAddress(INADDR_LOOPBACK), 20, 50, 1,
false);
ASSERT_EQ(WinPing::PING_SUCCESS, result);
if (HasIPv6Enabled()) {
WinPing::PingResult v6result = ping.Ping(IPAddress(in6addr_loopback), 20,
50, 1, false);
ASSERT_EQ(WinPing::PING_SUCCESS, v6result);
}
// Test invalid parameter cases.
ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping(
IPAddress(INADDR_LOOPBACK), 0, 50, 1, false));
ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping(
IPAddress(INADDR_LOOPBACK), 20, 0, 1, false));
ASSERT_EQ(WinPing::PING_INVALID_PARAMS, ping.Ping(
IPAddress(INADDR_LOOPBACK), 20, 50, 0, false));
}
TEST_F(Win32Test, IPv6AddressCompression) {
IPAddress ipv6;

View File

@ -17,7 +17,6 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/win32window.h"
#include "webrtc/base/winping.h"
namespace rtc {
@ -525,37 +524,6 @@ int Win32Socket::Close() {
return err;
}
int Win32Socket::EstimateMTU(uint16_t* mtu) {
SocketAddress addr = GetRemoteAddress();
if (addr.IsAnyIP()) {
error_ = ENOTCONN;
return -1;
}
WinPing ping;
if (!ping.IsValid()) {
error_ = EINVAL; // can't think of a better error ID
return -1;
}
for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
int32_t size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
WinPing::PingResult result = ping.Ping(addr.ipaddr(), size,
ICMP_PING_TIMEOUT_MILLIS, 1, false);
if (result == WinPing::PING_FAIL) {
error_ = EINVAL; // can't think of a better error ID
return -1;
}
if (result != WinPing::PING_TOO_LARGE) {
*mtu = PACKET_MAXIMUMS[level];
return 0;
}
}
RTC_NOTREACHED();
return 0;
}
void Win32Socket::CreateSink() {
RTC_DCHECK(nullptr == sink_);

View File

@ -55,7 +55,6 @@ class Win32Socket : public AsyncSocket {
virtual int GetError() const;
virtual void SetError(int error);
virtual ConnState GetState() const;
virtual int EstimateMTU(uint16_t* mtu);
virtual int GetOption(Option opt, int* value);
virtual int SetOption(Option opt, int value);

View File

@ -1,357 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/winping.h"
#include <Iphlpapi.h>
#include <algorithm>
#include "webrtc/base/byteorder.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/ipaddress.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/nethelpers.h"
#include "webrtc/base/socketaddress.h"
namespace rtc {
//////////////////////////////////////////////////////////////////////
// Found in IPExport.h
//////////////////////////////////////////////////////////////////////
typedef struct icmp_echo_reply {
ULONG Address; // Replying address
ULONG Status; // Reply IP_STATUS
ULONG RoundTripTime; // RTT in milliseconds
USHORT DataSize; // Reply data size in bytes
USHORT Reserved; // Reserved for system use
PVOID Data; // Pointer to the reply data
struct ip_option_information Options; // Reply options
} ICMP_ECHO_REPLY, * PICMP_ECHO_REPLY;
typedef struct icmpv6_echo_reply_lh {
sockaddr_in6 Address;
ULONG Status;
unsigned int RoundTripTime;
} ICMPV6_ECHO_REPLY, *PICMPV6_ECHO_REPLY;
//
// IP_STATUS codes returned from IP APIs
//
#define IP_STATUS_BASE 11000
#define IP_SUCCESS 0
#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1)
#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2)
#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3)
#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4)
#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
#define IP_NO_RESOURCES (IP_STATUS_BASE + 6)
#define IP_BAD_OPTION (IP_STATUS_BASE + 7)
#define IP_HW_ERROR (IP_STATUS_BASE + 8)
#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9)
#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10)
#define IP_BAD_REQ (IP_STATUS_BASE + 11)
#define IP_BAD_ROUTE (IP_STATUS_BASE + 12)
#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13)
#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14)
#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15)
#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16)
#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17)
#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18)
#define IP_ADDR_DELETED (IP_STATUS_BASE + 19)
#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20)
#define IP_MTU_CHANGE (IP_STATUS_BASE + 21)
#define IP_UNLOAD (IP_STATUS_BASE + 22)
#define IP_ADDR_ADDED (IP_STATUS_BASE + 23)
#define IP_MEDIA_CONNECT (IP_STATUS_BASE + 24)
#define IP_MEDIA_DISCONNECT (IP_STATUS_BASE + 25)
#define IP_BIND_ADAPTER (IP_STATUS_BASE + 26)
#define IP_UNBIND_ADAPTER (IP_STATUS_BASE + 27)
#define IP_DEVICE_DOES_NOT_EXIST (IP_STATUS_BASE + 28)
#define IP_DUPLICATE_ADDRESS (IP_STATUS_BASE + 29)
#define IP_INTERFACE_METRIC_CHANGE (IP_STATUS_BASE + 30)
#define IP_RECONFIG_SECFLTR (IP_STATUS_BASE + 31)
#define IP_NEGOTIATING_IPSEC (IP_STATUS_BASE + 32)
#define IP_INTERFACE_WOL_CAPABILITY_CHANGE (IP_STATUS_BASE + 33)
#define IP_DUPLICATE_IPADD (IP_STATUS_BASE + 34)
#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50)
#define MAX_IP_STATUS IP_GENERAL_FAILURE
#define IP_PENDING (IP_STATUS_BASE + 255)
//
// Values used in the IP header Flags field.
//
#define IP_FLAG_DF 0x2 // Don't fragment this packet.
//
// Supported IP Option Types.
//
// These types define the options which may be used in the OptionsData field
// of the ip_option_information structure. See RFC 791 for a complete
// description of each.
//
#define IP_OPT_EOL 0 // End of list option
#define IP_OPT_NOP 1 // No operation
#define IP_OPT_SECURITY 0x82 // Security option
#define IP_OPT_LSRR 0x83 // Loose source route
#define IP_OPT_SSRR 0x89 // Strict source route
#define IP_OPT_RR 0x7 // Record route
#define IP_OPT_TS 0x44 // Timestamp
#define IP_OPT_SID 0x88 // Stream ID (obsolete)
#define IP_OPT_ROUTER_ALERT 0x94 // Router Alert Option
#define MAX_OPT_SIZE 40 // Maximum length of IP options in bytes
//////////////////////////////////////////////////////////////////////
// Global Constants and Types
//////////////////////////////////////////////////////////////////////
const char * const ICMP_DLL_NAME = "Iphlpapi.dll";
const char * const ICMP_CREATE_FUNC = "IcmpCreateFile";
const char * const ICMP_CLOSE_FUNC = "IcmpCloseHandle";
const char * const ICMP_SEND_FUNC = "IcmpSendEcho";
const char * const ICMP6_CREATE_FUNC = "Icmp6CreateFile";
const char * const ICMP6_SEND_FUNC = "Icmp6SendEcho2";
inline uint32_t ReplySize(uint32_t data_size, int family) {
if (family == AF_INET) {
// A ping error message is 8 bytes long, so make sure we allow for at least
// 8 bytes of reply data.
return sizeof(ICMP_ECHO_REPLY) + std::max<uint32_t>(8, data_size);
} else if (family == AF_INET6) {
// Per MSDN, Send6IcmpEcho2 needs at least one ICMPV6_ECHO_REPLY,
// 8 bytes for ICMP header, _and_ an IO_BLOCK_STATUS (2 pointers),
// in addition to the data size.
return sizeof(ICMPV6_ECHO_REPLY) + data_size + 8 + (2 * sizeof(DWORD*));
} else {
return 0;
}
}
//////////////////////////////////////////////////////////////////////
// WinPing
//////////////////////////////////////////////////////////////////////
WinPing::WinPing()
: dll_(0), hping_(INVALID_HANDLE_VALUE), create_(0), close_(0), send_(0),
create6_(0), send6_(0), data_(0), dlen_(0), reply_(0),
rlen_(0), valid_(false) {
dll_ = LoadLibraryA(ICMP_DLL_NAME);
if (!dll_) {
LOG(LERROR) << "LoadLibrary: " << GetLastError();
return;
}
create_ = (PIcmpCreateFile) GetProcAddress(dll_, ICMP_CREATE_FUNC);
close_ = (PIcmpCloseHandle) GetProcAddress(dll_, ICMP_CLOSE_FUNC);
send_ = (PIcmpSendEcho) GetProcAddress(dll_, ICMP_SEND_FUNC);
if (!create_ || !close_ || !send_) {
LOG(LERROR) << "GetProcAddress(ICMP_*): " << GetLastError();
return;
}
hping_ = create_();
if (hping_ == INVALID_HANDLE_VALUE) {
LOG(LERROR) << "IcmpCreateFile: " << GetLastError();
return;
}
if (HasIPv6Enabled()) {
create6_ = (PIcmp6CreateFile) GetProcAddress(dll_, ICMP6_CREATE_FUNC);
send6_ = (PIcmp6SendEcho2) GetProcAddress(dll_, ICMP6_SEND_FUNC);
if (!create6_ || !send6_) {
LOG(LERROR) << "GetProcAddress(ICMP6_*): " << GetLastError();
return;
}
hping6_ = create6_();
if (hping6_ == INVALID_HANDLE_VALUE) {
LOG(LERROR) << "Icmp6CreateFile: " << GetLastError();
}
}
dlen_ = 0;
rlen_ = ReplySize(dlen_, AF_INET);
data_ = new char[dlen_];
reply_ = new char[rlen_];
valid_ = true;
}
WinPing::~WinPing() {
if ((hping_ != INVALID_HANDLE_VALUE) && close_) {
if (!close_(hping_))
LOG(WARNING) << "IcmpCloseHandle: " << GetLastError();
}
if ((hping6_ != INVALID_HANDLE_VALUE) && close_) {
if (!close_(hping6_)) {
LOG(WARNING) << "Icmp6CloseHandle: " << GetLastError();
}
}
if (dll_)
FreeLibrary(dll_);
delete[] data_;
delete[] reply_;
}
WinPing::PingResult WinPing::Ping(IPAddress ip,
uint32_t data_size,
uint32_t timeout,
uint8_t ttl,
bool allow_fragments) {
if (data_size == 0 || timeout == 0 || ttl == 0) {
LOG(LERROR) << "IcmpSendEcho: data_size/timeout/ttl is 0.";
return PING_INVALID_PARAMS;
}
RTC_DCHECK(IsValid());
IP_OPTION_INFORMATION ipopt;
memset(&ipopt, 0, sizeof(ipopt));
if (!allow_fragments)
ipopt.Flags |= IP_FLAG_DF;
ipopt.Ttl = ttl;
uint32_t reply_size = ReplySize(data_size, ip.family());
if (data_size > dlen_) {
delete [] data_;
dlen_ = data_size;
data_ = new char[dlen_];
memset(data_, 'z', dlen_);
}
if (reply_size > rlen_) {
delete [] reply_;
rlen_ = reply_size;
reply_ = new char[rlen_];
}
DWORD result = 0;
if (ip.family() == AF_INET) {
result = send_(hping_, ip.ipv4_address().S_un.S_addr, data_,
uint16_t(data_size), &ipopt, reply_, reply_size, timeout);
} else if (ip.family() == AF_INET6) {
sockaddr_in6 src = {0};
sockaddr_in6 dst = {0};
src.sin6_family = AF_INET6;
dst.sin6_family = AF_INET6;
dst.sin6_addr = ip.ipv6_address();
result = send6_(hping6_, nullptr, nullptr, nullptr, &src, &dst, data_,
int16_t(data_size), &ipopt, reply_, reply_size, timeout);
}
if (result == 0) {
DWORD error = GetLastError();
if (error == IP_PACKET_TOO_BIG)
return PING_TOO_LARGE;
if (error == IP_REQ_TIMED_OUT)
return PING_TIMEOUT;
LOG(LERROR) << "IcmpSendEcho(" << ip.ToSensitiveString()
<< ", " << data_size << "): " << error;
return PING_FAIL;
}
return PING_SUCCESS;
}
//////////////////////////////////////////////////////////////////////
// Microsoft Documenation
//////////////////////////////////////////////////////////////////////
//
// Routine Name:
//
// IcmpCreateFile
//
// Routine Description:
//
// Opens a handle on which ICMP Echo Requests can be issued.
//
// Arguments:
//
// None.
//
// Return Value:
//
// An open file handle or INVALID_HANDLE_VALUE. Extended error information
// is available by calling GetLastError().
//
//////////////////////////////////////////////////////////////////////
//
// Routine Name:
//
// IcmpCloseHandle
//
// Routine Description:
//
// Closes a handle opened by ICMPOpenFile.
//
// Arguments:
//
// IcmpHandle - The handle to close.
//
// Return Value:
//
// TRUE if the handle was closed successfully, otherwise FALSE. Extended
// error information is available by calling GetLastError().
//
//////////////////////////////////////////////////////////////////////
//
// Routine Name:
//
// IcmpSendEcho
//
// Routine Description:
//
// Sends an ICMP Echo request and returns any replies. The
// call returns when the timeout has expired or the reply buffer
// is filled.
//
// Arguments:
//
// IcmpHandle - An open handle returned by ICMPCreateFile.
//
// DestinationAddress - The destination of the echo request.
//
// RequestData - A buffer containing the data to send in the
// request.
//
// RequestSize - The number of bytes in the request data buffer.
//
// RequestOptions - Pointer to the IP header options for the request.
// May be null.
//
// ReplyBuffer - A buffer to hold any replies to the request.
// On return, the buffer will contain an array of
// ICMP_ECHO_REPLY structures followed by the
// options and data for the replies. The buffer
// should be large enough to hold at least one
// ICMP_ECHO_REPLY structure plus
// MAX(RequestSize, 8) bytes of data since an ICMP
// error message contains 8 bytes of data.
//
// ReplySize - The size in bytes of the reply buffer.
//
// Timeout - The time in milliseconds to wait for replies.
//
// Return Value:
//
// Returns the number of ICMP_ECHO_REPLY structures stored in ReplyBuffer.
// The status of each reply is contained in the structure. If the return
// value is zero, extended error information is available via
// GetLastError().
//
//////////////////////////////////////////////////////////////////////
} // namespace rtc

View File

@ -1,105 +0,0 @@
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_BASE_WINPING_H__
#define WEBRTC_BASE_WINPING_H__
#if defined(WEBRTC_WIN)
#include "webrtc/base/win32.h"
#include "webrtc/base/basictypes.h"
#include "webrtc/base/ipaddress.h"
namespace rtc {
// This class wraps a Win32 API for doing ICMP pinging. This API, unlike the
// the normal socket APIs (as implemented on Win9x), will return an error if
// an ICMP packet with the dont-fragment bit set is too large. This means this
// class can be used to detect the MTU to a given address.
typedef struct ip_option_information {
UCHAR Ttl; // Time To Live
UCHAR Tos; // Type Of Service
UCHAR Flags; // IP header flags
UCHAR OptionsSize; // Size in bytes of options data
PUCHAR OptionsData; // Pointer to options data
} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
typedef HANDLE (WINAPI *PIcmpCreateFile)();
typedef BOOL (WINAPI *PIcmpCloseHandle)(HANDLE icmp_handle);
typedef HANDLE (WINAPI *PIcmp6CreateFile)();
typedef BOOL (WINAPI *PIcmp6CloseHandle)(HANDLE icmp_handle);
typedef DWORD (WINAPI *PIcmpSendEcho)(
HANDLE IcmpHandle,
ULONG DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout);
typedef DWORD (WINAPI *PIcmp6SendEcho2)(
HANDLE IcmpHandle,
HANDLE Event,
FARPROC ApcRoutine,
PVOID ApcContext,
struct sockaddr_in6 *SourceAddress,
struct sockaddr_in6 *DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout
);
class WinPing {
public:
WinPing();
~WinPing();
// Determines whether the class was initialized correctly.
bool IsValid() { return valid_; }
// Attempts to send a ping with the given parameters.
enum PingResult { PING_FAIL, PING_INVALID_PARAMS,
PING_TOO_LARGE, PING_TIMEOUT, PING_SUCCESS };
PingResult Ping(IPAddress ip,
uint32_t data_size,
uint32_t timeout_millis,
uint8_t ttl,
bool allow_fragments);
private:
HMODULE dll_;
HANDLE hping_;
HANDLE hping6_;
PIcmpCreateFile create_;
PIcmpCloseHandle close_;
PIcmpSendEcho send_;
PIcmp6CreateFile create6_;
PIcmp6SendEcho2 send6_;
char* data_;
uint32_t dlen_;
char* reply_;
uint32_t rlen_;
bool valid_;
};
} // namespace rtc
#endif // WEBRTC_WIN
#endif // WEBRTC_BASE_WINPING_H__