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

Side by Side Diff: net/socket/tcp_client_socket_libevent.cc

Issue 10309002: Reimplements net::AddressList without struct addrinfo. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added missing NET_EXPORT to *PortOnAddressList. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/tcp_client_socket.h" 5 #include "net/socket/tcp_client_socket.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 120
121 //----------------------------------------------------------------------------- 121 //-----------------------------------------------------------------------------
122 122
123 TCPClientSocketLibevent::TCPClientSocketLibevent( 123 TCPClientSocketLibevent::TCPClientSocketLibevent(
124 const AddressList& addresses, 124 const AddressList& addresses,
125 net::NetLog* net_log, 125 net::NetLog* net_log,
126 const net::NetLog::Source& source) 126 const net::NetLog::Source& source)
127 : socket_(kInvalidSocket), 127 : socket_(kInvalidSocket),
128 bound_socket_(kInvalidSocket), 128 bound_socket_(kInvalidSocket),
129 addresses_(addresses), 129 addresses_(addresses),
130 current_ai_(NULL), 130 current_address_index_(static_cast<size_t>(-1)),
131 read_watcher_(this), 131 read_watcher_(this),
132 write_watcher_(this), 132 write_watcher_(this),
133 next_connect_state_(CONNECT_STATE_NONE), 133 next_connect_state_(CONNECT_STATE_NONE),
134 connect_os_error_(0), 134 connect_os_error_(0),
135 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), 135 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
136 previously_disconnected_(false), 136 previously_disconnected_(false),
137 use_tcp_fastopen_(false), 137 use_tcp_fastopen_(false),
138 tcp_fastopen_connected_(false), 138 tcp_fastopen_connected_(false),
139 num_bytes_read_(0) { 139 num_bytes_read_(0) {
140 scoped_refptr<NetLog::EventParameters> params; 140 scoped_refptr<NetLog::EventParameters> params;
(...skipping 15 matching lines...) Expand all
156 156
157 int error = SetupSocket(socket); 157 int error = SetupSocket(socket);
158 if (error) 158 if (error)
159 return MapSystemError(error); 159 return MapSystemError(error);
160 160
161 socket_ = socket; 161 socket_ = socket;
162 162
163 // This is to make GetPeerAddress() work. It's up to the caller ensure 163 // This is to make GetPeerAddress() work. It's up to the caller ensure
164 // that |address_| contains a reasonable address for this 164 // that |address_| contains a reasonable address for this
165 // socket. (i.e. at least match IPv4 vs IPv6!). 165 // socket. (i.e. at least match IPv4 vs IPv6!).
166 current_ai_ = addresses_.head(); 166 current_address_index_ = 0;
167 use_history_.set_was_ever_connected(); 167 use_history_.set_was_ever_connected();
168 168
169 return OK; 169 return OK;
170 } 170 }
171 171
172 int TCPClientSocketLibevent::Bind(const IPEndPoint& address) { 172 int TCPClientSocketLibevent::Bind(const IPEndPoint& address) {
173 if (current_ai_ != NULL || bind_address_.get()) { 173 if (current_address_index_ < addresses_.size() || bind_address_.get()) {
eroman 2012/05/04 01:08:41 If you do my recommendation to change index to an
174 // Cannot bind the socket if we are already bound connected or 174 // Cannot bind the socket if we are already bound connected or
175 // connecting. 175 // connecting.
176 return ERR_UNEXPECTED; 176 return ERR_UNEXPECTED;
177 } 177 }
178 178
179 sockaddr_storage addr_storage; 179 SockaddrStorage storage;
180 sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 180 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
181 size_t addr_len = sizeof(addr_storage);
182 if (!address.ToSockAddr(addr, &addr_len))
183 return ERR_INVALID_ARGUMENT; 181 return ERR_INVALID_ARGUMENT;
184 182
185 // Create |bound_socket_| and try to bound it to |address|. 183 // Create |bound_socket_| and try to bound it to |address|.
186 int error = CreateSocket(address.GetFamily(), &bound_socket_); 184 int error = CreateSocket(address.GetFamily(), &bound_socket_);
187 if (error) 185 if (error)
188 return MapSystemError(error); 186 return MapSystemError(error);
189 187
190 if (HANDLE_EINTR(bind(bound_socket_, addr, addr_len))) { 188 if (HANDLE_EINTR(bind(bound_socket_, storage.addr, storage.addr_len))) {
191 error = errno; 189 error = errno;
192 if (HANDLE_EINTR(close(bound_socket_)) < 0) 190 if (HANDLE_EINTR(close(bound_socket_)) < 0)
193 PLOG(ERROR) << "close"; 191 PLOG(ERROR) << "close";
194 bound_socket_ = kInvalidSocket; 192 bound_socket_ = kInvalidSocket;
195 return MapSystemError(error); 193 return MapSystemError(error);
196 } 194 }
197 195
198 bind_address_.reset(new IPEndPoint(address)); 196 bind_address_.reset(new IPEndPoint(address));
199 197
200 return 0; 198 return 0;
(...skipping 11 matching lines...) Expand all
212 210
213 DCHECK(!waiting_connect()); 211 DCHECK(!waiting_connect());
214 212
215 net_log_.BeginEvent( 213 net_log_.BeginEvent(
216 NetLog::TYPE_TCP_CONNECT, 214 NetLog::TYPE_TCP_CONNECT,
217 make_scoped_refptr(new AddressListNetLogParam(addresses_))); 215 make_scoped_refptr(new AddressListNetLogParam(addresses_)));
218 216
219 // We will try to connect to each address in addresses_. Start with the 217 // We will try to connect to each address in addresses_. Start with the
220 // first one in the list. 218 // first one in the list.
221 next_connect_state_ = CONNECT_STATE_CONNECT; 219 next_connect_state_ = CONNECT_STATE_CONNECT;
222 current_ai_ = addresses_.head(); 220 current_address_index_ = 0;
223 221
224 int rv = DoConnectLoop(OK); 222 int rv = DoConnectLoop(OK);
225 if (rv == ERR_IO_PENDING) { 223 if (rv == ERR_IO_PENDING) {
226 // Synchronous operation not supported. 224 // Synchronous operation not supported.
227 DCHECK(!callback.is_null()); 225 DCHECK(!callback.is_null());
228 write_callback_ = callback; 226 write_callback_ = callback;
229 } else { 227 } else {
230 LogConnectCompletion(rv); 228 LogConnectCompletion(rv);
231 } 229 }
232 230
(...skipping 19 matching lines...) Expand all
252 LOG(DFATAL) << "bad state"; 250 LOG(DFATAL) << "bad state";
253 rv = ERR_UNEXPECTED; 251 rv = ERR_UNEXPECTED;
254 break; 252 break;
255 } 253 }
256 } while (rv != ERR_IO_PENDING && next_connect_state_ != CONNECT_STATE_NONE); 254 } while (rv != ERR_IO_PENDING && next_connect_state_ != CONNECT_STATE_NONE);
257 255
258 return rv; 256 return rv;
259 } 257 }
260 258
261 int TCPClientSocketLibevent::DoConnect() { 259 int TCPClientSocketLibevent::DoConnect() {
262 DCHECK(current_ai_); 260 DCHECK_GE(current_address_index_, 0u);
eroman 2012/05/04 01:08:41 nit: trivially evaluates to true since index is un
szym 2012/05/04 02:38:29 True. This is a leftover of my first attempt with
261 DCHECK_LT(current_address_index_, addresses_.size());
262 DCHECK_EQ(0, connect_os_error_);
263 263
264 DCHECK_EQ(0, connect_os_error_); 264 const IPEndPoint& endpoint = addresses_[current_address_index_];
265 265
266 if (previously_disconnected_) { 266 if (previously_disconnected_) {
267 use_history_.Reset(); 267 use_history_.Reset();
268 previously_disconnected_ = false; 268 previously_disconnected_ = false;
269 } 269 }
270 270
271 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT, 271 net_log_.BeginEvent(NetLog::TYPE_TCP_CONNECT_ATTEMPT,
272 make_scoped_refptr(new NetLogStringParameter( 272 make_scoped_refptr(new NetLogStringParameter(
273 "address", NetAddressToStringWithPort(current_ai_)))); 273 "address",
274 endpoint.ToString())));
274 275
275 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE; 276 next_connect_state_ = CONNECT_STATE_CONNECT_COMPLETE;
276 277
277 if (bound_socket_ != kInvalidSocket) { 278 if (bound_socket_ != kInvalidSocket) {
278 DCHECK(bind_address_.get()); 279 DCHECK(bind_address_.get());
279 socket_ = bound_socket_; 280 socket_ = bound_socket_;
280 bound_socket_ = kInvalidSocket; 281 bound_socket_ = kInvalidSocket;
281 } else { 282 } else {
282 // Create a non-blocking socket. 283 // Create a non-blocking socket.
283 connect_os_error_ = CreateSocket(current_ai_->ai_family, &socket_); 284 connect_os_error_ = CreateSocket(endpoint.GetFamily(), &socket_);
284 if (connect_os_error_) 285 if (connect_os_error_)
285 return MapSystemError(connect_os_error_); 286 return MapSystemError(connect_os_error_);
286 287
287 if (bind_address_.get()) { 288 if (bind_address_.get()) {
288 sockaddr_storage addr_storage; 289 SockaddrStorage storage;
289 sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 290 if (!bind_address_->ToSockAddr(storage.addr, &storage.addr_len))
290 size_t addr_len = sizeof(addr_storage);
291 if (!bind_address_->ToSockAddr(addr, &addr_len))
292 return ERR_INVALID_ARGUMENT; 291 return ERR_INVALID_ARGUMENT;
293 if (HANDLE_EINTR(bind(socket_, addr, addr_len))) 292 if (HANDLE_EINTR(bind(socket_, storage.addr, storage.addr_len)))
294 return MapSystemError(errno); 293 return MapSystemError(errno);
295 } 294 }
296 } 295 }
297 296
298 // Connect the socket. 297 // Connect the socket.
299 if (!use_tcp_fastopen_) { 298 if (!use_tcp_fastopen_) {
299 SockaddrStorage storage;
300 if (!endpoint.ToSockAddr(storage.addr, &storage.addr_len))
eroman 2012/05/04 01:08:41 nit: This is duplicated in two locations. How abou
301 return ERR_INVALID_ARGUMENT;
302
300 connect_start_time_ = base::TimeTicks::Now(); 303 connect_start_time_ = base::TimeTicks::Now();
301 if (!HANDLE_EINTR(connect(socket_, current_ai_->ai_addr, 304 if (!HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len))) {
302 static_cast<int>(current_ai_->ai_addrlen)))) {
303 // Connected without waiting! 305 // Connected without waiting!
304 return OK; 306 return OK;
305 } 307 }
306 } else { 308 } else {
307 // With TCP FastOpen, we pretend that the socket is connected. 309 // With TCP FastOpen, we pretend that the socket is connected.
308 DCHECK(!tcp_fastopen_connected_); 310 DCHECK(!tcp_fastopen_connected_);
309 return OK; 311 return OK;
310 } 312 }
311 313
312 // Check if the connect() failed synchronously. 314 // Check if the connect() failed synchronously.
(...skipping 27 matching lines...) Expand all
340 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_; 342 connect_time_micros_ = base::TimeTicks::Now() - connect_start_time_;
341 write_socket_watcher_.StopWatchingFileDescriptor(); 343 write_socket_watcher_.StopWatchingFileDescriptor();
342 use_history_.set_was_ever_connected(); 344 use_history_.set_was_ever_connected();
343 return OK; // Done! 345 return OK; // Done!
344 } 346 }
345 347
346 // Close whatever partially connected socket we currently have. 348 // Close whatever partially connected socket we currently have.
347 DoDisconnect(); 349 DoDisconnect();
348 350
349 // Try to fall back to the next address in the list. 351 // Try to fall back to the next address in the list.
350 if (current_ai_->ai_next) { 352 if (current_address_index_ + 1 < addresses_.size()) {
eroman 2012/05/04 01:08:41 The reason I don't like current_address_index bein
351 next_connect_state_ = CONNECT_STATE_CONNECT; 353 next_connect_state_ = CONNECT_STATE_CONNECT;
352 current_ai_ = current_ai_->ai_next; 354 ++current_address_index_;
353 return OK; 355 return OK;
354 } 356 }
355 357
356 // Otherwise there is nothing to fall back to, so give up. 358 // Otherwise there is nothing to fall back to, so give up.
357 return result; 359 return result;
358 } 360 }
359 361
360 void TCPClientSocketLibevent::Disconnect() { 362 void TCPClientSocketLibevent::Disconnect() {
361 DCHECK(CalledOnValidThread()); 363 DCHECK(CalledOnValidThread());
362 364
363 DoDisconnect(); 365 DoDisconnect();
364 current_ai_ = NULL; 366 current_address_index_ = addresses_.size();
eroman 2012/05/04 01:08:41 This seems unnecessary... I would just delete it i
szym 2012/05/04 02:38:29 I was concerned that it was used to distinguish so
eroman 2012/05/04 19:37:36 Actually sorry, I changed my mind! I think it wou
365 } 367 }
366 368
367 void TCPClientSocketLibevent::DoDisconnect() { 369 void TCPClientSocketLibevent::DoDisconnect() {
368 if (socket_ == kInvalidSocket) 370 if (socket_ == kInvalidSocket)
369 return; 371 return;
370 372
371 bool ok = read_socket_watcher_.StopWatchingFileDescriptor(); 373 bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
372 DCHECK(ok); 374 DCHECK(ok);
373 ok = write_socket_watcher_.StopWatchingFileDescriptor(); 375 ok = write_socket_watcher_.StopWatchingFileDescriptor();
374 DCHECK(ok); 376 DCHECK(ok);
375 if (HANDLE_EINTR(close(socket_)) < 0) 377 if (HANDLE_EINTR(close(socket_)) < 0)
376 PLOG(ERROR) << "close"; 378 PLOG(ERROR) << "close";
377 socket_ = kInvalidSocket; 379 socket_ = kInvalidSocket;
378 previously_disconnected_ = true; 380 previously_disconnected_ = true;
379 } 381 }
380 382
381 bool TCPClientSocketLibevent::IsConnected() const { 383 bool TCPClientSocketLibevent::IsConnected() const {
382 DCHECK(CalledOnValidThread()); 384 DCHECK(CalledOnValidThread());
383 385
384 if (socket_ == kInvalidSocket || waiting_connect()) 386 if (socket_ == kInvalidSocket || waiting_connect())
385 return false; 387 return false;
386 388
387 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { 389 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) {
388 // With TCP FastOpen, we pretend that the socket is connected. 390 // With TCP FastOpen, we pretend that the socket is connected.
389 // This allows GetPeerAddress() to return current_ai_ as the peer 391 // This allows GetPeerAddress() to return current_ai_ as the peer
390 // address. Since we don't fail over to the next address if 392 // address. Since we don't fail over to the next address if
391 // sendto() fails, current_ai_ is the only possible peer address. 393 // sendto() fails, current_ai_ is the only possible peer address.
392 CHECK(current_ai_); 394 CHECK_LT(current_address_index_, addresses_.size());
393 return true; 395 return true;
394 } 396 }
395 397
396 // Check if connection is alive. 398 // Check if connection is alive.
397 char c; 399 char c;
398 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK)); 400 int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK));
399 if (rv == 0) 401 if (rv == 0)
400 return false; 402 return false;
401 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK) 403 if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
402 return false; 404 return false;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 500
499 write_buf_ = buf; 501 write_buf_ = buf;
500 write_buf_len_ = buf_len; 502 write_buf_len_ = buf_len;
501 write_callback_ = callback; 503 write_callback_ = callback;
502 return ERR_IO_PENDING; 504 return ERR_IO_PENDING;
503 } 505 }
504 506
505 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) { 507 int TCPClientSocketLibevent::InternalWrite(IOBuffer* buf, int buf_len) {
506 int nwrite; 508 int nwrite;
507 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) { 509 if (use_tcp_fastopen_ && !tcp_fastopen_connected_) {
510 SockaddrStorage storage;
511 if (!addresses_[current_address_index_].ToSockAddr(storage.addr,
eroman 2012/05/04 01:08:41 I have seen this in a couple places now. I think i
szym 2012/05/04 02:38:29 Not sure. |current_sockaddr_| would need to be a S
512 &storage.addr_len)) {
513 return ERR_INVALID_ARGUMENT;
514 }
515
508 // We have a limited amount of data to send in the SYN packet. 516 // We have a limited amount of data to send in the SYN packet.
509 int kMaxFastOpenSendLength = 1420; 517 int kMaxFastOpenSendLength = 1420;
510 518
511 buf_len = std::min(kMaxFastOpenSendLength, buf_len); 519 buf_len = std::min(kMaxFastOpenSendLength, buf_len);
512 520
513 int flags = 0x20000000; // Magic flag to enable TCP_FASTOPEN 521 int flags = 0x20000000; // Magic flag to enable TCP_FASTOPEN
514 nwrite = HANDLE_EINTR(sendto(socket_, 522 nwrite = HANDLE_EINTR(sendto(socket_,
515 buf->data(), 523 buf->data(),
516 buf_len, 524 buf_len,
517 flags, 525 flags,
518 current_ai_->ai_addr, 526 storage.addr,
519 static_cast<int>(current_ai_->ai_addrlen))); 527 storage.addr_len));
520 tcp_fastopen_connected_ = true; 528 tcp_fastopen_connected_ = true;
521 529
522 if (nwrite < 0) { 530 if (nwrite < 0) {
523 // Non-blocking mode is returning EINPROGRESS rather than EAGAIN. 531 // Non-blocking mode is returning EINPROGRESS rather than EAGAIN.
524 if (errno == EINPROGRESS) 532 if (errno == EINPROGRESS)
525 errno = EAGAIN; 533 errno = EAGAIN;
526 534
527 // Unlike "normal" nonblocking sockets, the data is already queued, 535 // Unlike "normal" nonblocking sockets, the data is already queued,
528 // so tell the app that we've consumed it. 536 // so tell the app that we've consumed it.
529 return buf_len; 537 return buf_len;
(...skipping 24 matching lines...) Expand all
554 562
555 void TCPClientSocketLibevent::LogConnectCompletion(int net_error) { 563 void TCPClientSocketLibevent::LogConnectCompletion(int net_error) {
556 if (net_error == OK) 564 if (net_error == OK)
557 UpdateConnectionTypeHistograms(CONNECTION_ANY); 565 UpdateConnectionTypeHistograms(CONNECTION_ANY);
558 566
559 if (net_error != OK) { 567 if (net_error != OK) {
560 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error); 568 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, net_error);
561 return; 569 return;
562 } 570 }
563 571
564 struct sockaddr_storage source_address; 572 SockaddrStorage storage;
565 socklen_t addrlen = sizeof(source_address); 573 int rv = getsockname(socket_, storage.addr, &storage.addr_len);
566 int rv = getsockname(
567 socket_, reinterpret_cast<struct sockaddr*>(&source_address), &addrlen);
568 if (rv != 0) { 574 if (rv != 0) {
569 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: "; 575 PLOG(ERROR) << "getsockname() [rv: " << rv << "] error: ";
570 NOTREACHED(); 576 NOTREACHED();
571 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv); 577 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_CONNECT, rv);
572 return; 578 return;
573 } 579 }
574 580
575 const std::string source_address_str = 581 const std::string source_address_str =
576 NetAddressToStringWithPort( 582 NetAddressToStringWithPort(storage.addr, storage.addr_len);
577 reinterpret_cast<const struct sockaddr*>(&source_address),
578 sizeof(source_address));
579 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT, 583 net_log_.EndEvent(NetLog::TYPE_TCP_CONNECT,
580 make_scoped_refptr(new NetLogStringParameter( 584 make_scoped_refptr(new NetLogStringParameter(
581 "source address", 585 "source address",
582 source_address_str))); 586 source_address_str)));
583 } 587 }
584 588
585 void TCPClientSocketLibevent::DoReadCallback(int rv) { 589 void TCPClientSocketLibevent::DoReadCallback(int rv) {
586 DCHECK_NE(rv, ERR_IO_PENDING); 590 DCHECK_NE(rv, ERR_IO_PENDING);
587 DCHECK(!read_callback_.is_null()); 591 DCHECK(!read_callback_.is_null());
588 592
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 write_socket_watcher_.StopWatchingFileDescriptor(); 681 write_socket_watcher_.StopWatchingFileDescriptor();
678 DoWriteCallback(result); 682 DoWriteCallback(result);
679 } 683 }
680 } 684 }
681 685
682 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const { 686 int TCPClientSocketLibevent::GetPeerAddress(AddressList* address) const {
683 DCHECK(CalledOnValidThread()); 687 DCHECK(CalledOnValidThread());
684 DCHECK(address); 688 DCHECK(address);
685 if (!IsConnected()) 689 if (!IsConnected())
686 return ERR_SOCKET_NOT_CONNECTED; 690 return ERR_SOCKET_NOT_CONNECTED;
687 *address = AddressList::CreateByCopyingFirstAddress(current_ai_); 691 *address = AddressList(addresses_[current_address_index_]);
688 return OK; 692 return OK;
689 } 693 }
690 694
691 int TCPClientSocketLibevent::GetLocalAddress(IPEndPoint* address) const { 695 int TCPClientSocketLibevent::GetLocalAddress(IPEndPoint* address) const {
692 DCHECK(CalledOnValidThread()); 696 DCHECK(CalledOnValidThread());
693 DCHECK(address); 697 DCHECK(address);
694 if (!IsConnected()) 698 if (!IsConnected())
695 return ERR_SOCKET_NOT_CONNECTED; 699 return ERR_SOCKET_NOT_CONNECTED;
696 700
697 struct sockaddr_storage addr_storage; 701 SockaddrStorage storage;
698 socklen_t addr_len = sizeof(addr_storage); 702 if (getsockname(socket_, storage.addr, &storage.addr_len))
699 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage);
700 if (getsockname(socket_, addr, &addr_len))
701 return MapSystemError(errno); 703 return MapSystemError(errno);
702 if (!address->FromSockAddr(addr, addr_len)) 704 if (!address->FromSockAddr(storage.addr, storage.addr_len))
703 return ERR_FAILED; 705 return ERR_FAILED;
704 706
705 return OK; 707 return OK;
706 } 708 }
707 709
708 const BoundNetLog& TCPClientSocketLibevent::NetLog() const { 710 const BoundNetLog& TCPClientSocketLibevent::NetLog() const {
709 return net_log_; 711 return net_log_;
710 } 712 }
711 713
712 void TCPClientSocketLibevent::SetSubresourceSpeculation() { 714 void TCPClientSocketLibevent::SetSubresourceSpeculation() {
(...skipping 18 matching lines...) Expand all
731 733
732 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const { 734 base::TimeDelta TCPClientSocketLibevent::GetConnectTimeMicros() const {
733 return connect_time_micros_; 735 return connect_time_micros_;
734 } 736 }
735 737
736 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const { 738 NextProto TCPClientSocketLibevent::GetNegotiatedProtocol() const {
737 return kProtoUnknown; 739 return kProtoUnknown;
738 } 740 }
739 741
740 } // namespace net 742 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698