OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/callback.h" | 9 #include "base/callback.h" |
10 #include "base/eintr_wrapper.h" | 10 #include "base/eintr_wrapper.h" |
(...skipping 28 matching lines...) Expand all Loading... | |
39 void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { | 39 void UDPSocketWin::WriteDelegate::OnObjectSignaled(HANDLE object) { |
40 DCHECK_EQ(object, socket_->write_overlapped_.hEvent); | 40 DCHECK_EQ(object, socket_->write_overlapped_.hEvent); |
41 socket_->DidCompleteWrite(); | 41 socket_->DidCompleteWrite(); |
42 } | 42 } |
43 | 43 |
44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
45 const RandIntCallback& rand_int_cb, | 45 const RandIntCallback& rand_int_cb, |
46 net::NetLog* net_log, | 46 net::NetLog* net_log, |
47 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
48 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
49 allow_broadcast_(false), | |
49 bind_type_(bind_type), | 50 bind_type_(bind_type), |
50 rand_int_cb_(rand_int_cb), | 51 rand_int_cb_(rand_int_cb), |
51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 53 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
53 recv_from_address_(NULL), | 54 recv_from_address_(NULL), |
54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 55 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
55 EnsureWinsockInit(); | 56 EnsureWinsockInit(); |
56 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 57 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
57 source.ToEventParametersCallback()); | 58 source.ToEventParametersCallback()); |
58 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 59 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 | 223 |
223 remote_address_.reset(new IPEndPoint(address)); | 224 remote_address_.reset(new IPEndPoint(address)); |
224 return rv; | 225 return rv; |
225 } | 226 } |
226 | 227 |
227 int UDPSocketWin::Bind(const IPEndPoint& address) { | 228 int UDPSocketWin::Bind(const IPEndPoint& address) { |
228 DCHECK(!is_connected()); | 229 DCHECK(!is_connected()); |
229 int rv = CreateSocket(address); | 230 int rv = CreateSocket(address); |
230 if (rv < 0) | 231 if (rv < 0) |
231 return rv; | 232 return rv; |
233 if (allow_broadcast_) { | |
234 rv = DoBroadcast(); | |
235 if (rv < 0) | |
236 return rv; | |
237 } | |
232 rv = DoBind(address); | 238 rv = DoBind(address); |
233 if (rv < 0) | 239 if (rv < 0) |
234 return rv; | 240 return rv; |
235 local_address_.reset(); | 241 local_address_.reset(); |
236 return rv; | 242 return rv; |
237 } | 243 } |
238 | 244 |
239 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { | 245 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { |
240 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, | 246 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, |
241 WSA_FLAG_OVERLAPPED); | 247 WSA_FLAG_OVERLAPPED); |
(...skipping 11 matching lines...) Expand all Loading... | |
253 } | 259 } |
254 | 260 |
255 bool UDPSocketWin::SetSendBufferSize(int32 size) { | 261 bool UDPSocketWin::SetSendBufferSize(int32 size) { |
256 DCHECK(CalledOnValidThread()); | 262 DCHECK(CalledOnValidThread()); |
257 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 263 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
258 reinterpret_cast<const char*>(&size), sizeof(size)); | 264 reinterpret_cast<const char*>(&size), sizeof(size)); |
259 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 265 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
260 return rv == 0; | 266 return rv == 0; |
261 } | 267 } |
262 | 268 |
269 void UDPSocketWin::AllowBroadcast() { | |
270 DCHECK(CalledOnValidThread()); | |
271 DCHECK(!is_connected()); | |
272 | |
273 allow_broadcast_ = true; | |
274 } | |
275 | |
263 void UDPSocketWin::DoReadCallback(int rv) { | 276 void UDPSocketWin::DoReadCallback(int rv) { |
264 DCHECK_NE(rv, ERR_IO_PENDING); | 277 DCHECK_NE(rv, ERR_IO_PENDING); |
265 DCHECK(!read_callback_.is_null()); | 278 DCHECK(!read_callback_.is_null()); |
266 | 279 |
267 // since Run may result in Read being called, clear read_callback_ up front. | 280 // since Run may result in Read being called, clear read_callback_ up front. |
268 CompletionCallback c = read_callback_; | 281 CompletionCallback c = read_callback_; |
269 read_callback_.Reset(); | 282 read_callback_.Reset(); |
270 c.Run(rv); | 283 c.Run(rv); |
271 } | 284 } |
272 | 285 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 int result = MapSystemError(os_error); | 437 int result = MapSystemError(os_error); |
425 LogWrite(result, NULL, NULL); | 438 LogWrite(result, NULL, NULL); |
426 return result; | 439 return result; |
427 } | 440 } |
428 } | 441 } |
429 | 442 |
430 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 443 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); |
431 return ERR_IO_PENDING; | 444 return ERR_IO_PENDING; |
432 } | 445 } |
433 | 446 |
447 int UDPSocketWin::DoBroadcast() { | |
448 int true_value = 1; | |
wtc
2012/07/11 18:26:37
It looks nicer to use the BOOL type here:
http://m
ygorshenin1
2012/07/12 09:28:08
Done.
| |
449 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, | |
450 reinterpret_cast<const char*>(&true_value), | |
451 sizeof(true_value)); | |
452 if (rv < 0) | |
453 return MapSystemError(errno); | |
454 rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, | |
455 reinterpret_cast<const char*>(&true_value), | |
456 sizeof(true_value)); | |
457 if (rv < 0) | |
458 return MapSystemError(errno); | |
459 return OK; | |
460 } | |
461 | |
434 int UDPSocketWin::DoBind(const IPEndPoint& address) { | 462 int UDPSocketWin::DoBind(const IPEndPoint& address) { |
435 SockaddrStorage storage; | 463 SockaddrStorage storage; |
436 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) | 464 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
437 return ERR_UNEXPECTED; | 465 return ERR_UNEXPECTED; |
438 int rv = bind(socket_, storage.addr, storage.addr_len); | 466 int rv = bind(socket_, storage.addr, storage.addr_len); |
439 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; | 467 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; |
440 } | 468 } |
441 | 469 |
442 int UDPSocketWin::RandomBind(const IPEndPoint& address) { | 470 int UDPSocketWin::RandomBind(const IPEndPoint& address) { |
443 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); | 471 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); |
444 | 472 |
445 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. | 473 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. |
446 IPAddressNumber ip(address.address().size()); | 474 IPAddressNumber ip(address.address().size()); |
447 | 475 |
448 for (int i = 0; i < kBindRetries; ++i) { | 476 for (int i = 0; i < kBindRetries; ++i) { |
449 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 477 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
450 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 478 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
451 return rv; | 479 return rv; |
452 } | 480 } |
453 return DoBind(IPEndPoint(ip, 0)); | 481 return DoBind(IPEndPoint(ip, 0)); |
454 } | 482 } |
455 | 483 |
456 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 484 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
457 const struct sockaddr* addr = | 485 const struct sockaddr* addr = |
458 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 486 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
459 return address->FromSockAddr(addr, recv_addr_len_); | 487 return address->FromSockAddr(addr, recv_addr_len_); |
460 } | 488 } |
461 | 489 |
462 } // namespace net | 490 } // namespace net |
OLD | NEW |