OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/udp/udp_socket_win.h" | 5 #include "net/udp/udp_socket_win.h" |
6 | 6 |
7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
8 | 8 |
9 #include "base/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/metrics/stats_counters.h" | 12 #include "base/metrics/stats_counters.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "net/base/address_list_net_log_param.h" | |
14 #include "net/base/io_buffer.h" | 15 #include "net/base/io_buffer.h" |
15 #include "net/base/ip_endpoint.h" | 16 #include "net/base/ip_endpoint.h" |
16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
17 #include "net/base/net_log.h" | 18 #include "net/base/net_log.h" |
18 #include "net/base/net_util.h" | 19 #include "net/base/net_util.h" |
19 #include "net/base/winsock_init.h" | 20 #include "net/base/winsock_init.h" |
20 #include "net/base/winsock_util.h" | 21 #include "net/base/winsock_util.h" |
22 #include "net/udp/udp_data_transfer_param.h" | |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 static const int kBindRetries = 10; | 26 static const int kBindRetries = 10; |
25 static const int kPortStart = 1024; | 27 static const int kPortStart = 1024; |
26 static const int kPortEnd = 65535; | 28 static const int kPortEnd = 65535; |
27 | 29 |
28 } // namespace net | 30 } // namespace net |
29 | 31 |
30 namespace net { | 32 namespace net { |
(...skipping 13 matching lines...) Expand all Loading... | |
44 net::NetLog* net_log, | 46 net::NetLog* net_log, |
45 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
46 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
47 bind_type_(bind_type), | 49 bind_type_(bind_type), |
48 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
49 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
50 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
51 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
52 read_callback_(NULL), | 54 read_callback_(NULL), |
53 write_callback_(NULL), | 55 write_callback_(NULL), |
54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { | 56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
55 EnsureWinsockInit(); | 57 EnsureWinsockInit(); |
56 scoped_refptr<NetLog::EventParameters> params; | 58 scoped_refptr<NetLog::EventParameters> params; |
57 if (source.is_valid()) | 59 if (source.is_valid()) |
58 params = new NetLogSourceParameter("source_dependency", source); | 60 params = new NetLogSourceParameter("source_dependency", source); |
59 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
60 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
61 read_overlapped_.hEvent = WSACreateEvent(); | 63 read_overlapped_.hEvent = WSACreateEvent(); |
62 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
63 write_overlapped_.hEvent = WSACreateEvent(); | 65 write_overlapped_.hEvent = WSACreateEvent(); |
64 if (bind_type == DatagramSocket::RANDOM_BIND) | 66 if (bind_type == DatagramSocket::RANDOM_BIND) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 IPEndPoint* address, | 145 IPEndPoint* address, |
144 OldCompletionCallback* callback) { | 146 OldCompletionCallback* callback) { |
145 DCHECK(CalledOnValidThread()); | 147 DCHECK(CalledOnValidThread()); |
146 DCHECK_NE(INVALID_SOCKET, socket_); | 148 DCHECK_NE(INVALID_SOCKET, socket_); |
147 DCHECK(!read_callback_); | 149 DCHECK(!read_callback_); |
148 DCHECK(!recv_from_address_); | 150 DCHECK(!recv_from_address_); |
149 DCHECK(callback); // Synchronous operation not supported. | 151 DCHECK(callback); // Synchronous operation not supported. |
150 DCHECK_GT(buf_len, 0); | 152 DCHECK_GT(buf_len, 0); |
151 | 153 |
152 int nread = InternalRecvFrom(buf, buf_len, address); | 154 int nread = InternalRecvFrom(buf, buf_len, address); |
153 if (nread != ERR_IO_PENDING) | 155 if (nread != ERR_IO_PENDING) { |
156 if (nread < 0) | |
157 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, nread); | |
Sergey Ulanov
2011/10/14 20:15:47
nit: InternalRecvFrom() logs success events, so ma
mmenke
2011/10/17 17:35:20
Done.
| |
154 return nread; | 158 return nread; |
159 } | |
155 | 160 |
156 read_iobuffer_ = buf; | 161 read_iobuffer_ = buf; |
157 read_callback_ = callback; | 162 read_callback_ = callback; |
158 recv_from_address_ = address; | 163 recv_from_address_ = address; |
159 return ERR_IO_PENDING; | 164 return ERR_IO_PENDING; |
160 } | 165 } |
161 | 166 |
162 int UDPSocketWin::Write(IOBuffer* buf, | 167 int UDPSocketWin::Write(IOBuffer* buf, |
163 int buf_len, | 168 int buf_len, |
164 OldCompletionCallback* callback) { | 169 OldCompletionCallback* callback) { |
165 return SendToOrWrite(buf, buf_len, NULL, callback); | 170 return SendToOrWrite(buf, buf_len, NULL, callback); |
166 } | 171 } |
167 | 172 |
168 int UDPSocketWin::SendTo(IOBuffer* buf, | 173 int UDPSocketWin::SendTo(IOBuffer* buf, |
169 int buf_len, | 174 int buf_len, |
170 const IPEndPoint& address, | 175 const IPEndPoint& address, |
171 OldCompletionCallback* callback) { | 176 OldCompletionCallback* callback) { |
172 return SendToOrWrite(buf, buf_len, &address, callback); | 177 return SendToOrWrite(buf, buf_len, &address, callback); |
173 } | 178 } |
174 | 179 |
175 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 180 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
176 int buf_len, | 181 int buf_len, |
177 const IPEndPoint* address, | 182 const IPEndPoint* address, |
178 OldCompletionCallback* callback) { | 183 OldCompletionCallback* callback) { |
179 DCHECK(CalledOnValidThread()); | 184 DCHECK(CalledOnValidThread()); |
180 DCHECK_NE(INVALID_SOCKET, socket_); | 185 DCHECK_NE(INVALID_SOCKET, socket_); |
181 DCHECK(!write_callback_); | 186 DCHECK(!write_callback_); |
182 DCHECK(callback); // Synchronous operation not supported. | 187 DCHECK(callback); // Synchronous operation not supported. |
183 DCHECK_GT(buf_len, 0); | 188 DCHECK_GT(buf_len, 0); |
189 DCHECK(!send_to_address_.get()); | |
184 | 190 |
185 int nwrite = InternalSendTo(buf, buf_len, address); | 191 int nwrite = InternalSendTo(buf, buf_len, address); |
186 if (nwrite != ERR_IO_PENDING) | 192 if (nwrite != ERR_IO_PENDING) { |
193 if (nwrite < 0) | |
194 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, nwrite); | |
Sergey Ulanov
2011/10/14 20:15:47
move this to InternalSendTo()
mmenke
2011/10/17 17:35:20
Done.
| |
187 return nwrite; | 195 return nwrite; |
196 } | |
188 | 197 |
198 if (address) | |
199 send_to_address_.reset(new IPEndPoint(*address)); | |
189 write_iobuffer_ = buf; | 200 write_iobuffer_ = buf; |
190 write_callback_ = callback; | 201 write_callback_ = callback; |
191 return ERR_IO_PENDING; | 202 return ERR_IO_PENDING; |
192 } | 203 } |
193 | 204 |
194 int UDPSocketWin::Connect(const IPEndPoint& address) { | 205 int UDPSocketWin::Connect(const IPEndPoint& address) { |
206 net_log_.BeginEvent( | |
207 NetLog::TYPE_UDP_CONNECT, | |
208 make_scoped_refptr(new NetLogStringParameter("address", | |
209 address.ToString()))); | |
210 int rv = InternalConnect(address); | |
211 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_UDP_CONNECT, rv); | |
212 return rv; | |
213 } | |
214 | |
215 int UDPSocketWin::InternalConnect(const IPEndPoint& address) { | |
195 DCHECK(!is_connected()); | 216 DCHECK(!is_connected()); |
196 DCHECK(!remote_address_.get()); | 217 DCHECK(!remote_address_.get()); |
197 int rv = CreateSocket(address); | 218 int rv = CreateSocket(address); |
198 if (rv < 0) | 219 if (rv < 0) |
199 return rv; | 220 return rv; |
200 | 221 |
201 if (bind_type_ == DatagramSocket::RANDOM_BIND) | 222 if (bind_type_ == DatagramSocket::RANDOM_BIND) |
202 rv = RandomBind(address); | 223 rv = RandomBind(address); |
203 // else connect() does the DatagramSocket::DEFAULT_BIND | 224 // else connect() does the DatagramSocket::DEFAULT_BIND |
204 | 225 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
259 c->Run(rv); | 280 c->Run(rv); |
260 } | 281 } |
261 | 282 |
262 void UDPSocketWin::DidCompleteRead() { | 283 void UDPSocketWin::DidCompleteRead() { |
263 DWORD num_bytes, flags; | 284 DWORD num_bytes, flags; |
264 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 285 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, |
265 &num_bytes, FALSE, &flags); | 286 &num_bytes, FALSE, &flags); |
266 WSAResetEvent(read_overlapped_.hEvent); | 287 WSAResetEvent(read_overlapped_.hEvent); |
267 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 288 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
268 if (ok) { | 289 if (ok) { |
269 if (!ProcessSuccessfulRead(num_bytes, recv_from_address_)) | 290 if (!ProcessSuccessfulRead(num_bytes, read_iobuffer_->data(), |
291 recv_from_address_)) { | |
270 result = ERR_FAILED; | 292 result = ERR_FAILED; |
293 } | |
271 } | 294 } |
295 if (result < 0) | |
296 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | |
272 read_iobuffer_ = NULL; | 297 read_iobuffer_ = NULL; |
273 recv_from_address_ = NULL; | 298 recv_from_address_ = NULL; |
274 DoReadCallback(result); | 299 DoReadCallback(result); |
275 } | 300 } |
276 | 301 |
277 bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes, IPEndPoint* address) { | 302 bool UDPSocketWin::ProcessSuccessfulRead(int num_bytes, const char* bytes, |
303 IPEndPoint* address) const { | |
278 base::StatsCounter read_bytes("udp.read_bytes"); | 304 base::StatsCounter read_bytes("udp.read_bytes"); |
279 read_bytes.Add(num_bytes); | 305 read_bytes.Add(num_bytes); |
280 | 306 |
307 const struct sockaddr* addr = | |
308 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | |
309 | |
281 // Convert address. | 310 // Convert address. |
282 if (address) { | 311 if (address) { |
283 struct sockaddr* addr = | |
284 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | |
285 if (!address->FromSockAddr(addr, recv_addr_len_)) | 312 if (!address->FromSockAddr(addr, recv_addr_len_)) |
286 return false; | 313 return false; |
287 } | 314 } |
288 | 315 |
316 if (net_log_.IsLoggingAllEvents()) { | |
317 // Get address for logging, if |address| is NULL. | |
318 IPEndPoint address_on_stack; | |
319 if (!address) { | |
320 if (address_on_stack.FromSockAddr(addr, recv_addr_len_)) | |
321 address = &address_on_stack; | |
322 } | |
323 net_log_.AddEvent( | |
324 NetLog::TYPE_UDP_BYTES_RECEIVED, | |
325 make_scoped_refptr( | |
326 new UDPDataTransferNetLogParam(num_bytes, bytes, | |
327 net_log_.IsLoggingBytes(), | |
328 address))); | |
329 } | |
330 | |
289 return true; | 331 return true; |
290 } | 332 } |
291 | 333 |
292 void UDPSocketWin::DidCompleteWrite() { | 334 void UDPSocketWin::DidCompleteWrite() { |
293 DWORD num_bytes, flags; | 335 DWORD num_bytes, flags; |
294 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, | 336 BOOL ok = WSAGetOverlappedResult(socket_, &write_overlapped_, |
295 &num_bytes, FALSE, &flags); | 337 &num_bytes, FALSE, &flags); |
296 WSAResetEvent(write_overlapped_.hEvent); | 338 WSAResetEvent(write_overlapped_.hEvent); |
297 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 339 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
298 if (ok) | 340 if (ok) { |
299 ProcessSuccessfulWrite(num_bytes); | 341 ProcessSuccessfulWrite(num_bytes, write_iobuffer_->data(), |
342 send_to_address_.get()); | |
343 } else { | |
344 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | |
345 } | |
346 send_to_address_.reset(); | |
300 write_iobuffer_ = NULL; | 347 write_iobuffer_ = NULL; |
301 DoWriteCallback(result); | 348 DoWriteCallback(result); |
302 } | 349 } |
303 | 350 |
304 void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes) { | 351 void UDPSocketWin::ProcessSuccessfulWrite(int num_bytes, |
352 const char* bytes, | |
353 const IPEndPoint* address) const { | |
354 if (net_log_.IsLoggingAllEvents()) { | |
355 net_log_.AddEvent( | |
356 NetLog::TYPE_UDP_BYTES_SENT, | |
357 make_scoped_refptr( | |
358 new UDPDataTransferNetLogParam(num_bytes, bytes, | |
359 net_log_.IsLoggingBytes(), | |
360 address))); | |
361 } | |
305 base::StatsCounter write_bytes("udp.write_bytes"); | 362 base::StatsCounter write_bytes("udp.write_bytes"); |
306 write_bytes.Add(num_bytes); | 363 write_bytes.Add(num_bytes); |
307 } | 364 } |
308 | 365 |
309 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 366 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, |
310 IPEndPoint* address) { | 367 IPEndPoint* address) { |
311 recv_addr_len_ = sizeof(recv_addr_storage_); | 368 recv_addr_len_ = sizeof(recv_addr_storage_); |
312 struct sockaddr* addr = | 369 struct sockaddr* addr = |
313 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); | 370 reinterpret_cast<struct sockaddr*>(&recv_addr_storage_); |
314 | 371 |
315 WSABUF read_buffer; | 372 WSABUF read_buffer; |
316 read_buffer.buf = buf->data(); | 373 read_buffer.buf = buf->data(); |
317 read_buffer.len = buf_len; | 374 read_buffer.len = buf_len; |
318 | 375 |
319 DWORD flags = 0; | 376 DWORD flags = 0; |
320 DWORD num; | 377 DWORD num; |
321 AssertEventNotSignaled(read_overlapped_.hEvent); | 378 AssertEventNotSignaled(read_overlapped_.hEvent); |
322 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, | 379 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, addr, |
323 &recv_addr_len_, &read_overlapped_, NULL); | 380 &recv_addr_len_, &read_overlapped_, NULL); |
324 if (rv == 0) { | 381 if (rv == 0) { |
325 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { | 382 if (ResetEventIfSignaled(read_overlapped_.hEvent)) { |
326 if (!ProcessSuccessfulRead(num, address)) | 383 if (!ProcessSuccessfulRead(num, buf->data(), address)) |
327 return ERR_FAILED; | 384 return ERR_FAILED; |
328 return static_cast<int>(num); | 385 return static_cast<int>(num); |
329 } | 386 } |
330 } else { | 387 } else { |
331 int os_error = WSAGetLastError(); | 388 int os_error = WSAGetLastError(); |
332 if (os_error != WSA_IO_PENDING) | 389 if (os_error != WSA_IO_PENDING) |
333 return MapSystemError(os_error); | 390 return MapSystemError(os_error); |
334 } | 391 } |
335 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); | 392 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); |
336 return ERR_IO_PENDING; | 393 return ERR_IO_PENDING; |
(...skipping 18 matching lines...) Expand all Loading... | |
355 write_buffer.buf = buf->data(); | 412 write_buffer.buf = buf->data(); |
356 write_buffer.len = buf_len; | 413 write_buffer.len = buf_len; |
357 | 414 |
358 DWORD flags = 0; | 415 DWORD flags = 0; |
359 DWORD num; | 416 DWORD num; |
360 AssertEventNotSignaled(write_overlapped_.hEvent); | 417 AssertEventNotSignaled(write_overlapped_.hEvent); |
361 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 418 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, |
362 addr, addr_len, &write_overlapped_, NULL); | 419 addr, addr_len, &write_overlapped_, NULL); |
363 if (rv == 0) { | 420 if (rv == 0) { |
364 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { | 421 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { |
365 ProcessSuccessfulWrite(num); | 422 ProcessSuccessfulWrite(num, buf->data(), address); |
366 return static_cast<int>(num); | 423 return static_cast<int>(num); |
367 } | 424 } |
368 } else { | 425 } else { |
369 int os_error = WSAGetLastError(); | 426 int os_error = WSAGetLastError(); |
370 if (os_error != WSA_IO_PENDING) | 427 if (os_error != WSA_IO_PENDING) |
371 return MapSystemError(os_error); | 428 return MapSystemError(os_error); |
372 } | 429 } |
373 | 430 |
374 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 431 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); |
375 return ERR_IO_PENDING; | 432 return ERR_IO_PENDING; |
(...skipping 17 matching lines...) Expand all Loading... | |
393 | 450 |
394 for (int i = 0; i < kBindRetries; ++i) { | 451 for (int i = 0; i < kBindRetries; ++i) { |
395 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 452 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
396 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 453 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
397 return rv; | 454 return rv; |
398 } | 455 } |
399 return DoBind(IPEndPoint(ip, 0)); | 456 return DoBind(IPEndPoint(ip, 0)); |
400 } | 457 } |
401 | 458 |
402 } // namespace net | 459 } // namespace net |
OLD | NEW |