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

Side by Side Diff: tools/android/forwarder2/socket.cc

Issue 68893013: Fix socket usage in forwarder2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « tools/android/forwarder2/socket.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "tools/android/forwarder2/socket.h" 5 #include "tools/android/forwarder2/socket.h"
6 6
7 #include <arpa/inet.h> 7 #include <arpa/inet.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <netdb.h> 9 #include <netdb.h>
10 #include <netinet/in.h> 10 #include <netinet/in.h>
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 socket_ = -1; 93 socket_ = -1;
94 } 94 }
95 } 95 }
96 96
97 bool Socket::InitSocketInternal() { 97 bool Socket::InitSocketInternal() {
98 socket_ = socket(family_, SOCK_STREAM, 0); 98 socket_ = socket(family_, SOCK_STREAM, 0);
99 if (socket_ < 0) 99 if (socket_ < 0)
100 return false; 100 return false;
101 tools::DisableNagle(socket_); 101 tools::DisableNagle(socket_);
102 int reuse_addr = 1; 102 int reuse_addr = 1;
103 setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 103 setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
104 &reuse_addr, sizeof(reuse_addr)); 104 sizeof(reuse_addr));
105 if (!SetNonBlocking())
106 return false;
105 return true; 107 return true;
106 } 108 }
107 109
110 bool Socket::SetNonBlocking() {
111 const int flags = fcntl(socket_, F_GETFL);
112 if (flags < 0) {
113 PLOG(ERROR) << "fcntl";
114 return false;
115 }
116 if (flags & O_NONBLOCK)
117 return true;
118 if (fcntl(socket_, F_SETFL, flags | O_NONBLOCK) < 0) {
119 PLOG(ERROR) << "fcntl";
120 return false;
121 }
122 return true;
123 }
124
108 bool Socket::InitUnixSocket(const std::string& path) { 125 bool Socket::InitUnixSocket(const std::string& path) {
109 static const size_t kPathMax = sizeof(addr_.addr_un.sun_path); 126 static const size_t kPathMax = sizeof(addr_.addr_un.sun_path);
110 // For abstract sockets we need one extra byte for the leading zero. 127 // For abstract sockets we need one extra byte for the leading zero.
111 if (path.size() + 2 /* '\0' */ > kPathMax) { 128 if (path.size() + 2 /* '\0' */ > kPathMax) {
112 LOG(ERROR) << "The provided path is too big to create a unix " 129 LOG(ERROR) << "The provided path is too big to create a unix "
113 << "domain socket: " << path; 130 << "domain socket: " << path;
114 return false; 131 return false;
115 } 132 }
116 family_ = PF_UNIX; 133 family_ = PF_UNIX;
117 addr_.addr_un.sun_family = family_; 134 addr_.addr_un.sun_family = family_;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr4); 184 addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr4);
168 port_ptr = &addr.addr4.sin_port; 185 port_ptr = &addr.addr4.sin_port;
169 addrlen = sizeof(addr.addr4); 186 addrlen = sizeof(addr.addr4);
170 } else if (family_ == AF_INET6) { 187 } else if (family_ == AF_INET6) {
171 addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr6); 188 addr_ptr = reinterpret_cast<sockaddr*>(&addr.addr6);
172 port_ptr = &addr.addr6.sin6_port; 189 port_ptr = &addr.addr6.sin6_port;
173 addrlen = sizeof(addr.addr6); 190 addrlen = sizeof(addr.addr6);
174 } 191 }
175 errno = 0; 192 errno = 0;
176 if (getsockname(socket_, addr_ptr, &addrlen) != 0) { 193 if (getsockname(socket_, addr_ptr, &addrlen) != 0) {
177 LOG(ERROR) << "getsockname error: " << safe_strerror(errno);; 194 PLOG(ERROR) << "getsockname";
178 SetSocketError(); 195 SetSocketError();
179 return false; 196 return false;
180 } 197 }
181 port_ = ntohs(*port_ptr); 198 port_ = ntohs(*port_ptr);
182 } 199 }
183 return true; 200 return true;
184 } 201 }
185 202
186 bool Socket::Accept(Socket* new_socket) { 203 bool Socket::Accept(Socket* new_socket) {
187 DCHECK(new_socket != NULL); 204 DCHECK(new_socket != NULL);
188 if (!WaitForEvent(READ, kNoTimeout)) { 205 if (!WaitForEvent(READ, kNoTimeout)) {
189 SetSocketError(); 206 SetSocketError();
190 return false; 207 return false;
191 } 208 }
192 errno = 0; 209 errno = 0;
193 int new_socket_fd = HANDLE_EINTR(accept(socket_, NULL, NULL)); 210 int new_socket_fd = HANDLE_EINTR(accept(socket_, NULL, NULL));
194 if (new_socket_fd < 0) { 211 if (new_socket_fd < 0) {
195 SetSocketError(); 212 SetSocketError();
196 return false; 213 return false;
197 } 214 }
198
199 tools::DisableNagle(new_socket_fd); 215 tools::DisableNagle(new_socket_fd);
200 new_socket->socket_ = new_socket_fd; 216 new_socket->socket_ = new_socket_fd;
217 if (!new_socket->SetNonBlocking())
218 return false;
201 return true; 219 return true;
202 } 220 }
203 221
204 bool Socket::Connect() { 222 bool Socket::Connect() {
205 // Set non-block because we use select for connect. 223 DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
206 const int kFlags = fcntl(socket_, F_GETFL);
207 DCHECK(!(kFlags & O_NONBLOCK));
208 fcntl(socket_, F_SETFL, kFlags | O_NONBLOCK);
209 errno = 0; 224 errno = 0;
210 if (HANDLE_EINTR(connect(socket_, addr_ptr_, addr_len_)) < 0 && 225 if (HANDLE_EINTR(connect(socket_, addr_ptr_, addr_len_)) < 0 &&
211 errno != EINPROGRESS) { 226 errno != EINPROGRESS) {
212 SetSocketError(); 227 SetSocketError();
213 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
214 return false; 228 return false;
215 } 229 }
216 // Wait for connection to complete, or receive a notification. 230 // Wait for connection to complete, or receive a notification.
217 if (!WaitForEvent(WRITE, kConnectTimeOut)) { 231 if (!WaitForEvent(WRITE, kConnectTimeOut)) {
218 SetSocketError(); 232 SetSocketError();
219 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
220 return false; 233 return false;
221 } 234 }
222 int socket_errno; 235 int socket_errno;
223 socklen_t opt_len = sizeof(socket_errno); 236 socklen_t opt_len = sizeof(socket_errno);
224 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &socket_errno, &opt_len) < 0) { 237 if (getsockopt(socket_, SOL_SOCKET, SO_ERROR, &socket_errno, &opt_len) < 0) {
225 LOG(ERROR) << "getsockopt(): " << safe_strerror(errno); 238 PLOG(ERROR) << "getsockopt()";
226 SetSocketError(); 239 SetSocketError();
227 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
228 return false; 240 return false;
229 } 241 }
230 if (socket_errno != 0) { 242 if (socket_errno != 0) {
231 LOG(ERROR) << "Could not connect to host: " << safe_strerror(socket_errno); 243 LOG(ERROR) << "Could not connect to host: " << safe_strerror(socket_errno);
232 SetSocketError(); 244 SetSocketError();
233 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags));
234 return false; 245 return false;
235 } 246 }
236 fcntl(socket_, F_SETFL, kFlags);
237 return true; 247 return true;
238 } 248 }
239 249
240 bool Socket::Resolve(const std::string& host) { 250 bool Socket::Resolve(const std::string& host) {
241 struct addrinfo hints; 251 struct addrinfo hints;
242 struct addrinfo* res; 252 struct addrinfo* res;
243 memset(&hints, 0, sizeof(hints)); 253 memset(&hints, 0, sizeof(hints));
244 hints.ai_family = AF_UNSPEC; 254 hints.ai_family = AF_UNSPEC;
245 hints.ai_socktype = SOCK_STREAM; 255 hints.ai_socktype = SOCK_STREAM;
246 hints.ai_flags |= AI_CANONNAME; 256 hints.ai_flags |= AI_CANONNAME;
247 257
248 int errcode = getaddrinfo(host.c_str(), NULL, &hints, &res); 258 int errcode = getaddrinfo(host.c_str(), NULL, &hints, &res);
249 if (errcode != 0) { 259 if (errcode != 0) {
260 errno = 0;
250 SetSocketError(); 261 SetSocketError();
251 freeaddrinfo(res); 262 freeaddrinfo(res);
252 return false; 263 return false;
253 } 264 }
254 family_ = res->ai_family; 265 family_ = res->ai_family;
255 switch (res->ai_family) { 266 switch (res->ai_family) {
256 case AF_INET: 267 case AF_INET:
257 memcpy(&addr_.addr4, 268 memcpy(&addr_.addr4,
258 reinterpret_cast<sockaddr_in*>(res->ai_addr), 269 reinterpret_cast<sockaddr_in*>(res->ai_addr),
259 sizeof(sockaddr_in)); 270 sizeof(sockaddr_in));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 while (bytes_read < num_bytes && ret > 0) { 306 while (bytes_read < num_bytes && ret > 0) {
296 ret = Read(static_cast<char*>(buffer) + bytes_read, num_bytes - bytes_read); 307 ret = Read(static_cast<char*>(buffer) + bytes_read, num_bytes - bytes_read);
297 if (ret >= 0) 308 if (ret >= 0)
298 bytes_read += ret; 309 bytes_read += ret;
299 } 310 }
300 return bytes_read; 311 return bytes_read;
301 } 312 }
302 313
303 void Socket::SetSocketError() { 314 void Socket::SetSocketError() {
304 socket_error_ = true; 315 socket_error_ = true;
305 // We never use non-blocking socket. 316 DCHECK_NE(EAGAIN, errno);
306 DCHECK(errno != EAGAIN && errno != EWOULDBLOCK); 317 DCHECK_NE(EWOULDBLOCK, errno);
307 Close(); 318 Close();
308 } 319 }
309 320
310 int Socket::Read(void* buffer, size_t buffer_size) { 321 int Socket::Read(void* buffer, size_t buffer_size) {
311 if (!WaitForEvent(READ, kNoTimeout)) { 322 if (!WaitForEvent(READ, kNoTimeout)) {
312 SetSocketError(); 323 SetSocketError();
313 return 0; 324 return 0;
314 } 325 }
315 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size)); 326 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size));
316 if (ret < 0) 327 if (ret < 0) {
328 PLOG(ERROR) << "read";
317 SetSocketError(); 329 SetSocketError();
330 }
331 return ret;
332 }
333
334 int Socket::NonBlockingRead(void* buffer, size_t buffer_size) {
335 DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
digit1 2013/11/13 10:28:42 I really like this DCHECK(), thanks :)
336 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size));
337 if (ret < 0) {
338 PLOG(ERROR) << "read";
339 SetSocketError();
340 }
318 return ret; 341 return ret;
319 } 342 }
320 343
321 int Socket::Write(const void* buffer, size_t count) { 344 int Socket::Write(const void* buffer, size_t count) {
345 if (!WaitForEvent(WRITE, kNoTimeout)) {
346 SetSocketError();
347 return 0;
348 }
322 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); 349 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL));
323 if (ret < 0) 350 if (ret < 0) {
351 PLOG(ERROR) << "send";
324 SetSocketError(); 352 SetSocketError();
353 }
325 return ret; 354 return ret;
326 } 355 }
327 356
357 int Socket::NonBlockingWrite(const void* buffer, size_t count) {
358 DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
359 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL));
360 if (ret < 0) {
361 PLOG(ERROR) << "send";
362 SetSocketError();
363 }
364 return ret;
365 }
366
328 int Socket::WriteString(const std::string& buffer) { 367 int Socket::WriteString(const std::string& buffer) {
329 return WriteNumBytes(buffer.c_str(), buffer.size()); 368 return WriteNumBytes(buffer.c_str(), buffer.size());
330 } 369 }
331 370
332 void Socket::AddEventFd(int event_fd) { 371 void Socket::AddEventFd(int event_fd) {
333 Event event; 372 Event event;
334 event.fd = event_fd; 373 event.fd = event_fd;
335 event.was_fired = false; 374 event.was_fired = false;
336 events_.push_back(event); 375 events_.push_back(event);
337 } 376 }
(...skipping 18 matching lines...) Expand all
356 while (bytes_written < num_bytes && ret > 0) { 395 while (bytes_written < num_bytes && ret > 0) {
357 ret = Write(static_cast<const char*>(buffer) + bytes_written, 396 ret = Write(static_cast<const char*>(buffer) + bytes_written,
358 num_bytes - bytes_written); 397 num_bytes - bytes_written);
359 if (ret >= 0) 398 if (ret >= 0)
360 bytes_written += ret; 399 bytes_written += ret;
361 } 400 }
362 return bytes_written; 401 return bytes_written;
363 } 402 }
364 403
365 bool Socket::WaitForEvent(EventType type, int timeout_secs) { 404 bool Socket::WaitForEvent(EventType type, int timeout_secs) {
366 if (events_.empty() || socket_ == -1) 405 if (socket_ == -1)
367 return true; 406 return true;
407 DCHECK(fcntl(socket_, F_GETFL) & O_NONBLOCK);
368 fd_set read_fds; 408 fd_set read_fds;
369 fd_set write_fds; 409 fd_set write_fds;
370 FD_ZERO(&read_fds); 410 FD_ZERO(&read_fds);
371 FD_ZERO(&write_fds); 411 FD_ZERO(&write_fds);
372 if (type == READ) 412 if (type == READ)
373 FD_SET(socket_, &read_fds); 413 FD_SET(socket_, &read_fds);
374 else 414 else
375 FD_SET(socket_, &write_fds); 415 FD_SET(socket_, &write_fds);
376 for (size_t i = 0; i < events_.size(); ++i) 416 for (size_t i = 0; i < events_.size(); ++i)
377 FD_SET(events_[i].fd, &read_fds); 417 FD_SET(events_[i].fd, &read_fds);
378 timeval tv = {}; 418 timeval tv = {};
379 timeval* tv_ptr = NULL; 419 timeval* tv_ptr = NULL;
380 if (timeout_secs > 0) { 420 if (timeout_secs > 0) {
381 tv.tv_sec = timeout_secs; 421 tv.tv_sec = timeout_secs;
382 tv.tv_usec = 0; 422 tv.tv_usec = 0;
383 tv_ptr = &tv; 423 tv_ptr = &tv;
384 } 424 }
385 int max_fd = socket_; 425 int max_fd = socket_;
386 for (size_t i = 0; i < events_.size(); ++i) 426 for (size_t i = 0; i < events_.size(); ++i)
387 if (events_[i].fd > max_fd) 427 if (events_[i].fd > max_fd)
388 max_fd = events_[i].fd; 428 max_fd = events_[i].fd;
389 if (HANDLE_EINTR( 429 if (HANDLE_EINTR(
390 select(max_fd + 1, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) { 430 select(max_fd + 1, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) {
431 PLOG(ERROR) << "select";
391 return false; 432 return false;
392 } 433 }
393 bool event_was_fired = false; 434 bool event_was_fired = false;
394 for (size_t i = 0; i < events_.size(); ++i) { 435 for (size_t i = 0; i < events_.size(); ++i) {
395 if (FD_ISSET(events_[i].fd, &read_fds)) { 436 if (FD_ISSET(events_[i].fd, &read_fds)) {
396 events_[i].was_fired = true; 437 events_[i].was_fired = true;
397 event_was_fired = true; 438 event_was_fired = true;
398 } 439 }
399 } 440 }
400 return !event_was_fired; 441 return !event_was_fired;
(...skipping 12 matching lines...) Expand all
413 ucred ucred; 454 ucred ucred;
414 socklen_t len = sizeof(ucred); 455 socklen_t len = sizeof(ucred);
415 if (getsockopt(socket.socket_, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) { 456 if (getsockopt(socket.socket_, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
416 CHECK_NE(ENOPROTOOPT, errno); 457 CHECK_NE(ENOPROTOOPT, errno);
417 return -1; 458 return -1;
418 } 459 }
419 return ucred.pid; 460 return ucred.pid;
420 } 461 }
421 462
422 } // namespace forwarder2 463 } // namespace forwarder2
OLDNEW
« no previous file with comments | « tools/android/forwarder2/socket.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698