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

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: Added MacOS specific 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.cc ('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 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
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
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
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
OLDNEW
« net/udp/udp_socket_libevent.cc ('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