udp_socket_win.cc 40 KB

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