1 // Copyright 2014 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.
5 #include "mojo/services/network/tcp_bound_socket_impl.h"
7 #include "mojo/services/network/net_adapters.h"
8 #include "mojo/services/network/net_address_type_converters.h"
9 #include "mojo/services/network/tcp_connected_socket_impl.h"
10 #include "mojo/services/network/tcp_server_socket_impl.h"
11 #include "net/base/net_errors.h"
15 TCPBoundSocketImpl::TCPBoundSocketImpl(
16 scoped_ptr
<mojo::AppRefCount
> app_refcount
,
17 InterfaceRequest
<TCPBoundSocket
> request
)
18 : app_refcount_(app_refcount
.Pass()), binding_(this, request
.Pass()) {
21 TCPBoundSocketImpl::~TCPBoundSocketImpl() {
24 int TCPBoundSocketImpl::Bind(NetAddressPtr local_address
) {
25 net::IPEndPoint end_point
= local_address
.To
<net::IPEndPoint
>();
27 socket_
.reset(new net::TCPSocket(NULL
, net::NetLog::Source()));
28 int result
= socket_
->Open(end_point
.GetFamily());
29 if (result
!= net::OK
)
32 result
= socket_
->SetDefaultOptionsForServer();
33 if (result
!= net::OK
)
36 result
= socket_
->Bind(end_point
);
37 if (result
!= net::OK
)
43 NetAddressPtr
TCPBoundSocketImpl::GetLocalAddress() const {
44 net::IPEndPoint resolved_local_address
;
45 if (socket_
->GetLocalAddress(&resolved_local_address
) != net::OK
)
46 return NetAddressPtr();
47 return NetAddress::From(resolved_local_address
);
50 void TCPBoundSocketImpl::StartListening(
51 InterfaceRequest
<TCPServerSocket
> server
,
52 const Callback
<void(NetworkErrorPtr
)>& callback
) {
53 if (!socket_
|| pending_connect_socket_
.is_pending()) {
54 // A bound socket will only be returned to the caller after binding
55 // succeeds, so if the socket doesn't exist, that means ownership was
56 // already passed to a server socket or client socket.
57 callback
.Run(MakeNetworkError(net::ERR_FAILED
));
61 // TODO(brettw) set the backlog properly.
62 int result
= socket_
->Listen(4);
63 if (result
!= net::OK
) {
64 callback
.Run(MakeNetworkError(result
));
68 // The server socket object takes ownership of the socket.
69 new TCPServerSocketImpl(socket_
.Pass(), app_refcount_
->Clone(),
71 callback
.Run(MakeNetworkError(net::OK
));
74 void TCPBoundSocketImpl::Connect(
75 NetAddressPtr remote_address
,
76 ScopedDataPipeConsumerHandle send_stream
,
77 ScopedDataPipeProducerHandle receive_stream
,
78 InterfaceRequest
<TCPConnectedSocket
> client_socket
,
79 const Callback
<void(NetworkErrorPtr
)>& callback
) {
80 if (!socket_
|| pending_connect_socket_
.is_pending()) {
81 // A bound socket will only be returned to the caller after binding
82 // succeeds, so if the socket doesn't exist, that means ownership was
83 // already passed to a server socket or client socket.
84 callback
.Run(MakeNetworkError(net::ERR_FAILED
));
88 net::IPEndPoint end_point
= remote_address
.To
<net::IPEndPoint
>();
90 pending_connect_send_stream_
= send_stream
.Pass();
91 pending_connect_receive_stream_
= receive_stream
.Pass();
92 pending_connect_socket_
= client_socket
.Pass();
93 pending_connect_callback_
= callback
;
94 int result
= socket_
->Connect(
96 base::Bind(&TCPBoundSocketImpl::OnConnected
, base::Unretained(this)));
97 if (result
== net::OK
) {
99 } else if (result
!= net::ERR_IO_PENDING
) {
101 pending_connect_send_stream_
.reset();
102 pending_connect_receive_stream_
.reset();
103 pending_connect_socket_
= InterfaceRequest
<TCPConnectedSocket
>();
104 pending_connect_callback_
= Callback
<void(NetworkErrorPtr
)>();
105 callback
.Run(MakeNetworkError(result
));
109 void TCPBoundSocketImpl::OnConnected(int result
) {
110 if (result
== net::OK
) {
111 new TCPConnectedSocketImpl(
112 socket_
.Pass(), pending_connect_send_stream_
.Pass(),
113 pending_connect_receive_stream_
.Pass(), pending_connect_socket_
.Pass(),
114 app_refcount_
->Clone());
116 pending_connect_send_stream_
.reset();
117 pending_connect_receive_stream_
.reset();
118 pending_connect_socket_
= InterfaceRequest
<TCPConnectedSocket
>();
120 pending_connect_callback_
.Run(MakeNetworkError(result
));
121 pending_connect_callback_
= Callback
<void(NetworkErrorPtr
)>();