Add NetLog support to UDP sockets.
BUG=99508 TEST=UDPSocketTest.Connect Review URL: http://codereview.chromium.org/8200011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106109 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
chrome/browser
net
resources
net_internals
net
@ -80,6 +80,7 @@ PassiveLogCollector::PassiveLogCollector()
|
||||
trackers_[net::NetLog::SOURCE_DNS_TRANSACTION] = &dns_transaction_tracker_;
|
||||
trackers_[net::NetLog::SOURCE_ASYNC_HOST_RESOLVER_REQUEST] =
|
||||
&async_host_resolver_request_tracker_;
|
||||
trackers_[net::NetLog::SOURCE_UDP_SOCKET] = &udp_socket_tracker_;
|
||||
// Make sure our mapping is up-to-date.
|
||||
for (size_t i = 0; i < arraysize(trackers_); ++i)
|
||||
DCHECK(trackers_[i]) << "Unhandled SourceType: " << i;
|
||||
@ -724,3 +725,33 @@ PassiveLogCollector::AsyncHostResolverRequestTracker::DoAddEntry(
|
||||
}
|
||||
return ACTION_NONE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// UDPSocketTracker
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
const size_t PassiveLogCollector::UDPSocketTracker::kMaxNumSources = 200;
|
||||
const size_t PassiveLogCollector::UDPSocketTracker::kMaxGraveyardSize = 15;
|
||||
|
||||
PassiveLogCollector::UDPSocketTracker::UDPSocketTracker()
|
||||
: SourceTracker(kMaxNumSources, kMaxGraveyardSize, NULL) {
|
||||
}
|
||||
|
||||
PassiveLogCollector::UDPSocketTracker::Action
|
||||
PassiveLogCollector::UDPSocketTracker::DoAddEntry(
|
||||
const ChromeNetLog::Entry& entry,
|
||||
SourceInfo* out_info) {
|
||||
if (entry.type == net::NetLog::TYPE_UDP_BYTES_SENT ||
|
||||
entry.type == net::NetLog::TYPE_UDP_BYTES_RECEIVED) {
|
||||
return ACTION_NONE;
|
||||
}
|
||||
|
||||
AddEntryToSourceInfo(entry, out_info);
|
||||
|
||||
if (entry.type == net::NetLog::TYPE_SOCKET_ALIVE &&
|
||||
entry.phase == net::NetLog::PHASE_END) {
|
||||
return ACTION_MOVE_TO_GRAVEYARD;
|
||||
}
|
||||
|
||||
return ACTION_NONE;
|
||||
}
|
||||
|
@ -384,6 +384,22 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserverImpl {
|
||||
DISALLOW_COPY_AND_ASSIGN(AsyncHostResolverRequestTracker);
|
||||
};
|
||||
|
||||
|
||||
// Tracks the log entries for the last seen SOURCE_UDP_SOCKET.
|
||||
class UDPSocketTracker : public SourceTracker {
|
||||
public:
|
||||
static const size_t kMaxNumSources;
|
||||
static const size_t kMaxGraveyardSize;
|
||||
|
||||
UDPSocketTracker();
|
||||
|
||||
private:
|
||||
virtual Action DoAddEntry(const ChromeNetLog::Entry& entry,
|
||||
SourceInfo* out_info);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(UDPSocketTracker);
|
||||
};
|
||||
|
||||
PassiveLogCollector();
|
||||
virtual ~PassiveLogCollector();
|
||||
|
||||
@ -426,6 +442,7 @@ class PassiveLogCollector : public ChromeNetLog::ThreadSafeObserverImpl {
|
||||
ExponentialBackoffThrottlingTracker exponential_backoff_throttling_tracker_;
|
||||
DnsTransactionTracker dns_transaction_tracker_;
|
||||
AsyncHostResolverRequestTracker async_host_resolver_request_tracker_;
|
||||
UDPSocketTracker udp_socket_tracker_;
|
||||
|
||||
// This array maps each NetLog::SourceType to one of the tracker instances
|
||||
// defined above. Use of this array avoid duplicating the list of trackers
|
||||
|
@ -73,7 +73,9 @@ found in the LICENSE file.
|
||||
}
|
||||
|
||||
#events-view-source-list-tbody .source_HOST_RESOLVER_IMPL_JOB,
|
||||
#events-view-source-list-tbody .source_HOST_RESOLVER_IMPL_REQUEST {
|
||||
#events-view-source-list-tbody .source_HOST_RESOLVER_IMPL_REQUEST,
|
||||
#events-view-source-list-tbody .source_ASYNC_HOST_RESOLVER_REQUEST,
|
||||
#events-view-source-list-tbody .source_DNS_TRANSACTION {
|
||||
color: #206060;
|
||||
}
|
||||
|
||||
@ -86,6 +88,10 @@ found in the LICENSE file.
|
||||
color: purple;
|
||||
}
|
||||
|
||||
#events-view-source-list-tbody .source_UDP_SOCKET {
|
||||
color: #803030;
|
||||
}
|
||||
|
||||
#events-view-source-list-tbody .source_INIT_PROXY_RESOLVER {
|
||||
color: green;
|
||||
}
|
||||
|
@ -99,12 +99,28 @@ var SourceEntry = (function() {
|
||||
this.description_ = e.params.host + ' (' + e.params.proxy + ')';
|
||||
break;
|
||||
case LogSourceType.SOCKET:
|
||||
// Use description of parent source, if any.
|
||||
if (e.params.source_dependency != undefined) {
|
||||
var connectJobId = e.params.source_dependency.id;
|
||||
var connectJob =
|
||||
g_browser.sourceTracker.getSourceEntry(connectJobId);
|
||||
if (connectJob)
|
||||
this.description_ = connectJob.getDescription();
|
||||
var parentId = e.params.source_dependency.id;
|
||||
this.description_ =
|
||||
g_browser.sourceTracker.getDescription(parentId);
|
||||
}
|
||||
break;
|
||||
case LogSourceType.UDP_SOCKET:
|
||||
if (e.params.address != undefined) {
|
||||
this.description_ = e.params.address;
|
||||
// If the parent of |this| is a DNS_TRANSACTION, use
|
||||
// '<DNS Server IP> [<DNS we're resolving>]'.
|
||||
if (this.entries_[0].type == LogEventType.SOCKET_ALIVE &&
|
||||
this.entries_[0].params.source_dependency != undefined) {
|
||||
var parentId = this.entries_[0].params.source_dependency.id;
|
||||
var parent = g_browser.sourceTracker.getSourceEntry(parentId);
|
||||
if (parent &&
|
||||
parent.getSourceType() == LogSourceType.DNS_TRANSACTION &&
|
||||
parent.getDescription().length > 0) {
|
||||
this.description_ += ' [' + parent.getDescription() + ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LogSourceType.ASYNC_HOST_RESOLVER_REQUEST:
|
||||
@ -137,8 +153,10 @@ var SourceEntry = (function() {
|
||||
return undefined;
|
||||
if (this.entries_.length >= 2) {
|
||||
if (this.entries_[0].type == LogEventType.REQUEST_ALIVE ||
|
||||
this.entries_[0].type == LogEventType.SOCKET_POOL_CONNECT_JOB)
|
||||
this.entries_[0].type == LogEventType.SOCKET_POOL_CONNECT_JOB ||
|
||||
this.entries_[1].type == LogEventType.UDP_CONNECT) {
|
||||
return this.entries_[1];
|
||||
}
|
||||
}
|
||||
return this.entries_[0];
|
||||
},
|
||||
|
@ -74,6 +74,17 @@ var SourceTracker = (function() {
|
||||
return this.numPassivelyCapturedEvents_;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the description of the specified SourceEntry, or an empty string
|
||||
* if it doesn't exist.
|
||||
*/
|
||||
getDescription: function(id) {
|
||||
var entry = this.getSourceEntry(id);
|
||||
if (entry)
|
||||
return entry.getDescription();
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the specified SourceEntry.
|
||||
*/
|
||||
|
@ -192,9 +192,18 @@ void BoundNetLog::EndEvent(
|
||||
AddEntry(event_type, NetLog::PHASE_END, params);
|
||||
}
|
||||
|
||||
void BoundNetLog::AddEventWithNetErrorCode(NetLog::EventType event_type,
|
||||
int net_error) const {
|
||||
DCHECK_GT(0, net_error);
|
||||
DCHECK_NE(ERR_IO_PENDING, net_error);
|
||||
AddEvent(
|
||||
event_type,
|
||||
make_scoped_refptr(new NetLogIntegerParameter("net_error", net_error)));
|
||||
}
|
||||
|
||||
void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
|
||||
int net_error) const {
|
||||
DCHECK_NE(net_error, ERR_IO_PENDING);
|
||||
DCHECK_NE(ERR_IO_PENDING, net_error);
|
||||
if (net_error >= 0) {
|
||||
EndEvent(event_type, NULL);
|
||||
} else {
|
||||
@ -205,7 +214,8 @@ void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
|
||||
}
|
||||
|
||||
void BoundNetLog::AddByteTransferEvent(NetLog::EventType event_type,
|
||||
int byte_count, char* bytes) const {
|
||||
int byte_count,
|
||||
const char* bytes) const {
|
||||
scoped_refptr<NetLog::EventParameters> params;
|
||||
if (IsLoggingBytes()) {
|
||||
params = new NetLogBytesTransferredParameter(byte_count, bytes);
|
||||
|
@ -243,6 +243,13 @@ class NET_EXPORT BoundNetLog {
|
||||
void EndEvent(NetLog::EventType event_type,
|
||||
const scoped_refptr<NetLog::EventParameters>& params) const;
|
||||
|
||||
// Just like AddEvent, except |net_error| is a net error code. A parameter
|
||||
// called "net_error" with the indicated value will be recorded for the event.
|
||||
// |net_error| must be negative, and not ERR_IO_PENDING, as it's not a true
|
||||
// error.
|
||||
void AddEventWithNetErrorCode(NetLog::EventType event_type,
|
||||
int net_error) const;
|
||||
|
||||
// Just like EndEvent, except |net_error| is a net error code. If it's
|
||||
// negative, a parameter called "net_error" with a value of |net_error| is
|
||||
// associated with the event. Otherwise, the end event has no parameters.
|
||||
@ -253,7 +260,7 @@ class NET_EXPORT BoundNetLog {
|
||||
// Logs a byte transfer event to the NetLog. Determines whether to log the
|
||||
// received bytes or not based on the current logging level.
|
||||
void AddByteTransferEvent(NetLog::EventType event_type,
|
||||
int byte_count, char* bytes) const;
|
||||
int byte_count, const char* bytes) const;
|
||||
|
||||
NetLog::LogLevel GetLogLevel() const;
|
||||
|
||||
|
@ -287,6 +287,19 @@ EVENT_TYPE(WAITING_FOR_PROXY_RESOLVER_THREAD)
|
||||
// }
|
||||
EVENT_TYPE(SUBMITTED_TO_RESOLVER_THREAD)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Socket (Shared by stream and datagram sockets)
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Marks the begin/end of a socket (TCP/SOCKS/SSL/UDP).
|
||||
//
|
||||
// The BEGIN phase contains the following parameters:
|
||||
//
|
||||
// {
|
||||
// "source_dependency": <Source identifier for the controlling entity>,
|
||||
// }
|
||||
EVENT_TYPE(SOCKET_ALIVE)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// StreamSocket
|
||||
// ------------------------------------------------------------------------
|
||||
@ -300,10 +313,11 @@ EVENT_TYPE(SUBMITTED_TO_RESOLVER_THREAD)
|
||||
// "address_list": <List of network address strings>,
|
||||
// }
|
||||
//
|
||||
// And the END event will contain the following parameters on failure:
|
||||
// And the END event will contain the following parameters:
|
||||
//
|
||||
// {
|
||||
// "net_error": <Net integer error code>,
|
||||
// "net_error": <Net integer error code, on error>,
|
||||
// "source_address": <Local source address of the connection, on success>,
|
||||
// }
|
||||
EVENT_TYPE(TCP_CONNECT)
|
||||
|
||||
@ -335,9 +349,6 @@ EVENT_TYPE(TCP_CONNECT_ATTEMPT)
|
||||
// }
|
||||
EVENT_TYPE(TCP_ACCEPT)
|
||||
|
||||
// Marks the begin/end of a socket (TCP/SOCKS/SSL).
|
||||
EVENT_TYPE(SOCKET_ALIVE)
|
||||
|
||||
// This event is logged to the socket stream whenever the socket is
|
||||
// acquired/released via a ClientSocketHandle.
|
||||
//
|
||||
@ -475,6 +486,45 @@ EVENT_TYPE(SSL_SOCKET_BYTES_SENT)
|
||||
EVENT_TYPE(SOCKET_BYTES_RECEIVED)
|
||||
EVENT_TYPE(SSL_SOCKET_BYTES_RECEIVED)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// DatagramSocket
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// The start/end of a UDP client connecting.
|
||||
//
|
||||
// The START event contains these parameters:
|
||||
//
|
||||
// {
|
||||
// "address": <Remote address being connected to>,
|
||||
// }
|
||||
//
|
||||
// And the END event will contain the following parameter:
|
||||
//
|
||||
// {
|
||||
// "net_error": <Net integer error code, on failure>,
|
||||
// }
|
||||
EVENT_TYPE(UDP_CONNECT)
|
||||
|
||||
// The specified number of bytes were transferred on the socket.
|
||||
// The following parameters are attached:
|
||||
// {
|
||||
// "address": <Remote address of data transfer. Not present when not
|
||||
// specified for UDP_BYTES_SENT events>,
|
||||
// "byte_count": <Number of bytes that were just received>,
|
||||
// "hex_encoded_bytes": <The exact bytes received, as a hexadecimal string.
|
||||
// Only present when byte logging is enabled>,
|
||||
// }
|
||||
EVENT_TYPE(UDP_BYTES_RECEIVED)
|
||||
EVENT_TYPE(UDP_BYTES_SENT)
|
||||
|
||||
// Logged when an error occurs while reading or writing to/from a UDP socket.
|
||||
// The following parameters are attached:
|
||||
// {
|
||||
// "net_error": <Net error code>,
|
||||
// }
|
||||
EVENT_TYPE(UDP_RECEIVE_ERROR)
|
||||
EVENT_TYPE(UDP_SEND_ERROR)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// ClientSocketPoolBase::ConnectJob
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1141,9 +1191,9 @@ EVENT_TYPE(THROTTLING_GOT_CUSTOM_RETRY_AFTER)
|
||||
// The END phase contains the following parameters:
|
||||
//
|
||||
// {
|
||||
// "net_error": <The net error code for the failure>,
|
||||
// "ip_address_list": <The result of the resolution process,
|
||||
// an IPAddressList>
|
||||
// "net_error": <The net error code for the failure, if any>,
|
||||
// }
|
||||
EVENT_TYPE(DNS_TRANSACTION)
|
||||
|
||||
|
@ -22,5 +22,6 @@ SOURCE_TYPE(HTTP_STREAM_JOB, 11)
|
||||
SOURCE_TYPE(EXPONENTIAL_BACKOFF_THROTTLING, 12)
|
||||
SOURCE_TYPE(DNS_TRANSACTION, 13)
|
||||
SOURCE_TYPE(ASYNC_HOST_RESOLVER_REQUEST, 14)
|
||||
SOURCE_TYPE(UDP_SOCKET, 15)
|
||||
|
||||
SOURCE_TYPE(COUNT, 15) // Always keep this as the last entry.
|
||||
SOURCE_TYPE(COUNT, 16) // Always keep this as the last entry.
|
||||
|
@ -631,6 +631,8 @@
|
||||
'udp/datagram_socket.h',
|
||||
'udp/udp_client_socket.cc',
|
||||
'udp/udp_client_socket.h',
|
||||
'udp/udp_data_transfer_param.cc',
|
||||
'udp/udp_data_transfer_param.h',
|
||||
'udp/udp_server_socket.cc',
|
||||
'udp/udp_server_socket.h',
|
||||
'udp/udp_socket.h',
|
||||
|
@ -805,7 +805,7 @@ void TCPClientSocketWin::LogConnectCompletion(int net_error) {
|
||||
sizeof(source_address));
|
||||
net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT,
|
||||
make_scoped_refptr(new NetLogStringParameter(
|
||||
"source address",
|
||||
"source_address",
|
||||
source_address_str)));
|
||||
}
|
||||
|
||||
|
36
net/udp/udp_data_transfer_param.cc
Normal file
36
net/udp/udp_data_transfer_param.cc
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/string_number_conversions.h"
|
||||
#include "base/values.h"
|
||||
#include "net/base/ip_endpoint.h"
|
||||
#include "net/udp/udp_data_transfer_param.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
UDPDataTransferNetLogParam::UDPDataTransferNetLogParam(
|
||||
int byte_count,
|
||||
const char* bytes,
|
||||
bool log_bytes,
|
||||
const IPEndPoint* address)
|
||||
: byte_count_(byte_count),
|
||||
hex_encoded_bytes_(log_bytes ? base::HexEncode(bytes, byte_count) : "") {
|
||||
if (address)
|
||||
address_.reset(new IPEndPoint(*address));
|
||||
}
|
||||
|
||||
UDPDataTransferNetLogParam::~UDPDataTransferNetLogParam() {
|
||||
}
|
||||
|
||||
Value* UDPDataTransferNetLogParam::ToValue() const {
|
||||
DictionaryValue* dict = new DictionaryValue();
|
||||
dict->SetInteger("byte_count", byte_count_);
|
||||
if (!hex_encoded_bytes_.empty())
|
||||
dict->SetString("hex_encoded_bytes", hex_encoded_bytes_);
|
||||
if (address_.get())
|
||||
dict->SetString("address", address_->ToString());
|
||||
return dict;
|
||||
}
|
||||
|
||||
} // namespace net
|
40
net/udp/udp_data_transfer_param.h
Normal file
40
net/udp/udp_data_transfer_param.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef NET_UDP_UDP_DATA_TRANSFER_PARAM_H_
|
||||
#define NET_UDP_UDP_DATA_TRANSFER_PARAM_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "net/base/net_log.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
class IPEndPoint;
|
||||
|
||||
// NetLog parameter to describe a UDP receive/send event. Each event has a
|
||||
// byte count, and may optionally have transferred bytes and an IPEndPoint as
|
||||
// well.
|
||||
class UDPDataTransferNetLogParam : public NetLog::EventParameters {
|
||||
public:
|
||||
// |bytes| are only logged when |log_bytes| is non-NULL.
|
||||
// |address| may be NULL.
|
||||
UDPDataTransferNetLogParam(int byte_count, const char* bytes, bool log_bytes,
|
||||
const IPEndPoint* address);
|
||||
virtual ~UDPDataTransferNetLogParam();
|
||||
|
||||
virtual base::Value* ToValue() const OVERRIDE;
|
||||
|
||||
private:
|
||||
const int byte_count_;
|
||||
const std::string hex_encoded_bytes_;
|
||||
scoped_ptr<IPEndPoint> address_;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
||||
#endif // NET_BASE_ADDRESS_LIST_NET_LOG_PARAM_H_
|
@ -19,6 +19,7 @@
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/base/net_log.h"
|
||||
#include "net/base/net_util.h"
|
||||
#include "net/udp/udp_data_transfer_param.h"
|
||||
#if defined(OS_POSIX)
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
@ -48,7 +49,7 @@ UDPSocketLibevent::UDPSocketLibevent(
|
||||
write_buf_len_(0),
|
||||
read_callback_(NULL),
|
||||
write_callback_(NULL),
|
||||
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
|
||||
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
|
||||
scoped_refptr<NetLog::EventParameters> params;
|
||||
if (source.is_valid())
|
||||
params = new NetLogSourceParameter("source_dependency", source);
|
||||
@ -158,7 +159,9 @@ int UDPSocketLibevent::RecvFrom(IOBuffer* buf,
|
||||
socket_, true, MessageLoopForIO::WATCH_READ,
|
||||
&read_socket_watcher_, &read_watcher_)) {
|
||||
PLOG(ERROR) << "WatchFileDescriptor failed on read";
|
||||
return MapSystemError(errno);
|
||||
int result = MapSystemError(errno);
|
||||
LogRead(result, NULL, 0, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
read_buf_ = buf;
|
||||
@ -191,20 +194,17 @@ int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf,
|
||||
DCHECK(callback); // Synchronous operation not supported
|
||||
DCHECK_GT(buf_len, 0);
|
||||
|
||||
int nwrite = InternalSendTo(buf, buf_len, address);
|
||||
if (nwrite >= 0) {
|
||||
base::StatsCounter write_bytes("udp.write_bytes");
|
||||
write_bytes.Add(nwrite);
|
||||
return nwrite;
|
||||
}
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
return MapSystemError(errno);
|
||||
int result = InternalSendTo(buf, buf_len, address);
|
||||
if (result != ERR_IO_PENDING)
|
||||
return result;
|
||||
|
||||
if (!MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
socket_, true, MessageLoopForIO::WATCH_WRITE,
|
||||
&write_socket_watcher_, &write_watcher_)) {
|
||||
DVLOG(1) << "WatchFileDescriptor failed on write, errno " << errno;
|
||||
return MapSystemError(errno);
|
||||
int result = MapSystemError(errno);
|
||||
LogWrite(result, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
write_buf_ = buf;
|
||||
@ -218,6 +218,16 @@ int UDPSocketLibevent::SendToOrWrite(IOBuffer* buf,
|
||||
}
|
||||
|
||||
int UDPSocketLibevent::Connect(const IPEndPoint& address) {
|
||||
net_log_.BeginEvent(
|
||||
NetLog::TYPE_UDP_CONNECT,
|
||||
make_scoped_refptr(new NetLogStringParameter("address",
|
||||
address.ToString())));
|
||||
int rv = InternalConnect(address);
|
||||
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int UDPSocketLibevent::InternalConnect(const IPEndPoint& address) {
|
||||
DCHECK(CalledOnValidThread());
|
||||
DCHECK(!is_connected());
|
||||
DCHECK(!remote_address_.get());
|
||||
@ -307,6 +317,33 @@ void UDPSocketLibevent::DidCompleteRead() {
|
||||
}
|
||||
}
|
||||
|
||||
void UDPSocketLibevent::LogRead(int result,
|
||||
const char* bytes,
|
||||
socklen_t addr_len,
|
||||
const sockaddr* addr) const {
|
||||
if (result < 0) {
|
||||
net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (net_log_.IsLoggingAllEvents()) {
|
||||
DCHECK(addr_len > 0);
|
||||
DCHECK(addr);
|
||||
|
||||
IPEndPoint address;
|
||||
bool is_address_valid = address.FromSockAddr(addr, addr_len);
|
||||
net_log_.AddEvent(
|
||||
NetLog::TYPE_UDP_BYTES_RECEIVED,
|
||||
make_scoped_refptr(
|
||||
new UDPDataTransferNetLogParam(
|
||||
result, bytes, net_log_.IsLoggingBytes(),
|
||||
is_address_valid ? &address : NULL)));
|
||||
}
|
||||
|
||||
base::StatsCounter read_bytes("udp.read_bytes");
|
||||
read_bytes.Add(result);
|
||||
}
|
||||
|
||||
int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
|
||||
socket_ = socket(address.GetFamily(), SOCK_DGRAM, 0);
|
||||
if (socket_ == kInvalidSocket)
|
||||
@ -322,12 +359,6 @@ int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
|
||||
void UDPSocketLibevent::DidCompleteWrite() {
|
||||
int result = InternalSendTo(write_buf_, write_buf_len_,
|
||||
send_to_address_.get());
|
||||
if (result >= 0) {
|
||||
base::StatsCounter write_bytes("udp.write_bytes");
|
||||
write_bytes.Add(result);
|
||||
} else {
|
||||
result = MapSystemError(errno);
|
||||
}
|
||||
|
||||
if (result != ERR_IO_PENDING) {
|
||||
write_buf_ = NULL;
|
||||
@ -338,6 +369,27 @@ void UDPSocketLibevent::DidCompleteWrite() {
|
||||
}
|
||||
}
|
||||
|
||||
void UDPSocketLibevent::LogWrite(int result,
|
||||
const char* bytes,
|
||||
const IPEndPoint* address) const {
|
||||
if (result < 0) {
|
||||
net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (net_log_.IsLoggingAllEvents()) {
|
||||
net_log_.AddEvent(
|
||||
NetLog::TYPE_UDP_BYTES_SENT,
|
||||
make_scoped_refptr(
|
||||
new UDPDataTransferNetLogParam(result, bytes,
|
||||
net_log_.IsLoggingBytes(),
|
||||
address)));
|
||||
}
|
||||
|
||||
base::StatsCounter write_bytes("udp.write_bytes");
|
||||
write_bytes.Add(result);
|
||||
}
|
||||
|
||||
int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
|
||||
IPEndPoint* address) {
|
||||
int bytes_transferred;
|
||||
@ -357,15 +409,13 @@ int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
|
||||
int result;
|
||||
if (bytes_transferred >= 0) {
|
||||
result = bytes_transferred;
|
||||
base::StatsCounter read_bytes("udp.read_bytes");
|
||||
read_bytes.Add(bytes_transferred);
|
||||
if (address) {
|
||||
if (!address->FromSockAddr(addr, addr_len))
|
||||
result = ERR_FAILED;
|
||||
}
|
||||
if (address && !address->FromSockAddr(addr, addr_len))
|
||||
result = ERR_FAILED;
|
||||
} else {
|
||||
result = MapSystemError(errno);
|
||||
}
|
||||
if (result != ERR_IO_PENDING)
|
||||
LogRead(result, buf->data(), addr_len, addr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -379,16 +429,24 @@ int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len,
|
||||
addr = NULL;
|
||||
addr_len = 0;
|
||||
} else {
|
||||
if (!address->ToSockAddr(addr, &addr_len))
|
||||
return ERR_FAILED;
|
||||
if (!address->ToSockAddr(addr, &addr_len)) {
|
||||
int result = ERR_FAILED;
|
||||
LogWrite(result, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return HANDLE_EINTR(sendto(socket_,
|
||||
buf->data(),
|
||||
buf_len,
|
||||
0,
|
||||
addr,
|
||||
addr_len));
|
||||
int result = HANDLE_EINTR(sendto(socket_,
|
||||
buf->data(),
|
||||
buf_len,
|
||||
0,
|
||||
addr,
|
||||
addr_len));
|
||||
if (result < 0)
|
||||
result = MapSystemError(errno);
|
||||
if (result != ERR_IO_PENDING)
|
||||
LogWrite(result, buf->data(), address);
|
||||
return result;
|
||||
}
|
||||
|
||||
int UDPSocketLibevent::DoBind(const IPEndPoint& address) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/threading/non_thread_safe.h"
|
||||
#include "net/base/address_list_net_log_param.h"
|
||||
#include "net/base/completion_callback.h"
|
||||
#include "net/base/rand_callback.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
@ -19,8 +20,6 @@
|
||||
|
||||
namespace net {
|
||||
|
||||
class BoundNetLog;
|
||||
|
||||
class UDPSocketLibevent : public base::NonThreadSafe {
|
||||
public:
|
||||
UDPSocketLibevent(DatagramSocket::BindType bind_type,
|
||||
@ -151,6 +150,14 @@ class UDPSocketLibevent : public base::NonThreadSafe {
|
||||
void DidCompleteRead();
|
||||
void DidCompleteWrite();
|
||||
|
||||
// Handles stats and logging. |result| is the number of bytes transferred, on
|
||||
// success, or the net error code on failure. On success, LogRead takes in a
|
||||
// sockaddr and its length, which are mandatory, while LogWrite takes in an
|
||||
// optional IPEndPoint.
|
||||
void LogRead(int result, const char* bytes, socklen_t addr_len,
|
||||
const sockaddr* addr) const;
|
||||
void LogWrite(int result, const char* bytes, const IPEndPoint* address) const;
|
||||
|
||||
// Returns the OS error code (or 0 on success).
|
||||
int CreateSocket(const IPEndPoint& address);
|
||||
|
||||
@ -162,6 +169,7 @@ class UDPSocketLibevent : public base::NonThreadSafe {
|
||||
const IPEndPoint* address,
|
||||
OldCompletionCallback* callback);
|
||||
|
||||
int InternalConnect(const IPEndPoint& address);
|
||||
int InternalRecvFrom(IOBuffer* buf, int buf_len, IPEndPoint* address);
|
||||
int InternalSendTo(IOBuffer* buf, int buf_len, const IPEndPoint* address);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/ip_endpoint.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/base/net_log_unittest.h"
|
||||
#include "net/base/net_test_suite.h"
|
||||
#include "net/base/net_util.h"
|
||||
#include "net/base/sys_addrinfo.h"
|
||||
@ -131,35 +132,73 @@ TEST_F(UDPSocketTest, Connect) {
|
||||
// Setup the server to listen.
|
||||
IPEndPoint bind_address;
|
||||
CreateUDPAddress("0.0.0.0", kPort, &bind_address);
|
||||
UDPServerSocket server(NULL, NetLog::Source());
|
||||
int rv = server.Listen(bind_address);
|
||||
CapturingNetLog server_log(CapturingNetLog::kUnbounded);
|
||||
scoped_ptr<UDPServerSocket> server(
|
||||
new UDPServerSocket(&server_log, NetLog::Source()));
|
||||
int rv = server->Listen(bind_address);
|
||||
EXPECT_EQ(OK, rv);
|
||||
|
||||
// Setup the client.
|
||||
IPEndPoint server_address;
|
||||
CreateUDPAddress("127.0.0.1", kPort, &server_address);
|
||||
UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
|
||||
RandIntCallback(),
|
||||
NULL,
|
||||
NetLog::Source());
|
||||
rv = client.Connect(server_address);
|
||||
CapturingNetLog client_log(CapturingNetLog::kUnbounded);
|
||||
scoped_ptr<UDPClientSocket> client(
|
||||
new UDPClientSocket(DatagramSocket::DEFAULT_BIND,
|
||||
RandIntCallback(),
|
||||
&client_log,
|
||||
NetLog::Source()));
|
||||
rv = client->Connect(server_address);
|
||||
EXPECT_EQ(OK, rv);
|
||||
|
||||
// Client sends to the server.
|
||||
rv = WriteSocket(&client, simple_message);
|
||||
rv = WriteSocket(client.get(), simple_message);
|
||||
EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
||||
|
||||
// Server waits for message.
|
||||
std::string str = RecvFromSocket(&server);
|
||||
std::string str = RecvFromSocket(server.get());
|
||||
DCHECK(simple_message == str);
|
||||
|
||||
// Server echoes reply.
|
||||
rv = SendToSocket(&server, simple_message);
|
||||
rv = SendToSocket(server.get(), simple_message);
|
||||
EXPECT_EQ(simple_message.length(), static_cast<size_t>(rv));
|
||||
|
||||
// Client waits for response.
|
||||
str = ReadSocket(&client);
|
||||
str = ReadSocket(client.get());
|
||||
DCHECK(simple_message == str);
|
||||
|
||||
// Delete sockets so they log their final events.
|
||||
server.reset();
|
||||
client.reset();
|
||||
|
||||
// Check the server's log.
|
||||
CapturingNetLog::EntryList server_entries;
|
||||
server_log.GetEntries(&server_entries);
|
||||
EXPECT_EQ(4u, server_entries.size());
|
||||
EXPECT_TRUE(LogContainsBeginEvent(
|
||||
server_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
||||
EXPECT_TRUE(LogContainsEvent(
|
||||
server_entries, 1, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
||||
EXPECT_TRUE(LogContainsEvent(
|
||||
server_entries, 2, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
|
||||
EXPECT_TRUE(LogContainsEndEvent(
|
||||
server_entries, 3, NetLog::TYPE_SOCKET_ALIVE));
|
||||
|
||||
// Check the client's log.
|
||||
CapturingNetLog::EntryList client_entries;
|
||||
client_log.GetEntries(&client_entries);
|
||||
EXPECT_EQ(6u, client_entries.size());
|
||||
EXPECT_TRUE(LogContainsBeginEvent(
|
||||
client_entries, 0, NetLog::TYPE_SOCKET_ALIVE));
|
||||
EXPECT_TRUE(LogContainsBeginEvent(
|
||||
client_entries, 1, NetLog::TYPE_UDP_CONNECT));
|
||||
EXPECT_TRUE(LogContainsEndEvent(
|
||||
client_entries, 2, NetLog::TYPE_UDP_CONNECT));
|
||||
EXPECT_TRUE(LogContainsEvent(
|
||||
client_entries, 3, NetLog::TYPE_UDP_BYTES_SENT, NetLog::PHASE_NONE));
|
||||
EXPECT_TRUE(LogContainsEvent(
|
||||
client_entries, 4, NetLog::TYPE_UDP_BYTES_RECEIVED, NetLog::PHASE_NONE));
|
||||
EXPECT_TRUE(LogContainsEndEvent(
|
||||
client_entries, 5, NetLog::TYPE_SOCKET_ALIVE));
|
||||
}
|
||||
|
||||
// In this test, we verify that random binding logic works, which attempts
|
||||
@ -321,11 +360,11 @@ TEST_F(UDPSocketTest, ClientGetLocalPeerAddresses) {
|
||||
SCOPED_TRACE(std::string("Connecting from ") + tests[i].local_address +
|
||||
std::string(" to ") + tests[i].remote_address);
|
||||
|
||||
net::IPAddressNumber ip_number;
|
||||
net::ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
|
||||
net::IPEndPoint remote_address(ip_number, 80);
|
||||
net::ParseIPLiteralToNumber(tests[i].local_address, &ip_number);
|
||||
net::IPEndPoint local_address(ip_number, 80);
|
||||
IPAddressNumber ip_number;
|
||||
ParseIPLiteralToNumber(tests[i].remote_address, &ip_number);
|
||||
IPEndPoint remote_address(ip_number, 80);
|
||||
ParseIPLiteralToNumber(tests[i].local_address, &ip_number);
|
||||
IPEndPoint local_address(ip_number, 80);
|
||||
|
||||
UDPClientSocket client(DatagramSocket::DEFAULT_BIND,
|
||||
RandIntCallback(),
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "base/message_loop.h"
|
||||
#include "base/metrics/stats_counters.h"
|
||||
#include "base/rand_util.h"
|
||||
#include "net/base/address_list_net_log_param.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/ip_endpoint.h"
|
||||
#include "net/base/net_errors.h"
|
||||
@ -18,6 +19,7 @@
|
||||
#include "net/base/net_util.h"
|
||||
#include "net/base/winsock_init.h"
|
||||
#include "net/base/winsock_util.h"
|
||||
#include "net/udp/udp_data_transfer_param.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -51,7 +53,7 @@ UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
|
||||
recv_from_address_(NULL),
|
||||
read_callback_(NULL),
|
||||
write_callback_(NULL),
|
||||
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
|
||||
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
|
||||
EnsureWinsockInit();
|
||||
scoped_refptr<NetLog::EventParameters> params;
|
||||
if (source.is_valid())
|
||||
@ -181,17 +183,30 @@ int UDPSocketWin::SendToOrWrite(IOBuffer* buf,
|
||||
DCHECK(!write_callback_);
|
||||
DCHECK(callback); // Synchronous operation not supported.
|
||||
DCHECK_GT(buf_len, 0);
|
||||
DCHECK(!send_to_address_.get());
|
||||
|
||||
int nwrite = InternalSendTo(buf, buf_len, address);
|
||||
if (nwrite != ERR_IO_PENDING)
|
||||
return nwrite;
|
||||
|
||||
if (address)
|
||||
send_to_address_.reset(new IPEndPoint(*address));
|
||||
write_iobuffer_ = buf;
|
||||
write_callback_ = callback;
|
||||
return ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
int UDPSocketWin::Connect(const IPEndPoint& address) {
|
||||
net_log_.BeginEvent(
|
||||
NetLog::TYPE_UDP_CONNECT,
|
||||
make_scoped_refptr(new NetLogStringParameter("address",
|
||||
address.ToString())));
|
||||
int rv = InternalConnect(address);
|
||||
net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int UDPSocketWin::InternalConnect(const IPEndPoint& address) {
|
||||
DCHECK(!is_connected());
|
||||
DCHECK(!remote_address_.get());
|
||||
int rv = CreateSocket(address);
|
||||
@ -281,28 +296,37 @@ void UDPSocketWin::DidCompleteRead() {
|
||||
&num_bytes, FALSE, &flags);
|
||||
WSAResetEvent(read_overlapped_.hEvent);
|
||||
int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
|
||||
if (ok) {
|
||||
if (!ProcessSuccessfulRead(num_bytes, recv_from_address_))
|
||||
// Convert address.
|
||||
if (recv_from_address_ && result >= 0) {
|
||||
if (!ReceiveAddressToIPEndpoint(recv_from_address_))
|
||||
result = ERR_FAILED;
|
||||
}
|
||||
LogRead(result, read_iobuffer_->data());
|
||||
read_iobuffer_ = NULL;
|
||||
recv_from_address_ = NULL;
|
||||
DoReadCallback(result);
|
||||
}
|
||||
|
||||
bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes, IPEndPoint* address) {
|
||||
base::StatsCounter read_bytes("udp.read_bytes");
|
||||
read_bytes.Add(num_bytes);
|
||||
|
||||
// Convert address.
|
||||
if (address) {
|
||||
struct sockaddr* addr =
|
||||
reinterpret_cast<struct sockaddr*>(&recv_addr_storage_);
|
||||
if (!address->FromSockAddr(addr, recv_addr_len_))
|
||||
return false;
|
||||
void UDPSocketWin::LogRead(int result, const char* bytes) const {
|
||||
if (result < 0) {
|
||||
net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (net_log_.IsLoggingAllEvents()) {
|
||||
// Get address for logging, if |address| is NULL.
|
||||
IPEndPoint address;
|
||||
bool is_address_valid = ReceiveAddressToIPEndpoint(&address);
|
||||
net_log_.AddEvent(
|
||||
NetLog::TYPE_UDP_BYTES_RECEIVED,
|
||||
make_scoped_refptr(
|
||||
new UDPDataTransferNetLogParam(
|
||||
result, bytes, net_log_.IsLoggingBytes(),
|
||||
is_address_valid ? &address : NULL)));
|
||||
}
|
||||
|
||||
base::StatsCounter read_bytes("udp.read_bytes");
|
||||
read_bytes.Add(result);
|
||||
}
|
||||
|
||||
void UDPSocketWin::DidCompleteWrite() {
|
||||
@ -311,15 +335,32 @@ void UDPSocketWin::DidCompleteWrite() {
|
||||
&num_bytes, FALSE, &flags);
|
||||
WSAResetEvent(write_overlapped_.hEvent);
|
||||
int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
|
||||
if (ok)
|
||||
ProcessSuccessfulWrite(num_bytes);
|
||||
LogWrite(result, write_iobuffer_->data(), send_to_address_.get());
|
||||
|
||||
send_to_address_.reset();
|
||||
write_iobuffer_ = NULL;
|
||||
DoWriteCallback(result);
|
||||
}
|
||||
|
||||
void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) {
|
||||
void UDPSocketWin::LogWrite(int result,
|
||||
const char* bytes,
|
||||
const IPEndPoint* address) const {
|
||||
if (result < 0) {
|
||||
net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (net_log_.IsLoggingAllEvents()) {
|
||||
net_log_.AddEvent(
|
||||
NetLog::TYPE_UDP_BYTES_SENT,
|
||||
make_scoped_refptr(
|
||||
new UDPDataTransferNetLogParam(result, bytes,
|
||||
net_log_.IsLoggingBytes(),
|
||||
address)));
|
||||
}
|
||||
|
||||
base::StatsCounter write_bytes("udp.write_bytes");
|
||||
write_bytes.Add(num_bytes);
|
||||
write_bytes.Add(result);
|
||||
}
|
||||
|
||||
int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
|
||||
@ -339,14 +380,22 @@ int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
|
||||
&recv_addr_len_, &read_overlapped_, NULL);
|
||||
if (rv == 0) {
|
||||
if (ResetEventIfSignaled(read_overlapped_.hEvent)) {
|
||||
if (!ProcessSuccessfulRead(num, address))
|
||||
return ERR_FAILED;
|
||||
return static_cast<int>(num);
|
||||
int result = num;
|
||||
// Convert address.
|
||||
if (address && result >= 0) {
|
||||
if (!ReceiveAddressToIPEndpoint(address))
|
||||
result = ERR_FAILED;
|
||||
}
|
||||
LogRead(result, buf->data());
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
int os_error = WSAGetLastError();
|
||||
if (os_error != WSA_IO_PENDING)
|
||||
return MapSystemError(os_error);
|
||||
if (os_error != WSA_IO_PENDING) {
|
||||
int result = MapSystemError(os_error);
|
||||
LogRead(result, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_);
|
||||
return ERR_IO_PENDING;
|
||||
@ -363,8 +412,11 @@ int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len,
|
||||
addr = NULL;
|
||||
addr_len = 0;
|
||||
} else {
|
||||
if (!address->ToSockAddr(addr, &addr_len))
|
||||
return ERR_FAILED;
|
||||
if (!address->ToSockAddr(addr, &addr_len)) {
|
||||
int result = ERR_FAILED;
|
||||
LogWrite(result, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
WSABUF write_buffer;
|
||||
@ -378,13 +430,17 @@ int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len,
|
||||
addr, addr_len, &write_overlapped_, NULL);
|
||||
if (rv == 0) {
|
||||
if (ResetEventIfSignaled(write_overlapped_.hEvent)) {
|
||||
ProcessSuccessfulWrite(num);
|
||||
return static_cast<int>(num);
|
||||
int result = num;
|
||||
LogWrite(result, buf->data(), address);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
int os_error = WSAGetLastError();
|
||||
if (os_error != WSA_IO_PENDING)
|
||||
return MapSystemError(os_error);
|
||||
if (os_error != WSA_IO_PENDING) {
|
||||
int result = MapSystemError(os_error);
|
||||
LogWrite(result, NULL, NULL);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_);
|
||||
@ -415,4 +471,10 @@ int UDPSocketWin::RandomBind(const IPEndPoint& address) {
|
||||
return DoBind(IPEndPoint(ip, 0));
|
||||
}
|
||||
|
||||
bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
|
||||
const struct sockaddr* addr =
|
||||
reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_);
|
||||
return address->FromSockAddr(addr, recv_addr_len_);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace net {
|
||||
|
||||
class BoundNetLog;
|
||||
|
||||
class UDPSocketWin : public base::NonThreadSafe {
|
||||
public:
|
||||
UDPSocketWin(DatagramSocket::BindType bind_type,
|
||||
@ -136,8 +134,12 @@ class UDPSocketWin : public base::NonThreadSafe {
|
||||
void DoWriteCallback(int rv);
|
||||
void DidCompleteRead();
|
||||
void DidCompleteWrite();
|
||||
bool ProcessSuccessfulRead(int num_bytes, IPEndPoint* address);
|
||||
void ProcessSuccessfulWrite(int num_bytes);
|
||||
|
||||
// Handles stats and logging. |result| is the number of bytes transferred, on
|
||||
// success, or the net error code on failure. LogRead retrieves the address
|
||||
// from |recv_addr_storage_|, while LogWrite takes it as an optional argument.
|
||||
void LogRead(int result, const char* bytes) const;
|
||||
void LogWrite(int result, const char* bytes, const IPEndPoint* address) const;
|
||||
|
||||
// Returns the OS error code (or 0 on success).
|
||||
int CreateSocket(const IPEndPoint& address);
|
||||
@ -150,12 +152,17 @@ class UDPSocketWin : public base::NonThreadSafe {
|
||||
const IPEndPoint* address,
|
||||
OldCompletionCallback* callback);
|
||||
|
||||
int InternalConnect(const IPEndPoint& address);
|
||||
int InternalRecvFrom(IOBuffer* buf, int buf_len, IPEndPoint* address);
|
||||
int InternalSendTo(IOBuffer* buf, int buf_len, const IPEndPoint* address);
|
||||
|
||||
int DoBind(const IPEndPoint& address);
|
||||
int RandomBind(const IPEndPoint& address);
|
||||
|
||||
// Attempts to convert the data in |recv_addr_storage_| and |recv_addr_len_|
|
||||
// to an IPEndPoint and writes it to |address|. Returns true on success.
|
||||
bool ReceiveAddressToIPEndpoint(IPEndPoint* address) const;
|
||||
|
||||
SOCKET socket_;
|
||||
|
||||
// How to do source port binding, used only when UDPSocket is part of
|
||||
@ -188,6 +195,10 @@ class UDPSocketWin : public base::NonThreadSafe {
|
||||
socklen_t recv_addr_len_;
|
||||
IPEndPoint* recv_from_address_;
|
||||
|
||||
// Cached copy of the current address we're sending to, if any. Used for
|
||||
// logging.
|
||||
scoped_ptr<IPEndPoint> send_to_address_;
|
||||
|
||||
// The buffer used by InternalWrite() to retry Write requests
|
||||
scoped_refptr<IOBuffer> write_iobuffer_;
|
||||
|
||||
|
Reference in New Issue
Block a user