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

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

Issue 2508593002: net: move udp directory into socket (Closed)
Patch Set: revert sys/socket.h change Created 4 years, 1 month 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
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | remoting/protocol/chromium_socket_factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/udp/udp_socket_win.h"
6
7 #include <mstcpip.h>
8
9 #include "base/callback.h"
10 #include "base/lazy_instance.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/sparse_histogram.h"
16 #include "base/rand_util.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/ip_address.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/network_activity_monitor.h"
22 #include "net/base/network_change_notifier.h"
23 #include "net/base/sockaddr_storage.h"
24 #include "net/base/winsock_init.h"
25 #include "net/base/winsock_util.h"
26 #include "net/log/net_log.h"
27 #include "net/log/net_log_event_type.h"
28 #include "net/log/net_log_source.h"
29 #include "net/log/net_log_source_type.h"
30 #include "net/socket/socket_descriptor.h"
31 #include "net/udp/udp_net_log_parameters.h"
32
33 namespace {
34
35 const int kBindRetries = 10;
36 const int kPortStart = 1024;
37 const int kPortEnd = 65535;
38
39 } // namespace
40
41 namespace net {
42
43 // This class encapsulates all the state that has to be preserved as long as
44 // there is a network IO operation in progress. If the owner UDPSocketWin
45 // is destroyed while an operation is in progress, the Core is detached and it
46 // lives until the operation completes and the OS doesn't reference any resource
47 // declared on this class anymore.
48 class UDPSocketWin::Core : public base::RefCounted<Core> {
49 public:
50 explicit Core(UDPSocketWin* socket);
51
52 // Start watching for the end of a read or write operation.
53 void WatchForRead();
54 void WatchForWrite();
55
56 // The UDPSocketWin is going away.
57 void Detach() { socket_ = NULL; }
58
59 // The separate OVERLAPPED variables for asynchronous operation.
60 OVERLAPPED read_overlapped_;
61 OVERLAPPED write_overlapped_;
62
63 // The buffers used in Read() and Write().
64 scoped_refptr<IOBuffer> read_iobuffer_;
65 scoped_refptr<IOBuffer> write_iobuffer_;
66
67 // The address storage passed to WSARecvFrom().
68 SockaddrStorage recv_addr_storage_;
69
70 private:
71 friend class base::RefCounted<Core>;
72
73 class ReadDelegate : public base::win::ObjectWatcher::Delegate {
74 public:
75 explicit ReadDelegate(Core* core) : core_(core) {}
76 ~ReadDelegate() override {}
77
78 // base::ObjectWatcher::Delegate methods:
79 void OnObjectSignaled(HANDLE object) override;
80
81 private:
82 Core* const core_;
83 };
84
85 class WriteDelegate : public base::win::ObjectWatcher::Delegate {
86 public:
87 explicit WriteDelegate(Core* core) : core_(core) {}
88 ~WriteDelegate() override {}
89
90 // base::ObjectWatcher::Delegate methods:
91 void OnObjectSignaled(HANDLE object) override;
92
93 private:
94 Core* const core_;
95 };
96
97 ~Core();
98
99 // The socket that created this object.
100 UDPSocketWin* socket_;
101
102 // |reader_| handles the signals from |read_watcher_|.
103 ReadDelegate reader_;
104 // |writer_| handles the signals from |write_watcher_|.
105 WriteDelegate writer_;
106
107 // |read_watcher_| watches for events from Read().
108 base::win::ObjectWatcher read_watcher_;
109 // |write_watcher_| watches for events from Write();
110 base::win::ObjectWatcher write_watcher_;
111
112 DISALLOW_COPY_AND_ASSIGN(Core);
113 };
114
115 UDPSocketWin::Core::Core(UDPSocketWin* socket)
116 : socket_(socket),
117 reader_(this),
118 writer_(this) {
119 memset(&read_overlapped_, 0, sizeof(read_overlapped_));
120 memset(&write_overlapped_, 0, sizeof(write_overlapped_));
121
122 read_overlapped_.hEvent = WSACreateEvent();
123 write_overlapped_.hEvent = WSACreateEvent();
124 }
125
126 UDPSocketWin::Core::~Core() {
127 // Make sure the message loop is not watching this object anymore.
128 read_watcher_.StopWatching();
129 write_watcher_.StopWatching();
130
131 WSACloseEvent(read_overlapped_.hEvent);
132 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_));
133 WSACloseEvent(write_overlapped_.hEvent);
134 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_));
135 }
136
137 void UDPSocketWin::Core::WatchForRead() {
138 // We grab an extra reference because there is an IO operation in progress.
139 // Balanced in ReadDelegate::OnObjectSignaled().
140 AddRef();
141 read_watcher_.StartWatchingOnce(read_overlapped_.hEvent, &reader_);
142 }
143
144 void UDPSocketWin::Core::WatchForWrite() {
145 // We grab an extra reference because there is an IO operation in progress.
146 // Balanced in WriteDelegate::OnObjectSignaled().
147 AddRef();
148 write_watcher_.StartWatchingOnce(write_overlapped_.hEvent, &writer_);
149 }
150
151 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) {
152 DCHECK_EQ(object, core_->read_overlapped_.hEvent);
153 if (core_->socket_)
154 core_->socket_->DidCompleteRead();
155
156 core_->Release();
157 }
158
159 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) {
160 DCHECK_EQ(object, core_->write_overlapped_.hEvent);
161 if (core_->socket_)
162 core_->socket_->DidCompleteWrite();
163
164 core_->Release();
165 }
166 //-----------------------------------------------------------------------------
167
168 QwaveAPI::QwaveAPI() : qwave_supported_(false) {
169 HMODULE qwave = LoadLibrary(L"qwave.dll");
170 if (!qwave)
171 return;
172 create_handle_func_ =
173 (CreateHandleFn)GetProcAddress(qwave, "QOSCreateHandle");
174 close_handle_func_ =
175 (CloseHandleFn)GetProcAddress(qwave, "QOSCloseHandle");
176 add_socket_to_flow_func_ =
177 (AddSocketToFlowFn)GetProcAddress(qwave, "QOSAddSocketToFlow");
178 remove_socket_from_flow_func_ =
179 (RemoveSocketFromFlowFn)GetProcAddress(qwave, "QOSRemoveSocketFromFlow");
180 set_flow_func_ = (SetFlowFn)GetProcAddress(qwave, "QOSSetFlow");
181
182 if (create_handle_func_ && close_handle_func_ &&
183 add_socket_to_flow_func_ && remove_socket_from_flow_func_ &&
184 set_flow_func_) {
185 qwave_supported_ = true;
186 }
187 }
188
189 QwaveAPI& QwaveAPI::Get() {
190 static base::LazyInstance<QwaveAPI>::Leaky lazy_qwave =
191 LAZY_INSTANCE_INITIALIZER;
192 return lazy_qwave.Get();
193 }
194
195 bool QwaveAPI::qwave_supported() const {
196 return qwave_supported_;
197 }
198 BOOL QwaveAPI::CreateHandle(PQOS_VERSION version, PHANDLE handle) {
199 return create_handle_func_(version, handle);
200 }
201 BOOL QwaveAPI::CloseHandle(HANDLE handle) {
202 return close_handle_func_(handle);
203 }
204
205 BOOL QwaveAPI::AddSocketToFlow(HANDLE handle,
206 SOCKET socket,
207 PSOCKADDR addr,
208 QOS_TRAFFIC_TYPE traffic_type,
209 DWORD flags,
210 PQOS_FLOWID flow_id) {
211 return add_socket_to_flow_func_(handle,
212 socket,
213 addr,
214 traffic_type,
215 flags,
216 flow_id);
217 }
218
219 BOOL QwaveAPI::RemoveSocketFromFlow(HANDLE handle,
220 SOCKET socket,
221 QOS_FLOWID flow_id,
222 DWORD reserved) {
223 return remove_socket_from_flow_func_(handle, socket, flow_id, reserved);
224 }
225
226 BOOL QwaveAPI::SetFlow(HANDLE handle,
227 QOS_FLOWID flow_id,
228 QOS_SET_FLOW op,
229 ULONG size,
230 PVOID data,
231 DWORD reserved,
232 LPOVERLAPPED overlapped) {
233 return set_flow_func_(handle,
234 flow_id,
235 op,
236 size,
237 data,
238 reserved,
239 overlapped);
240 }
241
242
243 //-----------------------------------------------------------------------------
244
245 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
246 const RandIntCallback& rand_int_cb,
247 net::NetLog* net_log,
248 const net::NetLogSource& source)
249 : socket_(INVALID_SOCKET),
250 addr_family_(0),
251 is_connected_(false),
252 socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
253 multicast_interface_(0),
254 multicast_time_to_live_(1),
255 bind_type_(bind_type),
256 rand_int_cb_(rand_int_cb),
257 use_non_blocking_io_(false),
258 read_iobuffer_len_(0),
259 write_iobuffer_len_(0),
260 recv_from_address_(NULL),
261 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)),
262 qos_handle_(NULL),
263 qos_flow_id_(0) {
264 EnsureWinsockInit();
265 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE,
266 source.ToEventParametersCallback());
267 if (bind_type == DatagramSocket::RANDOM_BIND)
268 DCHECK(!rand_int_cb.is_null());
269 }
270
271 UDPSocketWin::~UDPSocketWin() {
272 Close();
273 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE);
274 }
275
276 int UDPSocketWin::Open(AddressFamily address_family) {
277 DCHECK(CalledOnValidThread());
278 DCHECK_EQ(socket_, INVALID_SOCKET);
279
280 addr_family_ = ConvertAddressFamily(address_family);
281 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP);
282 if (socket_ == INVALID_SOCKET)
283 return MapSystemError(WSAGetLastError());
284 if (!use_non_blocking_io_) {
285 core_ = new Core(this);
286 } else {
287 read_write_event_.Set(WSACreateEvent());
288 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE);
289 }
290 return OK;
291 }
292
293 void UDPSocketWin::Close() {
294 DCHECK(CalledOnValidThread());
295
296 if (socket_ == INVALID_SOCKET)
297 return;
298
299 if (qos_handle_) {
300 QwaveAPI::Get().CloseHandle(qos_handle_);
301 }
302
303 // Zero out any pending read/write callback state.
304 read_callback_.Reset();
305 recv_from_address_ = NULL;
306 write_callback_.Reset();
307
308 base::TimeTicks start_time = base::TimeTicks::Now();
309 closesocket(socket_);
310 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose",
311 base::TimeTicks::Now() - start_time);
312 socket_ = INVALID_SOCKET;
313 addr_family_ = 0;
314 is_connected_ = false;
315
316 read_write_watcher_.StopWatching();
317 read_write_event_.Close();
318
319 if (core_) {
320 core_->Detach();
321 core_ = NULL;
322 }
323 }
324
325 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const {
326 DCHECK(CalledOnValidThread());
327 DCHECK(address);
328 if (!is_connected())
329 return ERR_SOCKET_NOT_CONNECTED;
330
331 // TODO(szym): Simplify. http://crbug.com/126152
332 if (!remote_address_.get()) {
333 SockaddrStorage storage;
334 if (getpeername(socket_, storage.addr, &storage.addr_len))
335 return MapSystemError(WSAGetLastError());
336 std::unique_ptr<IPEndPoint> remote_address(new IPEndPoint());
337 if (!remote_address->FromSockAddr(storage.addr, storage.addr_len))
338 return ERR_ADDRESS_INVALID;
339 remote_address_.reset(remote_address.release());
340 }
341
342 *address = *remote_address_;
343 return OK;
344 }
345
346 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const {
347 DCHECK(CalledOnValidThread());
348 DCHECK(address);
349 if (!is_connected())
350 return ERR_SOCKET_NOT_CONNECTED;
351
352 // TODO(szym): Simplify. http://crbug.com/126152
353 if (!local_address_.get()) {
354 SockaddrStorage storage;
355 if (getsockname(socket_, storage.addr, &storage.addr_len))
356 return MapSystemError(WSAGetLastError());
357 std::unique_ptr<IPEndPoint> local_address(new IPEndPoint());
358 if (!local_address->FromSockAddr(storage.addr, storage.addr_len))
359 return ERR_ADDRESS_INVALID;
360 local_address_.reset(local_address.release());
361 net_log_.AddEvent(NetLogEventType::UDP_LOCAL_ADDRESS,
362 CreateNetLogUDPConnectCallback(
363 local_address_.get(),
364 NetworkChangeNotifier::kInvalidNetworkHandle));
365 }
366
367 *address = *local_address_;
368 return OK;
369 }
370
371 int UDPSocketWin::Read(IOBuffer* buf,
372 int buf_len,
373 const CompletionCallback& callback) {
374 return RecvFrom(buf, buf_len, NULL, callback);
375 }
376
377 int UDPSocketWin::RecvFrom(IOBuffer* buf,
378 int buf_len,
379 IPEndPoint* address,
380 const CompletionCallback& callback) {
381 DCHECK(CalledOnValidThread());
382 DCHECK_NE(INVALID_SOCKET, socket_);
383 CHECK(read_callback_.is_null());
384 DCHECK(!recv_from_address_);
385 DCHECK(!callback.is_null()); // Synchronous operation not supported.
386 DCHECK_GT(buf_len, 0);
387
388 int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address)
389 : InternalRecvFromNonBlocking(buf, buf_len, address);
390 if (nread != ERR_IO_PENDING)
391 return nread;
392
393 read_callback_ = callback;
394 recv_from_address_ = address;
395 return ERR_IO_PENDING;
396 }
397
398 int UDPSocketWin::Write(IOBuffer* buf,
399 int buf_len,
400 const CompletionCallback& callback) {
401 return SendToOrWrite(buf, buf_len, remote_address_.get(), callback);
402 }
403
404 int UDPSocketWin::SendTo(IOBuffer* buf,
405 int buf_len,
406 const IPEndPoint& address,
407 const CompletionCallback& callback) {
408 return SendToOrWrite(buf, buf_len, &address, callback);
409 }
410
411 int UDPSocketWin::SendToOrWrite(IOBuffer* buf,
412 int buf_len,
413 const IPEndPoint* address,
414 const CompletionCallback& callback) {
415 DCHECK(CalledOnValidThread());
416 DCHECK_NE(INVALID_SOCKET, socket_);
417 CHECK(write_callback_.is_null());
418 DCHECK(!callback.is_null()); // Synchronous operation not supported.
419 DCHECK_GT(buf_len, 0);
420 DCHECK(!send_to_address_.get());
421
422 int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address)
423 : InternalSendToNonBlocking(buf, buf_len, address);
424 if (nwrite != ERR_IO_PENDING)
425 return nwrite;
426
427 if (address)
428 send_to_address_.reset(new IPEndPoint(*address));
429 write_callback_ = callback;
430 return ERR_IO_PENDING;
431 }
432
433 int UDPSocketWin::Connect(const IPEndPoint& address) {
434 DCHECK_NE(socket_, INVALID_SOCKET);
435 net_log_.BeginEvent(
436 NetLogEventType::UDP_CONNECT,
437 CreateNetLogUDPConnectCallback(
438 &address, NetworkChangeNotifier::kInvalidNetworkHandle));
439 int rv = InternalConnect(address);
440 net_log_.EndEventWithNetErrorCode(NetLogEventType::UDP_CONNECT, rv);
441 is_connected_ = (rv == OK);
442 return rv;
443 }
444
445 int UDPSocketWin::InternalConnect(const IPEndPoint& address) {
446 DCHECK(!is_connected());
447 DCHECK(!remote_address_.get());
448
449 int rv = 0;
450 if (bind_type_ == DatagramSocket::RANDOM_BIND) {
451 // Construct IPAddress of appropriate size (IPv4 or IPv6) of 0s,
452 // representing INADDR_ANY or in6addr_any.
453 size_t addr_size = (address.GetSockAddrFamily() == AF_INET)
454 ? IPAddress::kIPv4AddressSize
455 : IPAddress::kIPv6AddressSize;
456 rv = RandomBind(IPAddress::AllZeros(addr_size));
457 }
458 // else connect() does the DatagramSocket::DEFAULT_BIND
459
460 if (rv < 0) {
461 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", -rv);
462 return rv;
463 }
464
465 SockaddrStorage storage;
466 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
467 return ERR_ADDRESS_INVALID;
468
469 rv = connect(socket_, storage.addr, storage.addr_len);
470 if (rv < 0)
471 return MapSystemError(WSAGetLastError());
472
473 remote_address_.reset(new IPEndPoint(address));
474 return rv;
475 }
476
477 int UDPSocketWin::Bind(const IPEndPoint& address) {
478 DCHECK_NE(socket_, INVALID_SOCKET);
479 DCHECK(!is_connected());
480
481 int rv = SetMulticastOptions();
482 if (rv < 0)
483 return rv;
484
485 rv = DoBind(address);
486 if (rv < 0)
487 return rv;
488
489 local_address_.reset();
490 is_connected_ = true;
491 return rv;
492 }
493
494 int UDPSocketWin::BindToNetwork(NetworkChangeNotifier::NetworkHandle network) {
495 NOTIMPLEMENTED();
496 return ERR_NOT_IMPLEMENTED;
497 }
498
499 int UDPSocketWin::SetReceiveBufferSize(int32_t size) {
500 DCHECK_NE(socket_, INVALID_SOCKET);
501 DCHECK(CalledOnValidThread());
502 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
503 reinterpret_cast<const char*>(&size), sizeof(size));
504 if (rv != 0)
505 return MapSystemError(WSAGetLastError());
506
507 // According to documentation, setsockopt may succeed, but we need to check
508 // the results via getsockopt to be sure it works on Windows.
509 int32_t actual_size = 0;
510 int option_size = sizeof(actual_size);
511 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
512 reinterpret_cast<char*>(&actual_size), &option_size);
513 if (rv != 0)
514 return MapSystemError(WSAGetLastError());
515 if (actual_size >= size)
516 return OK;
517 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer",
518 actual_size, 1000, 1000000, 50);
519 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE;
520 }
521
522 int UDPSocketWin::SetSendBufferSize(int32_t size) {
523 DCHECK_NE(socket_, INVALID_SOCKET);
524 DCHECK(CalledOnValidThread());
525 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
526 reinterpret_cast<const char*>(&size), sizeof(size));
527 if (rv != 0)
528 return MapSystemError(WSAGetLastError());
529 // According to documentation, setsockopt may succeed, but we need to check
530 // the results via getsockopt to be sure it works on Windows.
531 int32_t actual_size = 0;
532 int option_size = sizeof(actual_size);
533 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
534 reinterpret_cast<char*>(&actual_size), &option_size);
535 if (rv != 0)
536 return MapSystemError(WSAGetLastError());
537 if (actual_size >= size)
538 return OK;
539 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer",
540 actual_size, 1000, 1000000, 50);
541 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE;
542 }
543
544 int UDPSocketWin::SetDoNotFragment() {
545 DCHECK_NE(socket_, INVALID_SOCKET);
546 DCHECK(CalledOnValidThread());
547
548 if (addr_family_ == AF_INET6)
549 return OK;
550
551 DWORD val = 1;
552 int rv = setsockopt(socket_, IPPROTO_IP, IP_DONTFRAGMENT,
553 reinterpret_cast<const char*>(&val), sizeof(val));
554 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
555 }
556
557 int UDPSocketWin::AllowAddressReuse() {
558 DCHECK_NE(socket_, INVALID_SOCKET);
559 DCHECK(CalledOnValidThread());
560 DCHECK(!is_connected());
561
562 BOOL true_value = TRUE;
563 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
564 reinterpret_cast<const char*>(&true_value),
565 sizeof(true_value));
566 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
567 }
568
569 int UDPSocketWin::SetBroadcast(bool broadcast) {
570 DCHECK_NE(socket_, INVALID_SOCKET);
571 DCHECK(CalledOnValidThread());
572
573 BOOL value = broadcast ? TRUE : FALSE;
574 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST,
575 reinterpret_cast<const char*>(&value), sizeof(value));
576 return rv == 0 ? OK : MapSystemError(WSAGetLastError());
577 }
578
579 void UDPSocketWin::DoReadCallback(int rv) {
580 DCHECK_NE(rv, ERR_IO_PENDING);
581 DCHECK(!read_callback_.is_null());
582
583 // since Run may result in Read being called, clear read_callback_ up front.
584 CompletionCallback c = read_callback_;
585 read_callback_.Reset();
586 c.Run(rv);
587 }
588
589 void UDPSocketWin::DoWriteCallback(int rv) {
590 DCHECK_NE(rv, ERR_IO_PENDING);
591 DCHECK(!write_callback_.is_null());
592
593 // since Run may result in Write being called, clear write_callback_ up front.
594 CompletionCallback c = write_callback_;
595 write_callback_.Reset();
596 c.Run(rv);
597 }
598
599 void UDPSocketWin::DidCompleteRead() {
600 DWORD num_bytes, flags;
601 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_,
602 &num_bytes, FALSE, &flags);
603 WSAResetEvent(core_->read_overlapped_.hEvent);
604 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
605 // Convert address.
606 IPEndPoint address;
607 IPEndPoint* address_to_log = NULL;
608 if (result >= 0) {
609 if (address.FromSockAddr(core_->recv_addr_storage_.addr,
610 core_->recv_addr_storage_.addr_len)) {
611 if (recv_from_address_)
612 *recv_from_address_ = address;
613 address_to_log = &address;
614 } else {
615 result = ERR_ADDRESS_INVALID;
616 }
617 }
618 LogRead(result, core_->read_iobuffer_->data(), address_to_log);
619 core_->read_iobuffer_ = NULL;
620 recv_from_address_ = NULL;
621 DoReadCallback(result);
622 }
623
624 void UDPSocketWin::DidCompleteWrite() {
625 DWORD num_bytes, flags;
626 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_,
627 &num_bytes, FALSE, &flags);
628 WSAResetEvent(core_->write_overlapped_.hEvent);
629 int result = ok ? num_bytes : MapSystemError(WSAGetLastError());
630 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get());
631
632 send_to_address_.reset();
633 core_->write_iobuffer_ = NULL;
634 DoWriteCallback(result);
635 }
636
637 void UDPSocketWin::OnObjectSignaled(HANDLE object) {
638 DCHECK(object == read_write_event_.Get());
639 WSANETWORKEVENTS network_events;
640 int os_error = 0;
641 int rv =
642 WSAEnumNetworkEvents(socket_, read_write_event_.Get(), &network_events);
643 if (rv == SOCKET_ERROR) {
644 os_error = WSAGetLastError();
645 rv = MapSystemError(os_error);
646 if (read_iobuffer_) {
647 read_iobuffer_ = NULL;
648 read_iobuffer_len_ = 0;
649 recv_from_address_ = NULL;
650 DoReadCallback(rv);
651 }
652 if (write_iobuffer_) {
653 write_iobuffer_ = NULL;
654 write_iobuffer_len_ = 0;
655 send_to_address_.reset();
656 DoWriteCallback(rv);
657 }
658 return;
659 }
660 if ((network_events.lNetworkEvents & FD_READ) && read_iobuffer_) {
661 OnReadSignaled();
662 }
663 if ((network_events.lNetworkEvents & FD_WRITE) && write_iobuffer_) {
664 OnWriteSignaled();
665 }
666
667 // There's still pending read / write. Watch for further events.
668 if (read_iobuffer_ || write_iobuffer_) {
669 WatchForReadWrite();
670 }
671 }
672
673 void UDPSocketWin::OnReadSignaled() {
674 int rv = InternalRecvFromNonBlocking(read_iobuffer_.get(), read_iobuffer_len_,
675 recv_from_address_);
676 if (rv == ERR_IO_PENDING)
677 return;
678 read_iobuffer_ = NULL;
679 read_iobuffer_len_ = 0;
680 recv_from_address_ = NULL;
681 DoReadCallback(rv);
682 }
683
684 void UDPSocketWin::OnWriteSignaled() {
685 int rv = InternalSendToNonBlocking(write_iobuffer_.get(), write_iobuffer_len_,
686 send_to_address_.get());
687 if (rv == ERR_IO_PENDING)
688 return;
689 write_iobuffer_ = NULL;
690 write_iobuffer_len_ = 0;
691 send_to_address_.reset();
692 DoWriteCallback(rv);
693 }
694
695 void UDPSocketWin::WatchForReadWrite() {
696 if (read_write_watcher_.IsWatching())
697 return;
698 bool watched =
699 read_write_watcher_.StartWatchingOnce(read_write_event_.Get(), this);
700 DCHECK(watched);
701 }
702
703 void UDPSocketWin::LogRead(int result,
704 const char* bytes,
705 const IPEndPoint* address) const {
706 if (result < 0) {
707 net_log_.AddEventWithNetErrorCode(NetLogEventType::UDP_RECEIVE_ERROR,
708 result);
709 return;
710 }
711
712 if (net_log_.IsCapturing()) {
713 net_log_.AddEvent(
714 NetLogEventType::UDP_BYTES_RECEIVED,
715 CreateNetLogUDPDataTranferCallback(result, bytes, address));
716 }
717
718 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result);
719 }
720
721 void UDPSocketWin::LogWrite(int result,
722 const char* bytes,
723 const IPEndPoint* address) const {
724 if (result < 0) {
725 net_log_.AddEventWithNetErrorCode(NetLogEventType::UDP_SEND_ERROR, result);
726 return;
727 }
728
729 if (net_log_.IsCapturing()) {
730 net_log_.AddEvent(
731 NetLogEventType::UDP_BYTES_SENT,
732 CreateNetLogUDPDataTranferCallback(result, bytes, address));
733 }
734
735 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result);
736 }
737
738 int UDPSocketWin::InternalRecvFromOverlapped(IOBuffer* buf,
739 int buf_len,
740 IPEndPoint* address) {
741 DCHECK(!core_->read_iobuffer_.get());
742 SockaddrStorage& storage = core_->recv_addr_storage_;
743 storage.addr_len = sizeof(storage.addr_storage);
744
745 WSABUF read_buffer;
746 read_buffer.buf = buf->data();
747 read_buffer.len = buf_len;
748
749 DWORD flags = 0;
750 DWORD num;
751 CHECK_NE(INVALID_SOCKET, socket_);
752 AssertEventNotSignaled(core_->read_overlapped_.hEvent);
753 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr,
754 &storage.addr_len, &core_->read_overlapped_, NULL);
755 if (rv == 0) {
756 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) {
757 int result = num;
758 // Convert address.
759 IPEndPoint address_storage;
760 IPEndPoint* address_to_log = NULL;
761 if (result >= 0) {
762 if (address_storage.FromSockAddr(core_->recv_addr_storage_.addr,
763 core_->recv_addr_storage_.addr_len)) {
764 if (address)
765 *address = address_storage;
766 address_to_log = &address_storage;
767 } else {
768 result = ERR_ADDRESS_INVALID;
769 }
770 }
771 LogRead(result, buf->data(), address_to_log);
772 return result;
773 }
774 } else {
775 int os_error = WSAGetLastError();
776 if (os_error != WSA_IO_PENDING) {
777 int result = MapSystemError(os_error);
778 LogRead(result, NULL, NULL);
779 return result;
780 }
781 }
782 core_->WatchForRead();
783 core_->read_iobuffer_ = buf;
784 return ERR_IO_PENDING;
785 }
786
787 int UDPSocketWin::InternalSendToOverlapped(IOBuffer* buf,
788 int buf_len,
789 const IPEndPoint* address) {
790 DCHECK(!core_->write_iobuffer_.get());
791 SockaddrStorage storage;
792 struct sockaddr* addr = storage.addr;
793 // Convert address.
794 if (!address) {
795 addr = NULL;
796 storage.addr_len = 0;
797 } else {
798 if (!address->ToSockAddr(addr, &storage.addr_len)) {
799 int result = ERR_ADDRESS_INVALID;
800 LogWrite(result, NULL, NULL);
801 return result;
802 }
803 }
804
805 WSABUF write_buffer;
806 write_buffer.buf = buf->data();
807 write_buffer.len = buf_len;
808
809 DWORD flags = 0;
810 DWORD num;
811 AssertEventNotSignaled(core_->write_overlapped_.hEvent);
812 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags,
813 addr, storage.addr_len, &core_->write_overlapped_, NULL);
814 if (rv == 0) {
815 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) {
816 int result = num;
817 LogWrite(result, buf->data(), address);
818 return result;
819 }
820 } else {
821 int os_error = WSAGetLastError();
822 if (os_error != WSA_IO_PENDING) {
823 int result = MapSystemError(os_error);
824 LogWrite(result, NULL, NULL);
825 return result;
826 }
827 }
828
829 core_->WatchForWrite();
830 core_->write_iobuffer_ = buf;
831 return ERR_IO_PENDING;
832 }
833
834 int UDPSocketWin::InternalRecvFromNonBlocking(IOBuffer* buf,
835 int buf_len,
836 IPEndPoint* address) {
837 DCHECK(!read_iobuffer_ || read_iobuffer_.get() == buf);
838 SockaddrStorage storage;
839 storage.addr_len = sizeof(storage.addr_storage);
840
841 CHECK_NE(INVALID_SOCKET, socket_);
842 int rv = recvfrom(socket_, buf->data(), buf_len, 0, storage.addr,
843 &storage.addr_len);
844 if (rv == SOCKET_ERROR) {
845 int os_error = WSAGetLastError();
846 if (os_error == WSAEWOULDBLOCK) {
847 read_iobuffer_ = buf;
848 read_iobuffer_len_ = buf_len;
849 WatchForReadWrite();
850 return ERR_IO_PENDING;
851 }
852 rv = MapSystemError(os_error);
853 LogRead(rv, NULL, NULL);
854 return rv;
855 }
856 IPEndPoint address_storage;
857 IPEndPoint* address_to_log = NULL;
858 if (rv >= 0) {
859 if (address_storage.FromSockAddr(storage.addr, storage.addr_len)) {
860 if (address)
861 *address = address_storage;
862 address_to_log = &address_storage;
863 } else {
864 rv = ERR_ADDRESS_INVALID;
865 }
866 }
867 LogRead(rv, buf->data(), address_to_log);
868 return rv;
869 }
870
871 int UDPSocketWin::InternalSendToNonBlocking(IOBuffer* buf,
872 int buf_len,
873 const IPEndPoint* address) {
874 DCHECK(!write_iobuffer_ || write_iobuffer_.get() == buf);
875 SockaddrStorage storage;
876 struct sockaddr* addr = storage.addr;
877 // Convert address.
878 if (address) {
879 if (!address->ToSockAddr(addr, &storage.addr_len)) {
880 int result = ERR_ADDRESS_INVALID;
881 LogWrite(result, NULL, NULL);
882 return result;
883 }
884 } else {
885 addr = NULL;
886 storage.addr_len = 0;
887 }
888
889 int rv = sendto(socket_, buf->data(), buf_len, 0, addr, storage.addr_len);
890 if (rv == SOCKET_ERROR) {
891 int os_error = WSAGetLastError();
892 if (os_error == WSAEWOULDBLOCK) {
893 write_iobuffer_ = buf;
894 write_iobuffer_len_ = buf_len;
895 WatchForReadWrite();
896 return ERR_IO_PENDING;
897 }
898 rv = MapSystemError(os_error);
899 LogWrite(rv, NULL, NULL);
900 return rv;
901 }
902 LogWrite(rv, buf->data(), address);
903 return rv;
904 }
905
906 int UDPSocketWin::SetMulticastOptions() {
907 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
908 DWORD loop = 0;
909 int protocol_level =
910 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
911 int option =
912 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
913 int rv = setsockopt(socket_, protocol_level, option,
914 reinterpret_cast<const char*>(&loop), sizeof(loop));
915 if (rv < 0)
916 return MapSystemError(WSAGetLastError());
917 }
918 if (multicast_time_to_live_ != 1) {
919 DWORD hops = multicast_time_to_live_;
920 int protocol_level =
921 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
922 int option =
923 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
924 int rv = setsockopt(socket_, protocol_level, option,
925 reinterpret_cast<const char*>(&hops), sizeof(hops));
926 if (rv < 0)
927 return MapSystemError(WSAGetLastError());
928 }
929 if (multicast_interface_ != 0) {
930 switch (addr_family_) {
931 case AF_INET: {
932 in_addr address;
933 address.s_addr = htonl(multicast_interface_);
934 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF,
935 reinterpret_cast<const char*>(&address),
936 sizeof(address));
937 if (rv)
938 return MapSystemError(WSAGetLastError());
939 break;
940 }
941 case AF_INET6: {
942 uint32_t interface_index = multicast_interface_;
943 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF,
944 reinterpret_cast<const char*>(&interface_index),
945 sizeof(interface_index));
946 if (rv)
947 return MapSystemError(WSAGetLastError());
948 break;
949 }
950 default:
951 NOTREACHED() << "Invalid address family";
952 return ERR_ADDRESS_INVALID;
953 }
954 }
955 return OK;
956 }
957
958 int UDPSocketWin::DoBind(const IPEndPoint& address) {
959 SockaddrStorage storage;
960 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
961 return ERR_ADDRESS_INVALID;
962 int rv = bind(socket_, storage.addr, storage.addr_len);
963 if (rv == 0)
964 return OK;
965 int last_error = WSAGetLastError();
966 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", last_error);
967 // Map some codes that are special to bind() separately.
968 // * WSAEACCES: If a port is already bound to a socket, WSAEACCES may be
969 // returned instead of WSAEADDRINUSE, depending on whether the socket
970 // option SO_REUSEADDR or SO_EXCLUSIVEADDRUSE is set and whether the
971 // conflicting socket is owned by a different user account. See the MSDN
972 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details.
973 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL)
974 return ERR_ADDRESS_IN_USE;
975 return MapSystemError(last_error);
976 }
977
978 int UDPSocketWin::RandomBind(const IPAddress& address) {
979 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null());
980
981 for (int i = 0; i < kBindRetries; ++i) {
982 int rv = DoBind(IPEndPoint(address, static_cast<uint16_t>(rand_int_cb_.Run(
983 kPortStart, kPortEnd))));
984 if (rv != ERR_ADDRESS_IN_USE)
985 return rv;
986 }
987 return DoBind(IPEndPoint(address, 0));
988 }
989
990 int UDPSocketWin::JoinGroup(const IPAddress& group_address) const {
991 DCHECK(CalledOnValidThread());
992 if (!is_connected())
993 return ERR_SOCKET_NOT_CONNECTED;
994
995 switch (group_address.size()) {
996 case IPAddress::kIPv4AddressSize: {
997 if (addr_family_ != AF_INET)
998 return ERR_ADDRESS_INVALID;
999 ip_mreq mreq;
1000 mreq.imr_interface.s_addr = htonl(multicast_interface_);
1001 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(),
1002 IPAddress::kIPv4AddressSize);
1003 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1004 reinterpret_cast<const char*>(&mreq),
1005 sizeof(mreq));
1006 if (rv)
1007 return MapSystemError(WSAGetLastError());
1008 return OK;
1009 }
1010 case IPAddress::kIPv6AddressSize: {
1011 if (addr_family_ != AF_INET6)
1012 return ERR_ADDRESS_INVALID;
1013 ipv6_mreq mreq;
1014 mreq.ipv6mr_interface = multicast_interface_;
1015 memcpy(&mreq.ipv6mr_multiaddr, group_address.bytes().data(),
1016 IPAddress::kIPv6AddressSize);
1017 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
1018 reinterpret_cast<const char*>(&mreq),
1019 sizeof(mreq));
1020 if (rv)
1021 return MapSystemError(WSAGetLastError());
1022 return OK;
1023 }
1024 default:
1025 NOTREACHED() << "Invalid address family";
1026 return ERR_ADDRESS_INVALID;
1027 }
1028 }
1029
1030 int UDPSocketWin::LeaveGroup(const IPAddress& group_address) const {
1031 DCHECK(CalledOnValidThread());
1032 if (!is_connected())
1033 return ERR_SOCKET_NOT_CONNECTED;
1034
1035 switch (group_address.size()) {
1036 case IPAddress::kIPv4AddressSize: {
1037 if (addr_family_ != AF_INET)
1038 return ERR_ADDRESS_INVALID;
1039 ip_mreq mreq;
1040 mreq.imr_interface.s_addr = htonl(multicast_interface_);
1041 memcpy(&mreq.imr_multiaddr, group_address.bytes().data(),
1042 IPAddress::kIPv4AddressSize);
1043 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1044 reinterpret_cast<const char*>(&mreq), sizeof(mreq));
1045 if (rv)
1046 return MapSystemError(WSAGetLastError());
1047 return OK;
1048 }
1049 case IPAddress::kIPv6AddressSize: {
1050 if (addr_family_ != AF_INET6)
1051 return ERR_ADDRESS_INVALID;
1052 ipv6_mreq mreq;
1053 mreq.ipv6mr_interface = multicast_interface_;
1054 memcpy(&mreq.ipv6mr_multiaddr, group_address.bytes().data(),
1055 IPAddress::kIPv6AddressSize);
1056 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP,
1057 reinterpret_cast<const char*>(&mreq), sizeof(mreq));
1058 if (rv)
1059 return MapSystemError(WSAGetLastError());
1060 return OK;
1061 }
1062 default:
1063 NOTREACHED() << "Invalid address family";
1064 return ERR_ADDRESS_INVALID;
1065 }
1066 }
1067
1068 int UDPSocketWin::SetMulticastInterface(uint32_t interface_index) {
1069 DCHECK(CalledOnValidThread());
1070 if (is_connected())
1071 return ERR_SOCKET_IS_CONNECTED;
1072 multicast_interface_ = interface_index;
1073 return OK;
1074 }
1075
1076 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) {
1077 DCHECK(CalledOnValidThread());
1078 if (is_connected())
1079 return ERR_SOCKET_IS_CONNECTED;
1080
1081 if (time_to_live < 0 || time_to_live > 255)
1082 return ERR_INVALID_ARGUMENT;
1083 multicast_time_to_live_ = time_to_live;
1084 return OK;
1085 }
1086
1087 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) {
1088 DCHECK(CalledOnValidThread());
1089 if (is_connected())
1090 return ERR_SOCKET_IS_CONNECTED;
1091
1092 if (loopback)
1093 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP;
1094 else
1095 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP;
1096 return OK;
1097 }
1098
1099 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) {
1100 if (dscp == DSCP_NO_CHANGE) {
1101 return OK;
1102 }
1103
1104 if (!is_connected())
1105 return ERR_SOCKET_NOT_CONNECTED;
1106
1107 QwaveAPI& qos(QwaveAPI::Get());
1108
1109 if (!qos.qwave_supported())
1110 return ERROR_NOT_SUPPORTED;
1111
1112 if (qos_handle_ == NULL) {
1113 QOS_VERSION version;
1114 version.MajorVersion = 1;
1115 version.MinorVersion = 0;
1116 qos.CreateHandle(&version, &qos_handle_);
1117 if (qos_handle_ == NULL)
1118 return ERROR_NOT_SUPPORTED;
1119 }
1120
1121 QOS_TRAFFIC_TYPE traffic_type = QOSTrafficTypeBestEffort;
1122 switch (dscp) {
1123 case DSCP_CS0:
1124 traffic_type = QOSTrafficTypeBestEffort;
1125 break;
1126 case DSCP_CS1:
1127 traffic_type = QOSTrafficTypeBackground;
1128 break;
1129 case DSCP_AF11:
1130 case DSCP_AF12:
1131 case DSCP_AF13:
1132 case DSCP_CS2:
1133 case DSCP_AF21:
1134 case DSCP_AF22:
1135 case DSCP_AF23:
1136 case DSCP_CS3:
1137 case DSCP_AF31:
1138 case DSCP_AF32:
1139 case DSCP_AF33:
1140 case DSCP_CS4:
1141 traffic_type = QOSTrafficTypeExcellentEffort;
1142 break;
1143 case DSCP_AF41:
1144 case DSCP_AF42:
1145 case DSCP_AF43:
1146 case DSCP_CS5:
1147 traffic_type = QOSTrafficTypeAudioVideo;
1148 break;
1149 case DSCP_EF:
1150 case DSCP_CS6:
1151 traffic_type = QOSTrafficTypeVoice;
1152 break;
1153 case DSCP_CS7:
1154 traffic_type = QOSTrafficTypeControl;
1155 break;
1156 case DSCP_NO_CHANGE:
1157 NOTREACHED();
1158 break;
1159 }
1160 if (qos_flow_id_ != 0) {
1161 qos.RemoveSocketFromFlow(qos_handle_, NULL, qos_flow_id_, 0);
1162 qos_flow_id_ = 0;
1163 }
1164 if (!qos.AddSocketToFlow(qos_handle_,
1165 socket_,
1166 NULL,
1167 traffic_type,
1168 QOS_NON_ADAPTIVE_FLOW,
1169 &qos_flow_id_)) {
1170 DWORD err = GetLastError();
1171 if (err == ERROR_DEVICE_REINITIALIZATION_NEEDED) {
1172 qos.CloseHandle(qos_handle_);
1173 qos_flow_id_ = 0;
1174 qos_handle_ = 0;
1175 }
1176 return MapSystemError(err);
1177 }
1178 // This requires admin rights, and may fail, if so we ignore it
1179 // as AddSocketToFlow should still do *approximately* the right thing.
1180 DWORD buf = dscp;
1181 qos.SetFlow(qos_handle_,
1182 qos_flow_id_,
1183 QOSSetOutgoingDSCPValue,
1184 sizeof(buf),
1185 &buf,
1186 0,
1187 NULL);
1188
1189 return OK;
1190 }
1191
1192 void UDPSocketWin::DetachFromThread() {
1193 base::NonThreadSafe::DetachFromThread();
1194 }
1195
1196 void UDPSocketWin::UseNonBlockingIO() {
1197 DCHECK(!core_);
1198 use_non_blocking_io_ = true;
1199 }
1200
1201 } // namespace net
OLDNEW
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | remoting/protocol/chromium_socket_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698