OLD | NEW |
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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 } | 81 } |
82 | 82 |
83 Socket::Socket() | 83 Socket::Socket() |
84 : socket_(-1), | 84 : socket_(-1), |
85 port_(0), | 85 port_(0), |
86 socket_error_(false), | 86 socket_error_(false), |
87 family_(AF_INET), | 87 family_(AF_INET), |
88 abstract_(false), | 88 abstract_(false), |
89 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)), | 89 addr_ptr_(reinterpret_cast<sockaddr*>(&addr_.addr4)), |
90 addr_len_(sizeof(sockaddr)), | 90 addr_len_(sizeof(sockaddr)), |
91 exit_notifier_fd_(-1) { | 91 exit_notifier_fd_(-1), |
| 92 exited_(-1) { |
92 memset(&addr_, 0, sizeof(addr_)); | 93 memset(&addr_, 0, sizeof(addr_)); |
93 } | 94 } |
94 | 95 |
95 Socket::~Socket() { | 96 Socket::~Socket() { |
96 CHECK(IsClosed()); | 97 Close(); |
97 } | 98 } |
98 | 99 |
99 void Socket::Shutdown() { | 100 void Socket::Shutdown() { |
100 if (!IsClosed()) { | 101 if (!IsClosed()) { |
101 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR)); | 102 PRESERVE_ERRNO_HANDLE_EINTR(shutdown(socket_, SHUT_RDWR)); |
102 } | 103 } |
103 } | 104 } |
104 | 105 |
105 void Socket::Close() { | 106 void Socket::Close() { |
106 if (!IsClosed()) { | 107 if (!IsClosed()) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 SetSocketError(); | 236 SetSocketError(); |
236 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); | 237 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); |
237 return false; | 238 return false; |
238 } | 239 } |
239 // Wait for connection to complete, or receive a notification. | 240 // Wait for connection to complete, or receive a notification. |
240 if (!WaitForEvent(WRITE, kConnectTimeOut)) { | 241 if (!WaitForEvent(WRITE, kConnectTimeOut)) { |
241 SetSocketError(); | 242 SetSocketError(); |
242 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); | 243 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); |
243 return false; | 244 return false; |
244 } | 245 } |
245 // Disable non-block since our code assumes blocking semantics. | 246 int socket_errno; |
| 247 socklen_t opt_len = sizeof(socket_errno); |
| 248 if (!getsockopt(socket_, SOL_SOCKET, SO_ERROR, &socket_errno, &opt_len) < 0) { |
| 249 LOG(ERROR) << "getsockopt(): " << safe_strerror(errno); |
| 250 SetSocketError(); |
| 251 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); |
| 252 return false; |
| 253 } |
| 254 if (socket_errno != 0) { |
| 255 LOG(ERROR) << "Could not connect to host: " << safe_strerror(socket_errno); |
| 256 SetSocketError(); |
| 257 PRESERVE_ERRNO_HANDLE_EINTR(fcntl(socket_, F_SETFL, kFlags)); |
| 258 return false; |
| 259 } |
246 fcntl(socket_, F_SETFL, kFlags); | 260 fcntl(socket_, F_SETFL, kFlags); |
247 return true; | 261 return true; |
248 } | 262 } |
249 | 263 |
250 bool Socket::Resolve(const std::string& host) { | 264 bool Socket::Resolve(const std::string& host) { |
251 struct addrinfo hints; | 265 struct addrinfo hints; |
252 struct addrinfo* res; | 266 struct addrinfo* res; |
253 memset(&hints, 0, sizeof(hints)); | 267 memset(&hints, 0, sizeof(hints)); |
254 hints.ai_family = AF_UNSPEC; | 268 hints.ai_family = AF_UNSPEC; |
255 hints.ai_socktype = SOCK_STREAM; | 269 hints.ai_socktype = SOCK_STREAM; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return FD_ISSET(socket_, &fds); | 304 return FD_ISSET(socket_, &fds); |
291 } | 305 } |
292 | 306 |
293 bool Socket::AddFdToSet(fd_set* fds) const { | 307 bool Socket::AddFdToSet(fd_set* fds) const { |
294 if (IsClosed()) | 308 if (IsClosed()) |
295 return false; | 309 return false; |
296 FD_SET(socket_, fds); | 310 FD_SET(socket_, fds); |
297 return true; | 311 return true; |
298 } | 312 } |
299 | 313 |
300 int Socket::ReadNumBytes(char* buffer, size_t num_bytes) { | 314 int Socket::ReadNumBytes(void* buffer, size_t num_bytes) { |
301 int bytes_read = 0; | 315 int bytes_read = 0; |
302 int ret = 1; | 316 int ret = 1; |
303 while (bytes_read < num_bytes && ret > 0) { | 317 while (bytes_read < num_bytes && ret > 0) { |
304 ret = Read(buffer + bytes_read, num_bytes - bytes_read); | 318 ret = Read(static_cast<char*>(buffer) + bytes_read, num_bytes - bytes_read); |
305 if (ret >= 0) | 319 if (ret >= 0) |
306 bytes_read += ret; | 320 bytes_read += ret; |
307 } | 321 } |
308 return bytes_read; | 322 return bytes_read; |
309 } | 323 } |
310 | 324 |
311 void Socket::SetSocketError() { | 325 void Socket::SetSocketError() { |
312 socket_error_ = true; | 326 socket_error_ = true; |
313 // We never use non-blocking socket. | 327 // We never use non-blocking socket. |
314 DCHECK(errno != EAGAIN && errno != EWOULDBLOCK); | 328 DCHECK(errno != EAGAIN && errno != EWOULDBLOCK); |
315 Close(); | 329 Close(); |
316 } | 330 } |
317 | 331 |
318 int Socket::Read(char* buffer, size_t buffer_size) { | 332 int Socket::Read(void* buffer, size_t buffer_size) { |
319 if (!WaitForEvent(READ, kNoTimeout)) { | 333 if (!WaitForEvent(READ, kNoTimeout)) { |
320 SetSocketError(); | 334 SetSocketError(); |
321 return 0; | 335 return 0; |
322 } | 336 } |
323 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size)); | 337 int ret = HANDLE_EINTR(read(socket_, buffer, buffer_size)); |
324 if (ret < 0) | 338 if (ret < 0) |
325 SetSocketError(); | 339 SetSocketError(); |
326 return ret; | 340 return ret; |
327 } | 341 } |
328 | 342 |
329 int Socket::Write(const char* buffer, size_t count) { | 343 int Socket::Write(const void* buffer, size_t count) { |
330 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); | 344 int ret = HANDLE_EINTR(send(socket_, buffer, count, MSG_NOSIGNAL)); |
331 if (ret < 0) | 345 if (ret < 0) |
332 SetSocketError(); | 346 SetSocketError(); |
333 return ret; | 347 return ret; |
334 } | 348 } |
335 | 349 |
336 int Socket::WriteString(const std::string& buffer) { | 350 int Socket::WriteString(const std::string& buffer) { |
337 return WriteNumBytes(buffer.c_str(), buffer.size()); | 351 return WriteNumBytes(buffer.c_str(), buffer.size()); |
338 } | 352 } |
339 | 353 |
340 int Socket::WriteNumBytes(const char* buffer, size_t num_bytes) { | 354 int Socket::WriteNumBytes(const void* buffer, size_t num_bytes) { |
341 int bytes_written = 0; | 355 int bytes_written = 0; |
342 int ret = 1; | 356 int ret = 1; |
343 while (bytes_written < num_bytes && ret > 0) { | 357 while (bytes_written < num_bytes && ret > 0) { |
344 ret = Write(buffer + bytes_written, num_bytes - bytes_written); | 358 ret = Write(static_cast<const char*>(buffer) + bytes_written, |
| 359 num_bytes - bytes_written); |
345 if (ret >= 0) | 360 if (ret >= 0) |
346 bytes_written += ret; | 361 bytes_written += ret; |
347 } | 362 } |
348 return bytes_written; | 363 return bytes_written; |
349 } | 364 } |
350 | 365 |
351 bool Socket::WaitForEvent(EventType type, int timeout_secs) const { | 366 bool Socket::WaitForEvent(EventType type, int timeout_secs) { |
352 if (exit_notifier_fd_ == -1 || socket_ == -1) | 367 if (exit_notifier_fd_ == -1 || socket_ == -1) |
353 return true; | 368 return true; |
354 const int nfds = std::max(socket_, exit_notifier_fd_) + 1; | 369 const int nfds = std::max(socket_, exit_notifier_fd_) + 1; |
355 fd_set read_fds; | 370 fd_set read_fds; |
356 fd_set write_fds; | 371 fd_set write_fds; |
357 FD_ZERO(&read_fds); | 372 FD_ZERO(&read_fds); |
358 FD_ZERO(&write_fds); | 373 FD_ZERO(&write_fds); |
359 if (type == READ) | 374 if (type == READ) |
360 FD_SET(socket_, &read_fds); | 375 FD_SET(socket_, &read_fds); |
361 else | 376 else |
362 FD_SET(socket_, &write_fds); | 377 FD_SET(socket_, &write_fds); |
363 FD_SET(exit_notifier_fd_, &read_fds); | 378 FD_SET(exit_notifier_fd_, &read_fds); |
364 | 379 |
365 timeval tv = {}; | 380 timeval tv = {}; |
366 timeval* tv_ptr = NULL; | 381 timeval* tv_ptr = NULL; |
367 if (timeout_secs > 0) { | 382 if (timeout_secs > 0) { |
368 tv.tv_sec = timeout_secs; | 383 tv.tv_sec = timeout_secs; |
369 tv.tv_usec = 0; | 384 tv.tv_usec = 0; |
370 tv_ptr = &tv; | 385 tv_ptr = &tv; |
371 } | 386 } |
372 if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) | 387 if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, tv_ptr)) <= 0) |
373 return false; | 388 return false; |
374 return !FD_ISSET(exit_notifier_fd_, &read_fds); | 389 if (FD_ISSET(exit_notifier_fd_, &read_fds)) { |
| 390 exited_ = true; |
| 391 return false; |
| 392 } |
| 393 return true; |
375 } | 394 } |
376 | 395 |
377 // static | 396 // static |
378 int Socket::GetHighestFileDescriptor( | 397 int Socket::GetHighestFileDescriptor( |
379 const Socket& s1, const Socket& s2) { | 398 const Socket& s1, const Socket& s2) { |
380 return std::max(s1.socket_, s2.socket_); | 399 return std::max(s1.socket_, s2.socket_); |
381 } | 400 } |
382 | 401 |
383 } // namespace forwarder | 402 } // namespace forwarder |
OLD | NEW |