OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/udp/udp_socket_win.h" | 5 #include "net/udp/udp_socket_win.h" |
6 | 6 |
7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
8 | 8 |
9 #include "base/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/metrics/stats_counters.h" | 12 #include "base/metrics/stats_counters.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "net/base/address_list_net_log_param.h" |
14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
15 #include "net/base/ip_endpoint.h" | 16 #include "net/base/ip_endpoint.h" |
16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
17 #include "net/base/net_log.h" | 18 #include "net/base/net_log.h" |
18 #include "net/base/net_util.h" | 19 #include "net/base/net_util.h" |
19 #include "net/base/winsock_init.h" | 20 #include "net/base/winsock_init.h" |
20 #include "net/base/winsock_util.h" | 21 #include "net/base/winsock_util.h" |
| 22 #include "net/udp/udp_data_transfer_param.h" |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 static const int kBindRetries = 10; | 26 static const int kBindRetries = 10; |
25 static const int kPortStart = 1024; | 27 static const int kPortStart = 1024; |
26 static const int kPortEnd = 65535; | 28 static const int kPortEnd = 65535; |
27 | 29 |
28 } // namespace net | 30 } // namespace net |
29 | 31 |
30 namespace net { | 32 namespace net { |
(...skipping 13 matching lines...) Expand all Loading... |
44 net::NetLog* net_log, | 46 net::NetLog* net_log, |
45 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
46 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
47 bind_type_(bind_type), | 49 bind_type_(bind_type), |
48 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
49 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
50 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
51 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
52 read_callback_(NULL), | 54 read_callback_(NULL), |
53 write_callback_(NULL), | 55 write_callback_(NULL), |
54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
55 EnsureWinsockInit(); | 57 EnsureWinsockInit(); |
56 scoped_refptr<NetLog::EventParameters> params; | 58 scoped_refptr<NetLog::EventParameters> params; |
57 if (source.is_valid()) | 59 if (source.is_valid()) |
58 params = new NetLogSourceParameter("source_dependency", source); | 60 params = new NetLogSourceParameter("source_dependency", source); |
59 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
60 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
61 read_overlapped_.hEvent = WSACreateEvent(); | 63 read_overlapped_.hEvent = WSACreateEvent(); |
62 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
63 write_overlapped_.hEvent = WSACreateEvent(); | 65 write_overlapped_.hEvent = WSACreateEvent(); |
64 if (bind_type == DatagramSocket::RANDOM_BIND) | 66 if (bind_type == DatagramSocket::RANDOM_BIND) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 | 176 |
175 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 177 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
176 int buf_len, | 178 int buf_len, |
177 const IPEndPoint* address, | 179 const IPEndPoint* address, |
178 OldCompletionCallback* callback) { | 180 OldCompletionCallback* callback) { |
179 DCHECK(CalledOnValidThread()); | 181 DCHECK(CalledOnValidThread()); |
180 DCHECK_NE(INVALID_SOCKET, socket_); | 182 DCHECK_NE(INVALID_SOCKET, socket_); |
181 DCHECK(!write_callback_); | 183 DCHECK(!write_callback_); |
182 DCHECK(callback); // Synchronous operation not supported. | 184 DCHECK(callback); // Synchronous operation not supported. |
183 DCHECK_GT(buf_len, 0); | 185 DCHECK_GT(buf_len, 0); |
| 186 DCHECK(!send_to_address_.get()); |
184 | 187 |
185 int nwrite = InternalSendTo(buf, buf_len, address); | 188 int nwrite = InternalSendTo(buf, buf_len, address); |
186 if (nwrite != ERR_IO_PENDING) | 189 if (nwrite != ERR_IO_PENDING) |
187 return nwrite; | 190 return nwrite; |
188 | 191 |
| 192 if (address) |
| 193 send_to_address_.reset(new IPEndPoint(*address)); |
189 write_iobuffer_ = buf; | 194 write_iobuffer_ = buf; |
190 write_callback_ = callback; | 195 write_callback_ = callback; |
191 return ERR_IO_PENDING; | 196 return ERR_IO_PENDING; |
192 } | 197 } |
193 | 198 |
194 int UDPSocketWin::Connect(const IPEndPoint& address) { | 199 int UDPSocketWin::Connect(const IPEndPoint& address) { |
| 200 net_log_.BeginEvent( |
| 201 NetLog::TYPE_UDP_CONNECT, |
| 202 make_scoped_refptr(new NetLogStringParameter("address", |
| 203 address.ToString()))); |
| 204 int rv = InternalConnect(address); |
| 205 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); |
| 206 return rv; |
| 207 } |
| 208 |
| 209 int UDPSocketWin::InternalConnect(const IPEndPoint& address) { |
195 DCHECK(!is_connected()); | 210 DCHECK(!is_connected()); |
196 DCHECK(!remote_address_.get()); | 211 DCHECK(!remote_address_.get()); |
197 int rv = CreateSocket(address); | 212 int rv = CreateSocket(address); |
198 if (rv < 0) | 213 if (rv < 0) |
199 return rv; | 214 return rv; |
200 | 215 |
201 if (bind_type_ == DatagramSocket::RANDOM_BIND) | 216 if (bind_type_ == DatagramSocket::RANDOM_BIND) |
202 rv = RandomBind(address); | 217 rv = RandomBind(address); |
203 // else connect() does the DatagramSocket::DEFAULT_BIND | 218 // else connect() does the DatagramSocket::DEFAULT_BIND |
204 | 219 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 write_callback_ = NULL; | 289 write_callback_ = NULL; |
275 c->Run(rv); | 290 c->Run(rv); |
276 } | 291 } |
277 | 292 |
278 void UDPSocketWin::DidCompleteRead() { | 293 void UDPSocketWin::DidCompleteRead() { |
279 DWORD num_bytes, flags; | 294 DWORD num_bytes, flags; |
280 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 295 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, |
281 &num_bytes, FALSE, &flags); | 296 &num_bytes, FALSE, &flags); |
282 WSAResetEvent(read_overlapped_.hEvent); | 297 WSAResetEvent(read_overlapped_.hEvent); |
283 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 298 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
284 if (ok) { | 299 // Convert address. |
285 if (!ProcessSuccessfulRead(num_bytes, recv_from_address_)) | 300 if (recv_from_address_ && result >= 0) { |
| 301 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) |
286 result = ERR_FAILED; | 302 result = ERR_FAILED; |
287 } | 303 } |
| 304 LogRead(result, read_iobuffer_->data()); |
288 read_iobuffer_ = NULL; | 305 read_iobuffer_ = NULL; |
289 recv_from_address_ = NULL; | 306 recv_from_address_ = NULL; |
290 DoReadCallback(result); | 307 DoReadCallback(result); |
291 } | 308 } |
292 | 309 |
293 bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes, IPEndPoint* address) { | 310 void UDPSocketWin::LogRead(int result, const char* bytes) const { |
294 base::StatsCounter read_bytes("udp.read_bytes"); | 311 if (result < 0) { |
295 read_bytes.Add(num_bytes); | 312 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); |
296 | 313 return; |
297 // Convert address. | |
298 if (address) { | |
299 struct sockaddr* addr = | |
300 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | |
301 if (!address->FromSockAddr(addr, recv_addr_len_)) | |
302 return false; | |
303 } | 314 } |
304 | 315 |
305 return true; | 316 if (net_log_.IsLoggingAllEvents()) { |
| 317 // Get address for logging, if |address| is NULL. |
| 318 IPEndPoint address; |
| 319 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); |
| 320 net_log_.AddEvent( |
| 321 NetLog::TYPE_UDP_BYTES_RECEIVED, |
| 322 make_scoped_refptr( |
| 323 new UDPDataTransferNetLogParam( |
| 324 result, bytes, net_log_.IsLoggingBytes(), |
| 325 is_address_valid ? &address : NULL))); |
| 326 } |
| 327 |
| 328 base::StatsCounter read_bytes("udp.read_bytes"); |
| 329 read_bytes.Add(result); |
306 } | 330 } |
307 | 331 |
308 void UDPSocketWin::DidCompleteWrite() { | 332 void UDPSocketWin::DidCompleteWrite() { |
309 DWORD num_bytes, flags; | 333 DWORD num_bytes, flags; |
310 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, | 334 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, |
311 &num_bytes, FALSE, &flags); | 335 &num_bytes, FALSE, &flags); |
312 WSAResetEvent(write_overlapped_.hEvent); | 336 WSAResetEvent(write_overlapped_.hEvent); |
313 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 337 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
314 if (ok) | 338 LogWrite(result, write_iobuffer_->data(), send_to_address_.get()); |
315 ProcessSuccessfulWrite(num_bytes); | 339 |
| 340 send_to_address_.reset(); |
316 write_iobuffer_ = NULL; | 341 write_iobuffer_ = NULL; |
317 DoWriteCallback(result); | 342 DoWriteCallback(result); |
318 } | 343 } |
319 | 344 |
320 void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) { | 345 void UDPSocketWin::LogWrite(int result, |
| 346 const char* bytes, |
| 347 const IPEndPoint* address) const { |
| 348 if (result < 0) { |
| 349 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); |
| 350 return; |
| 351 } |
| 352 |
| 353 if (net_log_.IsLoggingAllEvents()) { |
| 354 net_log_.AddEvent( |
| 355 NetLog::TYPE_UDP_BYTES_SENT, |
| 356 make_scoped_refptr( |
| 357 new UDPDataTransferNetLogParam(result, bytes, |
| 358 net_log_.IsLoggingBytes(), |
| 359 address))); |
| 360 } |
| 361 |
321 base::StatsCounter write_bytes("udp.write_bytes"); | 362 base::StatsCounter write_bytes("udp.write_bytes"); |
322 write_bytes.Add(num_bytes); | 363 write_bytes.Add(result); |
323 } | 364 } |
324 | 365 |
325 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 366 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, |
326 IPEndPoint* address) { | 367 IPEndPoint* address) { |
327 recv_addr_len_ = sizeof(recv_addr_storage_); | 368 recv_addr_len_ = sizeof(recv_addr_storage_); |
328 struct sockaddr* addr = | 369 struct sockaddr* addr = |
329 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | 370 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); |
330 | 371 |
331 WSABUF read_buffer; | 372 WSABUF read_buffer; |
332 read_buffer.buf = buf->data(); | 373 read_buffer.buf = buf->data(); |
333 read_buffer.len = buf_len; | 374 read_buffer.len = buf_len; |
334 | 375 |
335 DWORD flags = 0; | 376 DWORD flags = 0; |
336 DWORD num; | 377 DWORD num; |
337 AssertEventNotSignaled(read_overlapped_.hEvent); | 378 AssertEventNotSignaled(read_overlapped_.hEvent); |
338 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, | 379 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, |
339 &recv_addr_len_, &read_overlapped_, NULL); | 380 &recv_addr_len_, &read_overlapped_, NULL); |
340 if (rv == 0) { | 381 if (rv == 0) { |
341 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { | 382 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { |
342 if (!ProcessSuccessfulRead(num, address)) | 383 int result = num; |
343 return ERR_FAILED; | 384 // Convert address. |
344 return static_cast<int>(num); | 385 if (address && result >= 0) { |
| 386 if (!ReceiveAddressToIPEndpoint(address)) |
| 387 result = ERR_FAILED; |
| 388 } |
| 389 LogRead(result, buf->data()); |
| 390 return result; |
345 } | 391 } |
346 } else { | 392 } else { |
347 int os_error = WSAGetLastError(); | 393 int os_error = WSAGetLastError(); |
348 if (os_error != WSA_IO_PENDING) | 394 if (os_error != WSA_IO_PENDING) { |
349 return MapSystemError(os_error); | 395 int result = MapSystemError(os_error); |
| 396 LogRead(result, NULL); |
| 397 return result; |
| 398 } |
350 } | 399 } |
351 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); | 400 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); |
352 return ERR_IO_PENDING; | 401 return ERR_IO_PENDING; |
353 } | 402 } |
354 | 403 |
355 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 404 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, |
356 const IPEndPoint* address) { | 405 const IPEndPoint* address) { |
357 struct sockaddr_storage addr_storage; | 406 struct sockaddr_storage addr_storage; |
358 size_t addr_len = sizeof(addr_storage); | 407 size_t addr_len = sizeof(addr_storage); |
359 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | 408 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); |
360 | 409 |
361 // Convert address. | 410 // Convert address. |
362 if (!address) { | 411 if (!address) { |
363 addr = NULL; | 412 addr = NULL; |
364 addr_len = 0; | 413 addr_len = 0; |
365 } else { | 414 } else { |
366 if (!address->ToSockAddr(addr, &addr_len)) | 415 if (!address->ToSockAddr(addr, &addr_len)) { |
367 return ERR_FAILED; | 416 int result = ERR_FAILED; |
| 417 LogWrite(result, NULL, NULL); |
| 418 return result; |
| 419 } |
368 } | 420 } |
369 | 421 |
370 WSABUF write_buffer; | 422 WSABUF write_buffer; |
371 write_buffer.buf = buf->data(); | 423 write_buffer.buf = buf->data(); |
372 write_buffer.len = buf_len; | 424 write_buffer.len = buf_len; |
373 | 425 |
374 DWORD flags = 0; | 426 DWORD flags = 0; |
375 DWORD num; | 427 DWORD num; |
376 AssertEventNotSignaled(write_overlapped_.hEvent); | 428 AssertEventNotSignaled(write_overlapped_.hEvent); |
377 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 429 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, |
378 addr, addr_len, &write_overlapped_, NULL); | 430 addr, addr_len, &write_overlapped_, NULL); |
379 if (rv == 0) { | 431 if (rv == 0) { |
380 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { | 432 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { |
381 ProcessSuccessfulWrite(num); | 433 int result = num; |
382 return static_cast<int>(num); | 434 LogWrite(result, buf->data(), address); |
| 435 return result; |
383 } | 436 } |
384 } else { | 437 } else { |
385 int os_error = WSAGetLastError(); | 438 int os_error = WSAGetLastError(); |
386 if (os_error != WSA_IO_PENDING) | 439 if (os_error != WSA_IO_PENDING) { |
387 return MapSystemError(os_error); | 440 int result = MapSystemError(os_error); |
| 441 LogWrite(result, NULL, NULL); |
| 442 return result; |
| 443 } |
388 } | 444 } |
389 | 445 |
390 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 446 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); |
391 return ERR_IO_PENDING; | 447 return ERR_IO_PENDING; |
392 } | 448 } |
393 | 449 |
394 int UDPSocketWin::DoBind(const IPEndPoint& address) { | 450 int UDPSocketWin::DoBind(const IPEndPoint& address) { |
395 struct sockaddr_storage addr_storage; | 451 struct sockaddr_storage addr_storage; |
396 size_t addr_len = sizeof(addr_storage); | 452 size_t addr_len = sizeof(addr_storage); |
397 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | 453 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); |
(...skipping 10 matching lines...) Expand all Loading... |
408 IPAddressNumber ip(address.address().size()); | 464 IPAddressNumber ip(address.address().size()); |
409 | 465 |
410 for (int i = 0; i < kBindRetries; ++i) { | 466 for (int i = 0; i < kBindRetries; ++i) { |
411 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 467 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
412 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 468 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
413 return rv; | 469 return rv; |
414 } | 470 } |
415 return DoBind(IPEndPoint(ip, 0)); | 471 return DoBind(IPEndPoint(ip, 0)); |
416 } | 472 } |
417 | 473 |
| 474 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
| 475 const struct sockaddr* addr = |
| 476 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
| 477 return address->FromSockAddr(addr, recv_addr_len_); |
| 478 } |
| 479 |
418 } // namespace net | 480 } // namespace net |
OLD | NEW |