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

Side by Side Diff: net/udp/udp_socket_libevent.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
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_libevent.h" 5 #include "net/udp/udp_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 23 matching lines...) Expand all
34 } // namespace net 34 } // namespace net
35 35
36 namespace net { 36 namespace net {
37 37
38 UDPSocketLibevent::UDPSocketLibevent( 38 UDPSocketLibevent::UDPSocketLibevent(
39 DatagramSocket::BindType bind_type, 39 DatagramSocket::BindType bind_type,
40 const RandIntCallback& rand_int_cb, 40 const RandIntCallback& rand_int_cb,
41 net::NetLog* net_log, 41 net::NetLog* net_log,
42 const net::NetLog::Source& source) 42 const net::NetLog::Source& source)
43 : socket_(kInvalidSocket), 43 : socket_(kInvalidSocket),
44 socket_options_(0),
44 bind_type_(bind_type), 45 bind_type_(bind_type),
45 rand_int_cb_(rand_int_cb), 46 rand_int_cb_(rand_int_cb),
46 read_watcher_(this), 47 read_watcher_(this),
47 write_watcher_(this), 48 write_watcher_(this),
48 read_buf_len_(0), 49 read_buf_len_(0),
49 recv_from_address_(NULL), 50 recv_from_address_(NULL),
50 write_buf_len_(0), 51 write_buf_len_(0),
51 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { 52 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
52 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 53 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
53 source.ToEventParametersCallback()); 54 source.ToEventParametersCallback());
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 remote_address_.reset(new IPEndPoint(address)); 245 remote_address_.reset(new IPEndPoint(address));
245 return rv; 246 return rv;
246 } 247 }
247 248
248 int UDPSocketLibevent::Bind(const IPEndPoint& address) { 249 int UDPSocketLibevent::Bind(const IPEndPoint& address) {
249 DCHECK(CalledOnValidThread()); 250 DCHECK(CalledOnValidThread());
250 DCHECK(!is_connected()); 251 DCHECK(!is_connected());
251 int rv = CreateSocket(address); 252 int rv = CreateSocket(address);
252 if (rv < 0) 253 if (rv < 0)
253 return rv; 254 return rv;
255 rv = SetSocketOptions();
256 if (rv < 0)
257 return rv;
254 rv = DoBind(address); 258 rv = DoBind(address);
255 if (rv < 0) 259 if (rv < 0)
256 return rv; 260 return rv;
257 local_address_.reset(); 261 local_address_.reset();
258 return rv; 262 return rv;
259 } 263 }
260 264
261 bool UDPSocketLibevent::SetReceiveBufferSize(int32 size) { 265 bool UDPSocketLibevent::SetReceiveBufferSize(int32 size) {
262 DCHECK(CalledOnValidThread()); 266 DCHECK(CalledOnValidThread());
263 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 267 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
264 reinterpret_cast<const char*>(&size), sizeof(size)); 268 reinterpret_cast<const char*>(&size), sizeof(size));
265 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno; 269 DCHECK(!rv) << "Could not set socket receive buffer size: " << errno;
266 return rv == 0; 270 return rv == 0;
267 } 271 }
268 272
269 bool UDPSocketLibevent::SetSendBufferSize(int32 size) { 273 bool UDPSocketLibevent::SetSendBufferSize(int32 size) {
270 DCHECK(CalledOnValidThread()); 274 DCHECK(CalledOnValidThread());
271 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, 275 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
272 reinterpret_cast<const char*>(&size), sizeof(size)); 276 reinterpret_cast<const char*>(&size), sizeof(size));
273 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; 277 DCHECK(!rv) << "Could not set socket send buffer size: " << errno;
274 return rv == 0; 278 return rv == 0;
275 } 279 }
276 280
281 void UDPSocketLibevent::AllowAddressReuse() {
282 DCHECK(CalledOnValidThread());
283 DCHECK(!is_connected());
284
285 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS;
286 }
287
288 void UDPSocketLibevent::AllowBroadcast() {
289 DCHECK(CalledOnValidThread());
290 DCHECK(!is_connected());
291
292 socket_options_ |= SOCKET_OPTION_BROADCAST;
293 }
294
277 void UDPSocketLibevent::DoReadCallback(int rv) { 295 void UDPSocketLibevent::DoReadCallback(int rv) {
278 DCHECK_NE(rv, ERR_IO_PENDING); 296 DCHECK_NE(rv, ERR_IO_PENDING);
279 DCHECK(!read_callback_.is_null()); 297 DCHECK(!read_callback_.is_null());
280 298
281 // since Run may result in Read being called, clear read_callback_ up front. 299 // since Run may result in Read being called, clear read_callback_ up front.
282 CompletionCallback c = read_callback_; 300 CompletionCallback c = read_callback_;
283 read_callback_.Reset(); 301 read_callback_.Reset();
284 c.Run(rv); 302 c.Run(rv);
285 } 303 }
286 304
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 0, 441 0,
424 addr, 442 addr,
425 storage.addr_len)); 443 storage.addr_len));
426 if (result < 0) 444 if (result < 0)
427 result = MapSystemError(errno); 445 result = MapSystemError(errno);
428 if (result != ERR_IO_PENDING) 446 if (result != ERR_IO_PENDING)
429 LogWrite(result, buf->data(), address); 447 LogWrite(result, buf->data(), address);
430 return result; 448 return result;
431 } 449 }
432 450
451 int UDPSocketLibevent::SetSocketOptions() {
452 int true_value = 1;
453 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
454 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value,
455 sizeof(true_value));
456 if (rv < 0)
457 return MapSystemError(errno);
458 #if defined(SO_REUSEPORT)
459 rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &true_value,
460 sizeof(true_value));
461 if (rv < 0)
462 return MapSystemError(errno);
463 #endif
464 }
465 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
466 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value,
467 sizeof(true_value));
468 if (rv < 0)
469 return MapSystemError(errno);
470 }
471 return OK;
472 }
473
433 int UDPSocketLibevent::DoBind(const IPEndPoint& address) { 474 int UDPSocketLibevent::DoBind(const IPEndPoint& address) {
434 SockaddrStorage storage; 475 SockaddrStorage storage;
435 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 476 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
436 return ERR_UNEXPECTED; 477 return ERR_UNEXPECTED;
437 int rv = bind(socket_, storage.addr, storage.addr_len); 478 int rv = bind(socket_, storage.addr, storage.addr_len);
438 return rv < 0 ? MapSystemError(errno) : rv; 479 return rv < 0 ? MapSystemError(errno) : rv;
439 } 480 }
440 481
441 int UDPSocketLibevent::RandomBind(const IPEndPoint& address) { 482 int UDPSocketLibevent::RandomBind(const IPEndPoint& address) {
442 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); 483 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
443 484
444 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. 485 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s.
445 IPAddressNumber ip(address.address().size()); 486 IPAddressNumber ip(address.address().size());
446 487
447 for (int i = 0; i < kBindRetries; ++i) { 488 for (int i = 0; i < kBindRetries; ++i) {
448 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); 489 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd)));
449 if (rv == OK || rv != ERR_ADDRESS_IN_USE) 490 if (rv == OK || rv != ERR_ADDRESS_IN_USE)
450 return rv; 491 return rv;
451 } 492 }
452 return DoBind(IPEndPoint(ip, 0)); 493 return DoBind(IPEndPoint(ip, 0));
453 } 494 }
454 495
455 } // namespace net 496 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698