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() {
18 TCPBoundSocketImpl::~TCPBoundSocketImpl() {
21 int TCPBoundSocketImpl::Bind(NetAddressPtr local_address
) {
22 net::IPEndPoint end_point
= local_address
.To
<net::IPEndPoint
>();
24 socket_
.reset(new net::TCPSocket(NULL
, net::NetLog::Source()));
25 int result
= socket_
->Open(end_point
.GetFamily());
26 if (result
!= net::OK
)
29 result
= socket_
->SetDefaultOptionsForServer();
30 if (result
!= net::OK
)
33 result
= socket_
->Bind(end_point
);
34 if (result
!= net::OK
)
40 NetAddressPtr
TCPBoundSocketImpl::GetLocalAddress() const {
41 net::IPEndPoint resolved_local_address
;
42 if (socket_
->GetLocalAddress(&resolved_local_address
) != net::OK
)
43 return NetAddressPtr();
44 return NetAddress::From(resolved_local_address
);
47 void TCPBoundSocketImpl::StartListening(
48 InterfaceRequest
<TCPServerSocket
> server
,
49 const Callback
<void(NetworkErrorPtr
)>& callback
) {
50 if (!socket_
|| pending_connect_socket_
.is_pending()) {
51 // A bound socket will only be returned to the caller after binding
52 // succeeds, so if the socket doesn't exist, that means ownership was
53 // already passed to a server socket or client socket.
54 callback
.Run(MakeNetworkError(net::ERR_FAILED
));
58 // TODO(brettw) set the backlog properly.
59 int result
= socket_
->Listen(4);
60 if (result
!= net::OK
) {
61 callback
.Run(MakeNetworkError(result
));
65 // The server socket object takes ownership of the socket.
66 BindToRequest(new TCPServerSocketImpl(socket_
.Pass()), &server
);
67 callback
.Run(MakeNetworkError(net::OK
));
70 void TCPBoundSocketImpl::Connect(
71 NetAddressPtr remote_address
,
72 ScopedDataPipeConsumerHandle send_stream
,
73 ScopedDataPipeProducerHandle receive_stream
,
74 InterfaceRequest
<TCPConnectedSocket
> client_socket
,
75 const Callback
<void(NetworkErrorPtr
)>& callback
) {
76 if (!socket_
|| pending_connect_socket_
.is_pending()) {
77 // A bound socket will only be returned to the caller after binding
78 // succeeds, so if the socket doesn't exist, that means ownership was
79 // already passed to a server socket or client socket.
80 callback
.Run(MakeNetworkError(net::ERR_FAILED
));
84 net::IPEndPoint end_point
= remote_address
.To
<net::IPEndPoint
>();
86 pending_connect_send_stream_
= send_stream
.Pass();
87 pending_connect_receive_stream_
= receive_stream
.Pass();
88 pending_connect_socket_
= client_socket
.Pass();
89 pending_connect_callback_
= callback
;
90 int result
= socket_
->Connect(
92 base::Bind(&TCPBoundSocketImpl::OnConnected
, base::Unretained(this)));
93 if (result
== net::OK
) {
95 } else if (result
!= net::ERR_IO_PENDING
) {
97 pending_connect_send_stream_
.reset();
98 pending_connect_receive_stream_
.reset();
99 pending_connect_socket_
= InterfaceRequest
<TCPConnectedSocket
>();
100 pending_connect_callback_
= Callback
<void(NetworkErrorPtr
)>();
101 callback
.Run(MakeNetworkError(result
));
105 void TCPBoundSocketImpl::OnConnected(int result
) {
106 if (result
== net::OK
) {
107 new TCPConnectedSocketImpl(
108 socket_
.Pass(), pending_connect_send_stream_
.Pass(),
109 pending_connect_receive_stream_
.Pass(), pending_connect_socket_
.Pass());
111 pending_connect_send_stream_
.reset();
112 pending_connect_receive_stream_
.reset();
113 pending_connect_socket_
= InterfaceRequest
<TCPConnectedSocket
>();
115 pending_connect_callback_
.Run(MakeNetworkError(result
));
116 pending_connect_callback_
= Callback
<void(NetworkErrorPtr
)>();