| Index: net/udp/udp_socket_win.cc
|
| ===================================================================
|
| --- net/udp/udp_socket_win.cc (revision 105801)
|
| +++ net/udp/udp_socket_win.cc (working copy)
|
| @@ -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 @@
|
| 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 @@
|
| 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);
|
| @@ -265,28 +280,39 @@
|
| &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);
|
| +int UDPSocketWin::LogRead(int result,
|
| + const char* bytes) const {
|
| + if (result < 0) {
|
| + net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result);
|
| + return result;
|
| + }
|
|
|
| - // Convert address.
|
| - if (address) {
|
| - struct sockaddr* addr =
|
| - reinterpret_cast<struct sockaddr*>(&recv_addr_storage_);
|
| - if (!address->FromSockAddr(addr, recv_addr_len_))
|
| - return false;
|
| + 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)));
|
| }
|
|
|
| - return true;
|
| + base::StatsCounter read_bytes("udp.read_bytes");
|
| + read_bytes.Add(result);
|
| + return result;
|
| }
|
|
|
| void UDPSocketWin::DidCompleteWrite() {
|
| @@ -295,15 +321,33 @@
|
| &num_bytes, FALSE, &flags);
|
| WSAResetEvent(write_overlapped_.hEvent);
|
| int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
|
| - if (ok)
|
| - ProcessSuccessfulWrite(num_bytes);
|
| + result = LogWrite(result, write_iobuffer_->data(), send_to_address_.get());
|
| +
|
| + send_to_address_.reset();
|
| write_iobuffer_ = NULL;
|
| DoWriteCallback(result);
|
| }
|
|
|
| -void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) {
|
| +int UDPSocketWin::LogWrite(int result,
|
| + const char* bytes,
|
| + const IPEndPoint* address) const {
|
| + if (result < 0) {
|
| + net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result);
|
| + return result;
|
| + }
|
| +
|
| + 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);
|
| + return result;
|
| }
|
|
|
| int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
|
| @@ -323,14 +367,18 @@
|
| &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;
|
| + }
|
| + return LogRead(result, buf->data());
|
| }
|
| } else {
|
| int os_error = WSAGetLastError();
|
| if (os_error != WSA_IO_PENDING)
|
| - return MapSystemError(os_error);
|
| + return LogRead(MapSystemError(os_error), NULL);
|
| }
|
| read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_);
|
| return ERR_IO_PENDING;
|
| @@ -348,7 +396,7 @@
|
| addr_len = 0;
|
| } else {
|
| if (!address->ToSockAddr(addr, &addr_len))
|
| - return ERR_FAILED;
|
| + return LogWrite(ERR_FAILED, NULL, NULL);
|
| }
|
|
|
| WSABUF write_buffer;
|
| @@ -361,14 +409,12 @@
|
| int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags,
|
| addr, addr_len, &write_overlapped_, NULL);
|
| if (rv == 0) {
|
| - if (ResetEventIfSignaled(write_overlapped_.hEvent)) {
|
| - ProcessSuccessfulWrite(num);
|
| - return static_cast<int>(num);
|
| - }
|
| + if (ResetEventIfSignaled(write_overlapped_.hEvent))
|
| + return LogWrite(num, buf->data(), address);
|
| } else {
|
| int os_error = WSAGetLastError();
|
| if (os_error != WSA_IO_PENDING)
|
| - return MapSystemError(os_error);
|
| + return LogWrite(MapSystemError(os_error), NULL, NULL);
|
| }
|
|
|
| write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_);
|
| @@ -399,4 +445,10 @@
|
| 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
|
|
|