Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: net/socket/tcp_server_socket_libevent.cc

Issue 10907154: Allow server sockets to rebind to same port if there is nothing actively listening on that port. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/socket/tcp_server_socket_libevent.h" 5 #include "net/socket/tcp_server_socket_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 17 matching lines...) Expand all
28 28
29 const int kInvalidSocket = -1; 29 const int kInvalidSocket = -1;
30 30
31 } // namespace 31 } // namespace
32 32
33 TCPServerSocketLibevent::TCPServerSocketLibevent( 33 TCPServerSocketLibevent::TCPServerSocketLibevent(
34 net::NetLog* net_log, 34 net::NetLog* net_log,
35 const net::NetLog::Source& source) 35 const net::NetLog::Source& source)
36 : socket_(kInvalidSocket), 36 : socket_(kInvalidSocket),
37 accept_socket_(NULL), 37 accept_socket_(NULL),
38 reuse_address_(false),
38 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) { 39 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {
39 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 40 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
40 source.ToEventParametersCallback()); 41 source.ToEventParametersCallback());
41 } 42 }
42 43
43 TCPServerSocketLibevent::~TCPServerSocketLibevent() { 44 TCPServerSocketLibevent::~TCPServerSocketLibevent() {
44 if (socket_ != kInvalidSocket) 45 if (socket_ != kInvalidSocket)
45 Close(); 46 Close();
46 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); 47 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE);
47 } 48 }
48 49
50 void TCPServerSocketLibevent::AllowAddressReuse() {
51 DCHECK(CalledOnValidThread());
52 DCHECK_EQ(socket_, kInvalidSocket);
53
54 reuse_address_ = true;
55 }
56
49 int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) { 57 int TCPServerSocketLibevent::Listen(const IPEndPoint& address, int backlog) {
50 DCHECK(CalledOnValidThread()); 58 DCHECK(CalledOnValidThread());
51 DCHECK_GT(backlog, 0); 59 DCHECK_GT(backlog, 0);
52 DCHECK_EQ(socket_, kInvalidSocket); 60 DCHECK_EQ(socket_, kInvalidSocket);
53 61
54 socket_ = socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP); 62 socket_ = socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
55 if (socket_ < 0) { 63 if (socket_ < 0) {
56 PLOG(ERROR) << "socket() returned an error"; 64 PLOG(ERROR) << "socket() returned an error";
57 return MapSystemError(errno); 65 return MapSystemError(errno);
58 } 66 }
59 67
60 if (SetNonBlocking(socket_)) { 68 if (SetNonBlocking(socket_)) {
61 int result = MapSystemError(errno); 69 int result = MapSystemError(errno);
62 Close(); 70 Close();
63 return result; 71 return result;
64 } 72 }
65 73
74 int result = SetSocketOptions();
75 if (result != OK) {
wtc 2012/09/14 19:20:17 Remove the curly braces {}. Also in tcp_server_so
justinlin 2012/09/15 19:03:25 Done.
76 return result;
77 }
78
66 SockaddrStorage storage; 79 SockaddrStorage storage;
67 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 80 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
68 return ERR_INVALID_ARGUMENT; 81 return ERR_INVALID_ARGUMENT;
69 82
70 int result = bind(socket_, storage.addr, storage.addr_len); 83 result = bind(socket_, storage.addr, storage.addr_len);
71 if (result < 0) { 84 if (result < 0) {
72 PLOG(ERROR) << "bind() returned an error"; 85 PLOG(ERROR) << "bind() returned an error";
73 result = MapSystemError(errno); 86 result = MapSystemError(errno);
74 Close(); 87 Close();
75 return result; 88 return result;
76 } 89 }
77 90
78 result = listen(socket_, backlog); 91 result = listen(socket_, backlog);
79 if (result < 0) { 92 if (result < 0) {
80 PLOG(ERROR) << "listen() returned an error"; 93 PLOG(ERROR) << "listen() returned an error";
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 return MapSystemError(errno); 131 return MapSystemError(errno);
119 } 132 }
120 133
121 accept_socket_ = socket; 134 accept_socket_ = socket;
122 accept_callback_ = callback; 135 accept_callback_ = callback;
123 } 136 }
124 137
125 return result; 138 return result;
126 } 139 }
127 140
141 int TCPServerSocketLibevent::SetSocketOptions() {
142 int true_value = 1;
143 if (reuse_address_) {
144 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value,
145 sizeof(true_value));
146 if (rv < 0)
147 return MapSystemError(errno);
148 }
149 return OK;
150 }
151
128 int TCPServerSocketLibevent::AcceptInternal( 152 int TCPServerSocketLibevent::AcceptInternal(
129 scoped_ptr<StreamSocket>* socket) { 153 scoped_ptr<StreamSocket>* socket) {
130 SockaddrStorage storage; 154 SockaddrStorage storage;
131 int new_socket = HANDLE_EINTR(accept(socket_, 155 int new_socket = HANDLE_EINTR(accept(socket_,
132 storage.addr, 156 storage.addr,
133 &storage.addr_len)); 157 &storage.addr_len));
134 if (new_socket < 0) { 158 if (new_socket < 0) {
135 int net_error = MapSystemError(errno); 159 int net_error = MapSystemError(errno);
136 if (net_error != ERR_IO_PENDING) 160 if (net_error != ERR_IO_PENDING)
137 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error); 161 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_TCP_ACCEPT, net_error);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 accept_callback_.Reset(); 208 accept_callback_.Reset();
185 callback.Run(result); 209 callback.Run(result);
186 } 210 }
187 } 211 }
188 212
189 void TCPServerSocketLibevent::OnFileCanWriteWithoutBlocking(int fd) { 213 void TCPServerSocketLibevent::OnFileCanWriteWithoutBlocking(int fd) {
190 NOTREACHED(); 214 NOTREACHED();
191 } 215 }
192 216
193 } // namespace net 217 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698