1 // Copyright (c) 2012 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_listen_socket.h"
8 // winsock2.h must be included first in order to ensure it is included before
11 #elif defined(OS_POSIX)
12 #include <arpa/inet.h>
14 #include <netinet/in.h>
15 #include <sys/socket.h>
16 #include <sys/types.h>
17 #include "net/base/net_errors.h"
20 #include "base/logging.h"
21 #include "base/sys_byteorder.h"
22 #include "base/threading/platform_thread.h"
23 #include "build/build_config.h"
24 #include "net/base/net_util.h"
25 #include "net/base/winsock_init.h"
32 scoped_refptr
<TCPListenSocket
> TCPListenSocket::CreateAndListen(
33 const string
& ip
, int port
, StreamListenSocket::Delegate
* del
) {
34 SocketDescriptor s
= CreateAndBind(ip
, port
);
35 if (s
== kInvalidSocket
)
37 scoped_refptr
<TCPListenSocket
> sock(new TCPListenSocket(s
, del
));
42 TCPListenSocket::TCPListenSocket(SocketDescriptor s
,
43 StreamListenSocket::Delegate
* del
)
44 : StreamListenSocket(s
, del
) {
47 TCPListenSocket::~TCPListenSocket() {}
49 SocketDescriptor
TCPListenSocket::CreateAndBind(const string
& ip
, int port
) {
54 SocketDescriptor s
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
55 if (s
!= kInvalidSocket
) {
58 static const int kOn
= 1;
59 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, &kOn
, sizeof(kOn
));
62 memset(&addr
, 0, sizeof(addr
));
63 addr
.sin_family
= AF_INET
;
64 addr
.sin_addr
.s_addr
= inet_addr(ip
.c_str());
65 addr
.sin_port
= base::HostToNet16(port
);
66 if (bind(s
, reinterpret_cast<sockaddr
*>(&addr
), sizeof(addr
))) {
69 #elif defined(OS_POSIX)
72 LOG(ERROR
) << "Could not bind socket to " << ip
<< ":" << port
;
79 SocketDescriptor
TCPListenSocket::CreateAndBindAnyPort(const string
& ip
,
81 SocketDescriptor s
= CreateAndBind(ip
, 0);
82 if (s
== kInvalidSocket
)
83 return kInvalidSocket
;
85 socklen_t addr_size
= sizeof(addr
);
86 bool failed
= getsockname(s
, reinterpret_cast<struct sockaddr
*>(&addr
),
88 if (addr_size
!= sizeof(addr
))
91 LOG(ERROR
) << "Could not determine bound port, getsockname() failed";
94 #elif defined(OS_POSIX)
97 return kInvalidSocket
;
99 *port
= base::NetToHost16(addr
.sin_port
);
103 void TCPListenSocket::Accept() {
104 SocketDescriptor conn
= AcceptSocket();
105 if (conn
== kInvalidSocket
)
107 scoped_refptr
<TCPListenSocket
> sock(
108 new TCPListenSocket(conn
, socket_delegate_
));
109 // It's up to the delegate to AddRef if it wants to keep it around.
110 #if defined(OS_POSIX)
111 sock
->WatchSocket(WAITING_READ
);
113 socket_delegate_
->DidAccept(this, sock
.get());
116 TCPListenSocketFactory::TCPListenSocketFactory(const string
& ip
, int port
)
121 TCPListenSocketFactory::~TCPListenSocketFactory() {}
123 scoped_refptr
<StreamListenSocket
> TCPListenSocketFactory::CreateAndListen(
124 StreamListenSocket::Delegate
* delegate
) const {
125 return TCPListenSocket::CreateAndListen(ip_
, port_
, delegate
);