1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/socket/tcp_server_socket_win.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <mstcpip.h> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/ip_endpoint.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_errors.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_util.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/winsock_init.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/winsock_util.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/socket/tcp_client_socket.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace net { 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTCPServerSocketWin::TCPServerSocketWin(net::NetLog* net_log, 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const net::NetLog::Source& source) 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : socket_(INVALID_SOCKET), 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket_event_(WSA_INVALID_EVENT), 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_socket_(NULL), 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_callback_(NULL), 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_refptr<NetLog::EventParameters> params; 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (source.is_valid()) 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen params = new NetLogSourceParameter("source_dependency", source); 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, params); 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EnsureWinsockInit(); 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTCPServerSocketWin::~TCPServerSocketWin() { 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Close(); 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE, NULL); 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint TCPServerSocketWin::Listen(const IPEndPoint& address, int backlog) { 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(backlog, 0); 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(socket_, INVALID_SOCKET); 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_EQ(socket_event_, WSA_INVALID_EVENT); 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket_event_ = WSACreateEvent(); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (socket_event_ == WSA_INVALID_EVENT) { 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "WSACreateEvent()"; 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ERR_FAILED; 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (socket_ < 0) { 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "socket() returned an error"; 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return MapSystemError(WSAGetLastError()); 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (SetNonBlocking(socket_)) { 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = MapSystemError(WSAGetLastError()); 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Close(); 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr_storage addr_storage; 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t addr_len = sizeof(addr_storage); 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!address.ToSockAddr(addr, &addr_len)) 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ERR_INVALID_ARGUMENT; 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = bind(socket_, addr, addr_len); 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result < 0) { 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "bind() returned an error"; 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = MapSystemError(WSAGetLastError()); 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Close(); 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = listen(socket_, backlog); 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result < 0) { 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "listen() returned an error"; 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result = MapSystemError(WSAGetLastError()); 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Close(); 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return OK; 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint TCPServerSocketWin::GetLocalAddress(IPEndPoint* address) const { 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(address); 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr_storage addr_storage; 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socklen_t addr_len = sizeof(addr_storage); 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (getsockname(socket_, addr, &addr_len)) 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return MapSystemError(WSAGetLastError()); 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!address->FromSockAddr(addr, addr_len)) 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ERR_FAILED; 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return OK; 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint TCPServerSocketWin::Accept( 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<ClientSocket>* socket, CompletionCallback* callback) { 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(CalledOnValidThread()); 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(socket); 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(callback); 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(!accept_callback_); 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.BeginEvent(NetLog::TYPE_TCP_ACCEPT, NULL); 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = AcceptInternal(socket); 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result == ERR_IO_PENDING) { 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Start watching 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WSAEventSelect(socket_, socket_event_, FD_ACCEPT); 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_watcher_.StartWatching(socket_event_, this); 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_socket_ = socket; 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_callback_ = callback; 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result; 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint TCPServerSocketWin::AcceptInternal(scoped_ptr<ClientSocket>* socket) { 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr_storage addr_storage; 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socklen_t addr_len = sizeof(addr_storage); 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = accept(socket_, addr, &addr_len); 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result < 0) { 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int net_error = MapSystemError(WSAGetLastError()); 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (net_error != ERR_IO_PENDING) 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return net_error; 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IPEndPoint address; 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!address.FromSockAddr(addr, addr_len)) { 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (closesocket(result) < 0) 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "closesocket"; 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, ERR_FAILED); 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ERR_FAILED; 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TCPClientSocket* tcp_socket = new TCPClientSocket( 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AddressList(address.address(), address.port(), false), 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.net_log(), net_log_.source()); 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen tcp_socket->AdoptSocket(result); 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket->reset(tcp_socket); 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net_log_.EndEvent(NetLog::TYPE_TCP_ACCEPT, 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen make_scoped_refptr(new NetLogStringParameter( 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "address", address.ToString()))); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return OK; 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TCPServerSocketWin::Close() { 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (socket_ != INVALID_SOCKET) { 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (closesocket(socket_) < 0) 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "closesocket"; 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket_ = INVALID_SOCKET; 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (socket_event_) { 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WSACloseEvent(socket_event_); 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen socket_event_ = WSA_INVALID_EVENT; 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TCPServerSocketWin::OnObjectSignaled(HANDLE object) { 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WSANETWORKEVENTS ev; 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (WSAEnumNetworkEvents(socket_, socket_event_, &ev) == SOCKET_ERROR) { 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PLOG(ERROR) << "WSAEnumNetworkEvents()"; 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (ev.lNetworkEvents & FD_ACCEPT) { 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int result = AcceptInternal(accept_socket_); 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (result != ERR_IO_PENDING) { 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CompletionCallback* c = accept_callback_; 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_callback_ = NULL; 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_socket_ = NULL; 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen c->Run(result); 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace net 188