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

Side by Side Diff: chrome/test/chromedriver/net/port_server.cc

Issue 655063002: Use uint16 for port numbers more pervasively. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revert bad change Created 6 years, 1 month 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "chrome/test/chromedriver/net/port_server.h" 5 #include "chrome/test/chromedriver/net/port_server.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/process/process_handle.h" 10 #include "base/process/process_handle.h"
11 #include "base/rand_util.h" 11 #include "base/rand_util.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/sync_socket.h" 13 #include "base/sync_socket.h"
14 #include "chrome/test/chromedriver/chrome/status.h" 14 #include "chrome/test/chromedriver/chrome/status.h"
15 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h" 16 #include "net/base/net_log.h"
17 #include "net/base/net_util.h" 17 #include "net/base/net_util.h"
18 #include "net/base/sys_addrinfo.h" 18 #include "net/base/sys_addrinfo.h"
19 #include "net/socket/tcp_server_socket.h" 19 #include "net/socket/tcp_server_socket.h"
20 20
21 #if defined(OS_LINUX) 21 #if defined(OS_LINUX)
22 #include <sys/socket.h> 22 #include <sys/socket.h>
23 #include <sys/un.h> 23 #include <sys/un.h>
24 #endif 24 #endif
25 25
26 PortReservation::PortReservation(const base::Closure& on_free_func, int port) 26 PortReservation::PortReservation(const base::Closure& on_free_func, uint16 port)
27 : on_free_func_(on_free_func), port_(port) {} 27 : on_free_func_(on_free_func), port_(port) {}
28 28
29 PortReservation::~PortReservation() { 29 PortReservation::~PortReservation() {
30 if (!on_free_func_.is_null()) 30 if (!on_free_func_.is_null())
31 on_free_func_.Run(); 31 on_free_func_.Run();
32 } 32 }
33 33
34 void PortReservation::Leak() { 34 void PortReservation::Leak() {
35 LOG(ERROR) << "Port leaked: " << port_; 35 LOG(ERROR) << "Port leaked: " << port_;
36 on_free_func_.Reset(); 36 on_free_func_.Reset();
37 } 37 }
38 38
39 PortServer::PortServer(const std::string& path) : path_(path) { 39 PortServer::PortServer(const std::string& path) : path_(path) {
40 CHECK(path_.size() && path_[0] == 0) 40 CHECK(path_.size() && path_[0] == 0)
41 << "path must be for Linux abstract namespace"; 41 << "path must be for Linux abstract namespace";
42 } 42 }
43 43
44 PortServer::~PortServer() {} 44 PortServer::~PortServer() {}
45 45
46 Status PortServer::ReservePort(int* port, 46 Status PortServer::ReservePort(uint16* port,
47 scoped_ptr<PortReservation>* reservation) { 47 scoped_ptr<PortReservation>* reservation) {
48 int port_to_use = 0; 48 uint16 port_to_use = 0;
49 { 49 {
50 base::AutoLock lock(free_lock_); 50 base::AutoLock lock(free_lock_);
51 if (free_.size()) { 51 if (free_.size()) {
52 port_to_use = free_.front(); 52 port_to_use = free_.front();
53 free_.pop_front(); 53 free_.pop_front();
54 } 54 }
55 } 55 }
56 if (!port_to_use) { 56 if (!port_to_use) {
57 Status status = RequestPort(&port_to_use); 57 Status status = RequestPort(&port_to_use);
58 if (status.IsError()) 58 if (status.IsError())
59 return status; 59 return status;
60 } 60 }
61 *port = port_to_use; 61 *port = port_to_use;
62 reservation->reset(new PortReservation( 62 reservation->reset(new PortReservation(
63 base::Bind(&PortServer::ReleasePort, base::Unretained(this), port_to_use), 63 base::Bind(&PortServer::ReleasePort, base::Unretained(this), port_to_use),
64 port_to_use)); 64 port_to_use));
65 return Status(kOk); 65 return Status(kOk);
66 } 66 }
67 67
68 Status PortServer::RequestPort(int* port) { 68 Status PortServer::RequestPort(uint16* port) {
69 // The client sends its PID + \n, and the server responds with a port + \n, 69 // The client sends its PID + \n, and the server responds with a port + \n,
70 // which is valid for the lifetime of the referred process. 70 // which is valid for the lifetime of the referred process.
71 #if defined(OS_LINUX) 71 #if defined(OS_LINUX)
72 int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); 72 int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
73 if (sock_fd < 0) 73 if (sock_fd < 0)
74 return Status(kUnknownError, "unable to create socket"); 74 return Status(kUnknownError, "unable to create socket");
75 base::SyncSocket sock(sock_fd); 75 base::SyncSocket sock(sock_fd);
76 struct timeval tv; 76 struct timeval tv;
77 tv.tv_sec = 10; 77 tv.tv_sec = 10;
78 tv.tv_usec = 0; 78 tv.tv_usec = 0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if (!rv) 113 if (!rv)
114 break; 114 break;
115 response.push_back(c); 115 response.push_back(c);
116 } while (sock.Peek()); 116 } while (sock.Peek());
117 if (response.empty()) 117 if (response.empty())
118 return Status(kUnknownError, "failed to receive portserver response"); 118 return Status(kUnknownError, "failed to receive portserver response");
119 VLOG(0) << "PORTSERVER RESPONSE " << response; 119 VLOG(0) << "PORTSERVER RESPONSE " << response;
120 120
121 int new_port = 0; 121 int new_port = 0;
122 if (*response.rbegin() != '\n' || 122 if (*response.rbegin() != '\n' ||
123 !base::StringToInt(response.substr(0, response.length() - 1), &new_port)) 123 !base::StringToInt(response.substr(0, response.length() - 1),
124 &new_port) ||
125 new_port < 0 || new_port > 65535)
124 return Status(kUnknownError, "failed to parse portserver response"); 126 return Status(kUnknownError, "failed to parse portserver response");
125 *port = new_port; 127 *port = static_cast<uint16>(new_port);
126 return Status(kOk); 128 return Status(kOk);
127 #else 129 #else
128 return Status(kUnknownError, "not implemented for this platform"); 130 return Status(kUnknownError, "not implemented for this platform");
129 #endif 131 #endif
130 } 132 }
131 133
132 void PortServer::ReleasePort(int port) { 134 void PortServer::ReleasePort(uint16 port) {
133 base::AutoLock lock(free_lock_); 135 base::AutoLock lock(free_lock_);
134 free_.push_back(port); 136 free_.push_back(port);
135 } 137 }
136 138
137 PortManager::PortManager(int min_port, int max_port) 139 PortManager::PortManager(uint16 min_port, uint16 max_port)
138 : min_port_(min_port), max_port_(max_port) { 140 : min_port_(min_port), max_port_(max_port) {
139 CHECK_GE(max_port_, min_port_); 141 CHECK_GE(max_port_, min_port_);
140 } 142 }
141 143
142 PortManager::~PortManager() {} 144 PortManager::~PortManager() {}
143 145
144 int PortManager::FindAvailablePort() const { 146 uint16 PortManager::FindAvailablePort() const {
145 int start = base::RandInt(min_port_, max_port_); 147 uint16 start = static_cast<uint16>(base::RandInt(min_port_, max_port_));
146 bool wrapped = false; 148 bool wrapped = false;
147 for (int try_port = start; try_port != start || !wrapped; ++try_port) { 149 for (uint32 try_port = start; try_port != start || !wrapped; ++try_port) {
148 if (try_port > max_port_) { 150 if (try_port > max_port_) {
149 wrapped = true; 151 wrapped = true;
150 if (min_port_ == max_port_) 152 if (min_port_ == max_port_)
151 break; 153 break;
152 try_port = min_port_; 154 try_port = min_port_;
153 } 155 }
154 if (taken_.count(try_port)) 156 uint16 try_port_uint16 = static_cast<uint16>(try_port);
157 if (taken_.count(try_port_uint16))
155 continue; 158 continue;
156 159
157 char parts[] = {127, 0, 0, 1}; 160 char parts[] = {127, 0, 0, 1};
158 net::IPAddressNumber address(parts, parts + arraysize(parts)); 161 net::IPAddressNumber address(parts, parts + arraysize(parts));
159 net::NetLog::Source source; 162 net::NetLog::Source source;
160 net::TCPServerSocket sock(NULL, source); 163 net::TCPServerSocket sock(NULL, source);
161 if (sock.Listen(net::IPEndPoint(address, try_port), 1) == net::OK) 164 if (sock.Listen(net::IPEndPoint(address, try_port_uint16), 1) == net::OK)
162 return try_port; 165 return try_port_uint16;
163 } 166 }
164 return 0; 167 return 0;
165 } 168 }
166 169
167 Status PortManager::ReservePort(int* port, 170 Status PortManager::ReservePort(uint16* port,
168 scoped_ptr<PortReservation>* reservation) { 171 scoped_ptr<PortReservation>* reservation) {
169 base::AutoLock lock(lock_); 172 base::AutoLock lock(lock_);
170 int port_to_use = FindAvailablePort(); 173 uint16 port_to_use = FindAvailablePort();
171 if (!port_to_use) 174 if (!port_to_use)
172 return Status(kUnknownError, "unable to find open port"); 175 return Status(kUnknownError, "unable to find open port");
173 176
174 taken_.insert(port_to_use); 177 taken_.insert(port_to_use);
175 *port = port_to_use; 178 *port = port_to_use;
176 reservation->reset(new PortReservation( 179 reservation->reset(new PortReservation(
177 base::Bind(&PortManager::ReleasePort, base::Unretained(this), 180 base::Bind(&PortManager::ReleasePort, base::Unretained(this),
178 port_to_use), 181 port_to_use),
179 port_to_use)); 182 port_to_use));
180 return Status(kOk); 183 return Status(kOk);
181 } 184 }
182 185
183 Status PortManager::ReservePortFromPool( 186 Status PortManager::ReservePortFromPool(
184 int* port, scoped_ptr<PortReservation>* reservation) { 187 uint16* port,
188 scoped_ptr<PortReservation>* reservation) {
185 base::AutoLock lock(lock_); 189 base::AutoLock lock(lock_);
186 int port_to_use = 0; 190 uint16 port_to_use = 0;
187 if (unused_forwarded_port_.size()) { 191 if (unused_forwarded_port_.size()) {
188 port_to_use = unused_forwarded_port_.front(); 192 port_to_use = unused_forwarded_port_.front();
189 unused_forwarded_port_.pop_front(); 193 unused_forwarded_port_.pop_front();
190 } else { 194 } else {
191 port_to_use = FindAvailablePort(); 195 port_to_use = FindAvailablePort();
192 } 196 }
193 if (!port_to_use) 197 if (!port_to_use)
194 return Status(kUnknownError, "unable to find open port"); 198 return Status(kUnknownError, "unable to find open port");
195 199
196 taken_.insert(port_to_use); 200 taken_.insert(port_to_use);
197 *port = port_to_use; 201 *port = port_to_use;
198 reservation->reset(new PortReservation( 202 reservation->reset(new PortReservation(
199 base::Bind(&PortManager::ReleasePortToPool, base::Unretained(this), 203 base::Bind(&PortManager::ReleasePortToPool, base::Unretained(this),
200 port_to_use), 204 port_to_use),
201 port_to_use)); 205 port_to_use));
202 return Status(kOk); 206 return Status(kOk);
203 } 207 }
204 208
205 void PortManager::ReleasePort(int port) { 209 void PortManager::ReleasePort(uint16 port) {
206 base::AutoLock lock(lock_); 210 base::AutoLock lock(lock_);
207 taken_.erase(port); 211 taken_.erase(port);
208 } 212 }
209 213
210 void PortManager::ReleasePortToPool(int port) { 214 void PortManager::ReleasePortToPool(uint16 port) {
211 base::AutoLock lock(lock_); 215 base::AutoLock lock(lock_);
212 taken_.erase(port); 216 taken_.erase(port);
213 unused_forwarded_port_.push_back(port); 217 unused_forwarded_port_.push_back(port);
214 } 218 }
OLDNEW
« no previous file with comments | « chrome/test/chromedriver/net/port_server.h ('k') | chrome/test/chromedriver/net/port_server_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698