1 // Copyright (c) 2011 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 "net/socket/tcp_server_socket_win.h"
9 #include "net/base/ip_endpoint.h"
10 #include "net/base/net_errors.h"
11 #include "net/base/net_util.h"
12 #include "net/base/winsock_init.h"
13 #include "net/base/winsock_util.h"
14 #include "net/socket/tcp_client_socket.h"
18 TCPServerSocketWin::TCPServerSocketWin(net::NetLog
* net_log
,
19 const net::NetLog::Source
& source
)
20 : socket_(INVALID_SOCKET
),
21 socket_event_(WSA_INVALID_EVENT
),
23 net_log_(BoundNetLog::Make(net_log
, NetLog::SOURCE_SOCKET
)) {
24 scoped_refptr
<NetLog::EventParameters
> params
;
25 if (source
.is_valid())
26 params
= new NetLogSourceParameter("source_dependency", source
);
27 net_log_
.BeginEvent(NetLog::TYPE_SOCKET_ALIVE
, params
);
31 TCPServerSocketWin::~TCPServerSocketWin() {
33 net_log_
.EndEvent(NetLog::TYPE_SOCKET_ALIVE
, NULL
);
36 int TCPServerSocketWin::Listen(const IPEndPoint
& address
, int backlog
) {
37 DCHECK(CalledOnValidThread());
38 DCHECK_GT(backlog
, 0);
39 DCHECK_EQ(socket_
, INVALID_SOCKET
);
40 DCHECK_EQ(socket_event_
, WSA_INVALID_EVENT
);
42 socket_event_
= WSACreateEvent();
43 if (socket_event_
== WSA_INVALID_EVENT
) {
44 PLOG(ERROR
) << "WSACreateEvent()";
48 socket_
= socket(address
.GetFamily(), SOCK_STREAM
, IPPROTO_TCP
);
50 PLOG(ERROR
) << "socket() returned an error";
51 return MapSystemError(WSAGetLastError());
54 if (SetNonBlocking(socket_
)) {
55 int result
= MapSystemError(WSAGetLastError());
60 struct sockaddr_storage addr_storage
;
61 size_t addr_len
= sizeof(addr_storage
);
62 struct sockaddr
* addr
= reinterpret_cast<struct sockaddr
*>(&addr_storage
);
63 if (!address
.ToSockAddr(addr
, &addr_len
))
64 return ERR_INVALID_ARGUMENT
;
66 int result
= bind(socket_
, addr
, addr_len
);
68 PLOG(ERROR
) << "bind() returned an error";
69 result
= MapSystemError(WSAGetLastError());
74 result
= listen(socket_
, backlog
);
76 PLOG(ERROR
) << "listen() returned an error";
77 result
= MapSystemError(WSAGetLastError());
85 int TCPServerSocketWin::GetLocalAddress(IPEndPoint
* address
) const {
86 DCHECK(CalledOnValidThread());
89 struct sockaddr_storage addr_storage
;
90 socklen_t addr_len
= sizeof(addr_storage
);
91 struct sockaddr
* addr
= reinterpret_cast<struct sockaddr
*>(&addr_storage
);
92 if (getsockname(socket_
, addr
, &addr_len
))
93 return MapSystemError(WSAGetLastError());
94 if (!address
->FromSockAddr(addr
, addr_len
))
100 int TCPServerSocketWin::Accept(
101 scoped_ptr
<StreamSocket
>* socket
, const CompletionCallback
& callback
) {
102 DCHECK(CalledOnValidThread());
104 DCHECK(!callback
.is_null());
105 DCHECK(accept_callback_
.is_null());
107 net_log_
.BeginEvent(NetLog::TYPE_TCP_ACCEPT
, NULL
);
109 int result
= AcceptInternal(socket
);
111 if (result
== ERR_IO_PENDING
) {
113 WSAEventSelect(socket_
, socket_event_
, FD_ACCEPT
);
114 accept_watcher_
.StartWatching(socket_event_
, this);
116 accept_socket_
= socket
;
117 accept_callback_
= callback
;
123 int TCPServerSocketWin::AcceptInternal(scoped_ptr
<StreamSocket
>* socket
) {
124 struct sockaddr_storage addr_storage
;
125 socklen_t addr_len
= sizeof(addr_storage
);
126 struct sockaddr
* addr
= reinterpret_cast<struct sockaddr
*>(&addr_storage
);
128 int new_socket
= accept(socket_
, addr
, &addr_len
);
129 if (new_socket
< 0) {
130 int net_error
= MapSystemError(WSAGetLastError());
131 if (net_error
!= ERR_IO_PENDING
)
132 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT
, net_error
);
137 if (!address
.FromSockAddr(addr
, addr_len
)) {
139 if (closesocket(new_socket
) < 0)
140 PLOG(ERROR
) << "closesocket";
141 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT
, ERR_FAILED
);
144 scoped_ptr
<TCPClientSocket
> tcp_socket(new TCPClientSocket(
145 AddressList::CreateFromIPAddress(address
.address(), address
.port()),
146 net_log_
.net_log(), net_log_
.source()));
147 int adopt_result
= tcp_socket
->AdoptSocket(new_socket
);
148 if (adopt_result
!= OK
) {
149 if (closesocket(new_socket
) < 0)
150 PLOG(ERROR
) << "closesocket";
151 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT
, adopt_result
);
154 socket
->reset(tcp_socket
.release());
155 net_log_
.EndEvent(NetLog::TYPE_TCP_ACCEPT
,
156 make_scoped_refptr(new NetLogStringParameter(
157 "address", address
.ToString())));
161 void TCPServerSocketWin::Close() {
162 if (socket_
!= INVALID_SOCKET
) {
163 if (closesocket(socket_
) < 0)
164 PLOG(ERROR
) << "closesocket";
165 socket_
= INVALID_SOCKET
;
169 WSACloseEvent(socket_event_
);
170 socket_event_
= WSA_INVALID_EVENT
;
174 void TCPServerSocketWin::OnObjectSignaled(HANDLE object
) {
176 if (WSAEnumNetworkEvents(socket_
, socket_event_
, &ev
) == SOCKET_ERROR
) {
177 PLOG(ERROR
) << "WSAEnumNetworkEvents()";
181 if (ev
.lNetworkEvents
& FD_ACCEPT
) {
182 int result
= AcceptInternal(accept_socket_
);
183 if (result
!= ERR_IO_PENDING
) {
184 accept_socket_
= NULL
;
185 accept_callback_
.Run(result
);
186 accept_callback_
.Reset();