• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "net/base/net_errors.h"
11 #include "net/socket/tcp_client_socket.h"
12 
13 namespace net {
14 
TCPServerSocket(NetLog * net_log,const NetLog::Source & source)15 TCPServerSocket::TCPServerSocket(NetLog* net_log, const NetLog::Source& source)
16     : socket_(net_log, source),
17       pending_accept_(false) {
18 }
19 
~TCPServerSocket()20 TCPServerSocket::~TCPServerSocket() {
21 }
22 
Listen(const IPEndPoint & address,int backlog)23 int TCPServerSocket::Listen(const IPEndPoint& address, int backlog) {
24   int result = socket_.Open(address.GetFamily());
25   if (result != OK)
26     return result;
27 
28   result = socket_.SetDefaultOptionsForServer();
29   if (result != OK) {
30     socket_.Close();
31     return result;
32   }
33 
34   result = socket_.Bind(address);
35   if (result != OK) {
36     socket_.Close();
37     return result;
38   }
39 
40   result = socket_.Listen(backlog);
41   if (result != OK) {
42     socket_.Close();
43     return result;
44   }
45 
46   return OK;
47 }
48 
GetLocalAddress(IPEndPoint * address) const49 int TCPServerSocket::GetLocalAddress(IPEndPoint* address) const {
50   return socket_.GetLocalAddress(address);
51 }
52 
Accept(scoped_ptr<StreamSocket> * socket,const CompletionCallback & callback)53 int TCPServerSocket::Accept(scoped_ptr<StreamSocket>* socket,
54                             const CompletionCallback& callback) {
55   DCHECK(socket);
56   DCHECK(!callback.is_null());
57 
58   if (pending_accept_) {
59     NOTREACHED();
60     return ERR_UNEXPECTED;
61   }
62 
63   // It is safe to use base::Unretained(this). |socket_| is owned by this class,
64   // and the callback won't be run after |socket_| is destroyed.
65   CompletionCallback accept_callback =
66       base::Bind(&TCPServerSocket::OnAcceptCompleted, base::Unretained(this),
67                  socket, callback);
68   int result = socket_.Accept(&accepted_socket_, &accepted_address_,
69                               accept_callback);
70   if (result != ERR_IO_PENDING) {
71     // |accept_callback| won't be called so we need to run
72     // ConvertAcceptedSocket() ourselves in order to do the conversion from
73     // |accepted_socket_| to |socket|.
74     result = ConvertAcceptedSocket(result, socket);
75   } else {
76     pending_accept_ = true;
77   }
78 
79   return result;
80 }
81 
ConvertAcceptedSocket(int result,scoped_ptr<StreamSocket> * output_accepted_socket)82 int TCPServerSocket::ConvertAcceptedSocket(
83     int result,
84     scoped_ptr<StreamSocket>* output_accepted_socket) {
85   // Make sure the TCPSocket object is destroyed in any case.
86   scoped_ptr<TCPSocket> temp_accepted_socket(accepted_socket_.Pass());
87   if (result != OK)
88     return result;
89 
90   output_accepted_socket->reset(new TCPClientSocket(
91       temp_accepted_socket.Pass(), accepted_address_));
92 
93   return OK;
94 }
95 
OnAcceptCompleted(scoped_ptr<StreamSocket> * output_accepted_socket,const CompletionCallback & forward_callback,int result)96 void TCPServerSocket::OnAcceptCompleted(
97     scoped_ptr<StreamSocket>* output_accepted_socket,
98     const CompletionCallback& forward_callback,
99     int result) {
100   result = ConvertAcceptedSocket(result, output_accepted_socket);
101   pending_accept_ = false;
102   forward_callback.Run(result);
103 }
104 
105 }  // namespace net
106