tcp_server_socket.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/socket/tcp_server_socket.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/logging.h" 10#include "build/build_config.h" 11#include "net/base/net_errors.h" 12#include "net/socket/tcp_client_socket.h" 13 14namespace net { 15 16TCPServerSocket::TCPServerSocket(NetLog* net_log, const NetLog::Source& source) 17 : socket_(net_log, source), 18 pending_accept_(false) { 19} 20 21TCPServerSocket::~TCPServerSocket() { 22} 23 24int TCPServerSocket::Listen(const IPEndPoint& address, int backlog) { 25 int result = socket_.Create(address.GetFamily()); 26 if (result != OK) 27 return result; 28 29 result = socket_.SetDefaultOptionsForServer(); 30 if (result != OK) { 31 socket_.Close(); 32 return result; 33 } 34 35 result = socket_.Bind(address); 36 if (result != OK) { 37 socket_.Close(); 38 return result; 39 } 40 41 result = socket_.Listen(backlog); 42 if (result != OK) { 43 socket_.Close(); 44 return result; 45 } 46 47 return OK; 48} 49 50int TCPServerSocket::GetLocalAddress(IPEndPoint* address) const { 51 return socket_.GetLocalAddress(address); 52} 53 54int TCPServerSocket::Accept(scoped_ptr<StreamSocket>* socket, 55 const CompletionCallback& callback) { 56 DCHECK(socket); 57 DCHECK(!callback.is_null()); 58 59 if (pending_accept_) { 60 NOTREACHED(); 61 return ERR_UNEXPECTED; 62 } 63 64 // It is safe to use base::Unretained(this). |socket_| is owned by this class, 65 // and the callback won't be run after |socket_| is destroyed. 66 CompletionCallback accept_callback = 67 base::Bind(&TCPServerSocket::OnAcceptCompleted, base::Unretained(this), 68 socket, callback); 69 int result = socket_.Accept(&accepted_socket_, &accepted_address_, 70 accept_callback); 71 if (result != ERR_IO_PENDING) { 72 // |accept_callback| won't be called so we need to run 73 // ConvertAcceptedSocket() ourselves in order to do the conversion from 74 // |accepted_socket_| to |socket|. 75 result = ConvertAcceptedSocket(result, socket); 76 } else { 77 pending_accept_ = true; 78 } 79 80 return result; 81} 82 83int TCPServerSocket::ConvertAcceptedSocket( 84 int result, 85 scoped_ptr<StreamSocket>* output_accepted_socket) { 86 // Make sure the TCPSocket object is destroyed in any case. 87 scoped_ptr<TCPSocket> temp_accepted_socket(accepted_socket_.Pass()); 88 if (result != OK) 89 return result; 90 91 scoped_ptr<TCPClientSocket> client_socket(new TCPClientSocket( 92 AddressList(accepted_address_), 93 temp_accepted_socket->net_log().net_log(), 94 temp_accepted_socket->net_log().source())); 95 // TODO(yzshen): Once we switch TCPClientSocket::AdoptSocket() to take a 96 // TCPSocket object, we don't need to do platform-specific handling. 97#if defined(OS_WIN) 98 SOCKET raw_socket = temp_accepted_socket->Release(); 99#elif defined(OS_POSIX) 100 int raw_socket = temp_accepted_socket->Release(); 101#endif 102 result = client_socket->AdoptSocket(raw_socket); 103 if (result != OK) { 104 // |client_socket| won't take ownership of |raw_socket| on failure. 105 // Therefore, we put it back into |temp_accepted_socket| to close it. 106 temp_accepted_socket->Adopt(raw_socket); 107 return result; 108 } 109 110 *output_accepted_socket = client_socket.Pass(); 111 return OK; 112} 113 114void TCPServerSocket::OnAcceptCompleted( 115 scoped_ptr<StreamSocket>* output_accepted_socket, 116 const CompletionCallback& forward_callback, 117 int result) { 118 result = ConvertAcceptedSocket(result, output_accepted_socket); 119 pending_accept_ = false; 120 forward_callback.Run(result); 121} 122 123} // namespace net 124