Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(883)

Side by Side Diff: net/udp/udp_socket_win.cc

Issue 10739002: Added broadcasting feature to UDP server sockets. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed Win code. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« net/udp/udp_socket_libevent.h ('K') | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 socket_options_(0),
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
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 rv = SetSocketOptions();
234 if (rv < 0)
235 return rv;
232 rv = DoBind(address); 236 rv = DoBind(address);
233 if (rv < 0) 237 if (rv < 0)
234 return rv; 238 return rv;
235 local_address_.reset(); 239 local_address_.reset();
236 return rv; 240 return rv;
237 } 241 }
238 242
239 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { 243 int UDPSocketWin::CreateSocket(const IPEndPoint& address) {
240 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 244 socket_ = WSASocket(address.GetFamily(), SOCK_DGRAM, IPPROTO_UDP, NULL, 0,
241 WSA_FLAG_OVERLAPPED); 245 WSA_FLAG_OVERLAPPED);
(...skipping 11 matching lines...) Expand all
253 } 257 }
254 258
255 bool UDPSocketWin::SetSendBufferSize(int32 size) { 259 bool UDPSocketWin::SetSendBufferSize(int32 size) {
256 DCHECK(CalledOnValidThread()); 260 DCHECK(CalledOnValidThread());
257 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 261 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
258 reinterpret_cast<const char*>(&size), sizeof(size)); 262 reinterpret_cast<const char*>(&size), sizeof(size));
259 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; 263 DCHECK(!rv) << "Could not set socket send buffer size: " << errno;
260 return rv == 0; 264 return rv == 0;
261 } 265 }
262 266
267 void UDPSocketWin::AllowAddressReuse() {
268 DCHECK(CalledOnValidThread());
269 DCHECK(!is_connected());
270
271 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
272 }
273
274 void UDPSocketWin::AllowBroadcast() {
275 DCHECK(CalledOnValidThread());
276 DCHECK(!is_connected());
277
278 socket_options_ |= SOCKET_OPTION_BROADCAST;
279 }
280
263 void UDPSocketWin::DoReadCallback(int rv) { 281 void UDPSocketWin::DoReadCallback(int rv) {
264 DCHECK_NE(rv, ERR_IO_PENDING); 282 DCHECK_NE(rv, ERR_IO_PENDING);
265 DCHECK(!read_callback_.is_null()); 283 DCHECK(!read_callback_.is_null());
266 284
267 // since Run may result in Read being called, clear read_callback_ up front. 285 // since Run may result in Read being called, clear read_callback_ up front.
268 CompletionCallback c = read_callback_; 286 CompletionCallback c = read_callback_;
269 read_callback_.Reset(); 287 read_callback_.Reset();
270 c.Run(rv); 288 c.Run(rv);
271 } 289 }
272 290
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 int result = MapSystemError(os_error); 442 int result = MapSystemError(os_error);
425 LogWrite(result, NULL, NULL); 443 LogWrite(result, NULL, NULL);
426 return result; 444 return result;
427 } 445 }
428 } 446 }
429 447
430 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); 448 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_);
431 return ERR_IO_PENDING; 449 return ERR_IO_PENDING;
432 } 450 }
433 451
452 int UDPSocketWin::SetSocketOptions() {
453 BOOL true_value = 1;
454 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
455 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
456 reinterpret_cast<const char*>(&true_value),
457 sizeof(true_value));
458 if (rv < 0)
459 return MapSystemError(errno);
460 }
461 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
462 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST,
463 reinterpret_cast<const char*>(&true_value),
464 sizeof(true_value));
465 if (rv < 0)
466 return MapSystemError(errno);
467 }
468 return OK;
469 }
470
434 int UDPSocketWin::DoBind(const IPEndPoint& address) { 471 int UDPSocketWin::DoBind(const IPEndPoint& address) {
435 SockaddrStorage storage; 472 SockaddrStorage storage;
436 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 473 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
437 return ERR_UNEXPECTED; 474 return ERR_UNEXPECTED;
438 int rv = bind(socket_, storage.addr, storage.addr_len); 475 int rv = bind(socket_, storage.addr, storage.addr_len);
439 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; 476 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv;
440 } 477 }
441 478
442 int UDPSocketWin::RandomBind(const IPEndPoint& address) { 479 int UDPSocketWin::RandomBind(const IPEndPoint& address) {
443 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); 480 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
444 481
445 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. 482 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s.
446 IPAddressNumber ip(address.address().size()); 483 IPAddressNumber ip(address.address().size());
447 484
448 for (int i = 0; i < kBindRetries; ++i) { 485 for (int i = 0; i < kBindRetries; ++i) {
449 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 486 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
450 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 487 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
451 return rv; 488 return rv;
452 } 489 }
453 return DoBind(IPEndPoint(ip, 0)); 490 return DoBind(IPEndPoint(ip, 0));
454 } 491 }
455 492
456 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { 493 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
457 const struct sockaddr* addr = 494 const struct sockaddr* addr =
458 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); 495 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_);
459 return address->FromSockAddr(addr, recv_addr_len_); 496 return address->FromSockAddr(addr, recv_addr_len_);
460 } 497 }
461 498
462 } // namespace net 499 } // namespace net
OLDNEW
« net/udp/udp_socket_libevent.h ('K') | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698