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" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, | 44 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, |
45 const RandIntCallback& rand_int_cb, | 45 const RandIntCallback& rand_int_cb, |
46 net::NetLog* net_log, | 46 net::NetLog* net_log, |
47 const net::NetLog::Source& source) | 47 const net::NetLog::Source& source) |
48 : socket_(INVALID_SOCKET), | 48 : socket_(INVALID_SOCKET), |
49 bind_type_(bind_type), | 49 bind_type_(bind_type), |
50 rand_int_cb_(rand_int_cb), | 50 rand_int_cb_(rand_int_cb), |
51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), | 51 ALLOW_THIS_IN_INITIALIZER_LIST(read_delegate_(this)), |
52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), | 52 ALLOW_THIS_IN_INITIALIZER_LIST(write_delegate_(this)), |
53 recv_from_address_(NULL), | 53 recv_from_address_(NULL), |
54 old_read_callback_(NULL), | |
55 write_callback_(NULL), | |
56 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { | 54 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { |
57 EnsureWinsockInit(); | 55 EnsureWinsockInit(); |
58 scoped_refptr<NetLog::EventParameters> params; | 56 scoped_refptr<NetLog::EventParameters> params; |
59 if (source.is_valid()) | 57 if (source.is_valid()) |
60 params = new NetLogSourceParameter("source_dependency", source); | 58 params = new NetLogSourceParameter("source_dependency", source); |
61 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); | 59 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); |
62 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 60 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
63 read_overlapped_.hEvent = WSACreateEvent(); | 61 read_overlapped_.hEvent = WSACreateEvent(); |
64 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 62 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
65 write_overlapped_.hEvent = WSACreateEvent(); | 63 write_overlapped_.hEvent = WSACreateEvent(); |
66 if (bind_type == DatagramSocket::RANDOM_BIND) | 64 if (bind_type == DatagramSocket::RANDOM_BIND) |
67 DCHECK(!rand_int_cb.is_null()); | 65 DCHECK(!rand_int_cb.is_null()); |
68 } | 66 } |
69 | 67 |
70 UDPSocketWin::~UDPSocketWin() { | 68 UDPSocketWin::~UDPSocketWin() { |
71 Close(); | 69 Close(); |
72 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); | 70 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); |
73 } | 71 } |
74 | 72 |
75 void UDPSocketWin::Close() { | 73 void UDPSocketWin::Close() { |
76 DCHECK(CalledOnValidThread()); | 74 DCHECK(CalledOnValidThread()); |
77 | 75 |
78 if (!is_connected()) | 76 if (!is_connected()) |
79 return; | 77 return; |
80 | 78 |
81 // Zero out any pending read/write callback state. | 79 // Zero out any pending read/write callback state. |
82 old_read_callback_ = NULL; | |
83 read_callback_.Reset(); | 80 read_callback_.Reset(); |
84 recv_from_address_ = NULL; | 81 recv_from_address_ = NULL; |
85 write_callback_ = NULL; | 82 write_callback_.Reset(); |
86 | 83 |
87 read_watcher_.StopWatching(); | 84 read_watcher_.StopWatching(); |
88 write_watcher_.StopWatching(); | 85 write_watcher_.StopWatching(); |
89 | 86 |
90 closesocket(socket_); | 87 closesocket(socket_); |
91 socket_ = INVALID_SOCKET; | 88 socket_ = INVALID_SOCKET; |
92 } | 89 } |
93 | 90 |
94 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 91 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
95 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 return ERR_FAILED; | 127 return ERR_FAILED; |
131 local_address_.reset(address.release()); | 128 local_address_.reset(address.release()); |
132 } | 129 } |
133 | 130 |
134 *address = *local_address_; | 131 *address = *local_address_; |
135 return OK; | 132 return OK; |
136 } | 133 } |
137 | 134 |
138 int UDPSocketWin::Read(IOBuffer* buf, | 135 int UDPSocketWin::Read(IOBuffer* buf, |
139 int buf_len, | 136 int buf_len, |
140 OldCompletionCallback* callback) { | |
141 return RecvFrom(buf, buf_len, NULL, callback); | |
142 } | |
143 int UDPSocketWin::Read(IOBuffer* buf, | |
144 int buf_len, | |
145 const CompletionCallback& callback) { | 137 const CompletionCallback& callback) { |
146 return RecvFrom(buf, buf_len, NULL, callback); | 138 return RecvFrom(buf, buf_len, NULL, callback); |
147 } | 139 } |
148 | 140 |
149 int UDPSocketWin::RecvFrom(IOBuffer* buf, | 141 int UDPSocketWin::RecvFrom(IOBuffer* buf, |
150 int buf_len, | 142 int buf_len, |
151 IPEndPoint* address, | 143 IPEndPoint* address, |
152 OldCompletionCallback* callback) { | |
153 DCHECK(CalledOnValidThread()); | |
154 DCHECK_NE(INVALID_SOCKET, socket_); | |
155 DCHECK(!old_read_callback_ && read_callback_.is_null()); | |
156 DCHECK(!recv_from_address_); | |
157 DCHECK(callback); // Synchronous operation not supported. | |
158 DCHECK_GT(buf_len, 0); | |
159 | |
160 int nread = InternalRecvFrom(buf, buf_len, address); | |
161 if (nread != ERR_IO_PENDING) | |
162 return nread; | |
163 | |
164 read_iobuffer_ = buf; | |
165 old_read_callback_ = callback; | |
166 recv_from_address_ = address; | |
167 return ERR_IO_PENDING; | |
168 } | |
169 int UDPSocketWin::RecvFrom(IOBuffer* buf, | |
170 int buf_len, | |
171 IPEndPoint* address, | |
172 const CompletionCallback& callback) { | 144 const CompletionCallback& callback) { |
173 DCHECK(CalledOnValidThread()); | 145 DCHECK(CalledOnValidThread()); |
174 DCHECK_NE(INVALID_SOCKET, socket_); | 146 DCHECK_NE(INVALID_SOCKET, socket_); |
175 DCHECK(!old_read_callback_ && read_callback_.is_null()); | 147 DCHECK(read_callback_.is_null()); |
176 DCHECK(!recv_from_address_); | 148 DCHECK(!recv_from_address_); |
177 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 149 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
178 DCHECK_GT(buf_len, 0); | 150 DCHECK_GT(buf_len, 0); |
179 | 151 |
180 int nread = InternalRecvFrom(buf, buf_len, address); | 152 int nread = InternalRecvFrom(buf, buf_len, address); |
181 if (nread != ERR_IO_PENDING) | 153 if (nread != ERR_IO_PENDING) |
182 return nread; | 154 return nread; |
183 | 155 |
184 read_iobuffer_ = buf; | 156 read_iobuffer_ = buf; |
185 read_callback_ = callback; | 157 read_callback_ = callback; |
186 recv_from_address_ = address; | 158 recv_from_address_ = address; |
187 return ERR_IO_PENDING; | 159 return ERR_IO_PENDING; |
188 } | 160 } |
189 | 161 |
190 int UDPSocketWin::Write(IOBuffer* buf, | 162 int UDPSocketWin::Write(IOBuffer* buf, |
191 int buf_len, | 163 int buf_len, |
192 OldCompletionCallback* callback) { | 164 const CompletionCallback& callback) { |
193 return SendToOrWrite(buf, buf_len, NULL, callback); | 165 return SendToOrWrite(buf, buf_len, NULL, callback); |
194 } | 166 } |
195 | 167 |
196 int UDPSocketWin::SendTo(IOBuffer* buf, | 168 int UDPSocketWin::SendTo(IOBuffer* buf, |
197 int buf_len, | 169 int buf_len, |
198 const IPEndPoint& address, | 170 const IPEndPoint& address, |
199 OldCompletionCallback* callback) { | 171 const CompletionCallback& callback) { |
200 return SendToOrWrite(buf, buf_len, &address, callback); | 172 return SendToOrWrite(buf, buf_len, &address, callback); |
201 } | 173 } |
202 | 174 |
203 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, | 175 int UDPSocketWin::SendToOrWrite(IOBuffer* buf, |
204 int buf_len, | 176 int buf_len, |
205 const IPEndPoint* address, | 177 const IPEndPoint* address, |
206 OldCompletionCallback* callback) { | 178 const CompletionCallback& callback) { |
207 DCHECK(CalledOnValidThread()); | 179 DCHECK(CalledOnValidThread()); |
208 DCHECK_NE(INVALID_SOCKET, socket_); | 180 DCHECK_NE(INVALID_SOCKET, socket_); |
209 DCHECK(!write_callback_); | 181 DCHECK(write_callback_.is_null()); |
210 DCHECK(callback); // Synchronous operation not supported. | 182 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
211 DCHECK_GT(buf_len, 0); | 183 DCHECK_GT(buf_len, 0); |
212 DCHECK(!send_to_address_.get()); | 184 DCHECK(!send_to_address_.get()); |
213 | 185 |
214 int nwrite = InternalSendTo(buf, buf_len, address); | 186 int nwrite = InternalSendTo(buf, buf_len, address); |
215 if (nwrite != ERR_IO_PENDING) | 187 if (nwrite != ERR_IO_PENDING) |
216 return nwrite; | 188 return nwrite; |
217 | 189 |
218 if (address) | 190 if (address) |
219 send_to_address_.reset(new IPEndPoint(*address)); | 191 send_to_address_.reset(new IPEndPoint(*address)); |
220 write_iobuffer_ = buf; | 192 write_iobuffer_ = buf; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 bool UDPSocketWin::SetSendBufferSize(int32 size) { | 263 bool UDPSocketWin::SetSendBufferSize(int32 size) { |
292 DCHECK(CalledOnValidThread()); | 264 DCHECK(CalledOnValidThread()); |
293 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 265 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
294 reinterpret_cast<const char*>(&size), sizeof(size)); | 266 reinterpret_cast<const char*>(&size), sizeof(size)); |
295 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; | 267 DCHECK(!rv) << "Could not set socket send buffer size: " << errno; |
296 return rv == 0; | 268 return rv == 0; |
297 } | 269 } |
298 | 270 |
299 void UDPSocketWin::DoReadCallback(int rv) { | 271 void UDPSocketWin::DoReadCallback(int rv) { |
300 DCHECK_NE(rv, ERR_IO_PENDING); | 272 DCHECK_NE(rv, ERR_IO_PENDING); |
301 DCHECK(old_read_callback_ || !read_callback_.is_null()); | 273 DCHECK(!read_callback_.is_null()); |
302 | 274 |
303 // since Run may result in Read being called, clear read_callback_ up front. | 275 // since Run may result in Read being called, clear read_callback_ up front. |
304 if (old_read_callback_) { | 276 CompletionCallback c = read_callback_; |
305 OldCompletionCallback* c = old_read_callback_; | 277 read_callback_.Reset(); |
306 old_read_callback_ = NULL; | 278 c.Run(rv); |
307 c->Run(rv); | |
308 } else { | |
309 CompletionCallback c = read_callback_; | |
310 read_callback_.Reset(); | |
311 c.Run(rv); | |
312 } | |
313 } | 279 } |
314 | 280 |
315 void UDPSocketWin::DoWriteCallback(int rv) { | 281 void UDPSocketWin::DoWriteCallback(int rv) { |
316 DCHECK_NE(rv, ERR_IO_PENDING); | 282 DCHECK_NE(rv, ERR_IO_PENDING); |
317 DCHECK(write_callback_); | 283 DCHECK(!write_callback_.is_null()); |
318 | 284 |
319 // since Run may result in Write being called, clear write_callback_ up front. | 285 // since Run may result in Write being called, clear write_callback_ up front. |
320 OldCompletionCallback* c = write_callback_; | 286 CompletionCallback c = write_callback_; |
321 write_callback_ = NULL; | 287 write_callback_.Reset(); |
322 c->Run(rv); | 288 c.Run(rv); |
323 } | 289 } |
324 | 290 |
325 void UDPSocketWin::DidCompleteRead() { | 291 void UDPSocketWin::DidCompleteRead() { |
326 DWORD num_bytes, flags; | 292 DWORD num_bytes, flags; |
327 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, | 293 BOOL ok = WSAGetOverlappedResult(socket_, &read_overlapped_, |
328 &num_bytes, FALSE, &flags); | 294 &num_bytes, FALSE, &flags); |
329 WSAResetEvent(read_overlapped_.hEvent); | 295 WSAResetEvent(read_overlapped_.hEvent); |
330 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 296 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
331 // Convert address. | 297 // Convert address. |
332 if (recv_from_address_ && result >= 0) { | 298 if (recv_from_address_ && result >= 0) { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 return DoBind(IPEndPoint(ip, 0)); | 469 return DoBind(IPEndPoint(ip, 0)); |
504 } | 470 } |
505 | 471 |
506 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 472 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
507 const struct sockaddr* addr = | 473 const struct sockaddr* addr = |
508 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 474 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
509 return address->FromSockAddr(addr, recv_addr_len_); | 475 return address->FromSockAddr(addr, recv_addr_len_); |
510 } | 476 } |
511 | 477 |
512 } // namespace net | 478 } // namespace net |
OLD | NEW |