15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/in.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <netinet/tcp.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/select.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/wait.h> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/common/adb_connection.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/common/daemon.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/common/net.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const pthread_t kInvalidThread = static_cast<pthread_t>(-1); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)volatile bool g_killed = false; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloseSocket(int fd) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd >= 0) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_errno = errno; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void) HANDLE_EINTR(close(fd)); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = old_errno; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Buffer { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Buffer() 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bytes_read_(0), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_(0) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanRead() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_read_ == 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanWrite() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return write_offset_ < bytes_read_; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Read(int fd) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = -1; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanRead()) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = HANDLE_EINTR(read(fd, buffer_, kBufferSize)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret > 0) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read_ = ret; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Write(int fd) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = -1; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CanWrite()) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = HANDLE_EINTR(write(fd, buffer_ + write_offset_, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read_ - write_offset_)); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret > 0) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_ += ret; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_offset_ == bytes_read_) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_ = 0; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read_ = 0; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A big buffer to let our file-over-http bridge work more like real file. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBufferSize = 1024 * 128; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read_; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_offset_; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer_[kBufferSize]; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Buffer); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Server; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ForwarderThreadInfo { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderThreadInfo(Server* a_server, int a_forwarder_index) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : server(a_server), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_index(a_forwarder_index) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Server* server; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int forwarder_index; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ForwarderInfo { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t start_time; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket1; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t socket1_last_byte_time; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t socket1_bytes; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket2; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t socket2_last_byte_time; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t socket2_bytes; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Server { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Server() 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : thread_(kInvalidThread), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_(-1) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(forward_to_, 0, sizeof(forward_to_)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&forwarders_, 0, sizeof(forwarders_)); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetFreeForwarderIndex() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxForwarders; i++) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forwarders_[i].start_time == 0) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DisposeForwarderInfo(int index) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarders_[index].start_time = 0; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderInfo* GetForwarderInfo(int index) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &forwarders_[index]; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DumpInformation() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "Server information: " << forward_to_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << "No.: age up(bytes,idle) down(bytes,idle)"; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t now = time(NULL); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxForwarders; i++) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ForwarderInfo& info = forwarders_[i]; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info.start_time) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count++; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(INFO) << count << ": " << now - info.start_time << " up(" 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << info.socket1_bytes << "," 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << now - info.socket1_last_byte_time << " down(" 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << info.socket2_bytes << "," 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << now - info.socket2_last_byte_time << ")"; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Shutdown() { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_ >= 0) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown(socket_, SHUT_RDWR); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitSocket(const char* arg); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartThread() { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_create(&thread_, NULL, ServerThread, this); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void JoinThread() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (thread_ != kInvalidThread) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_join(thread_, NULL); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void* ServerThread(void* arg); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There are 3 kinds of threads that will access the array: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1. Server thread will get a free ForwarderInfo and initialize it; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2. Forwarder threads will dispose the ForwarderInfo when it finishes; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3. Main thread will iterate and print the forwarders. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Using an array is not optimal, but can avoid locks or other complex 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inter-thread communication. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kMaxForwarders = 512; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderInfo forwarders_[kMaxForwarders]; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t thread_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char forward_to_[40]; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Server); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forwards all outputs from one socket to another socket. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ForwarderThread(void* arg) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderThreadInfo* thread_info = 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<ForwarderThreadInfo*>(arg); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Server* server = thread_info->server; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = thread_info->forwarder_index; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete thread_info; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderInfo* info = server->GetForwarderInfo(index); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket1 = info->socket1; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket2 = info->socket2; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nfds = socket1 > socket2 ? socket1 + 1 : socket2 + 1; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set read_fds; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd_set write_fds; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Buffer buffer1; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Buffer buffer2; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!g_killed) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&read_fds); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer1.CanRead()) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(socket1, &read_fds); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer2.CanRead()) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(socket2, &read_fds); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_ZERO(&write_fds); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer1.CanWrite()) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(socket2, &write_fds); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer2.CanWrite()) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FD_SET(socket1, &write_fds); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(select(nfds, &read_fds, &write_fds, NULL, NULL)) <= 0) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Select error: " << strerror(errno); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int now = time(NULL); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FD_ISSET(socket1, &read_fds)) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->socket1_last_byte_time = now; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes = buffer1.Read(socket1); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes <= 0) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->socket1_bytes += bytes; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FD_ISSET(socket2, &read_fds)) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->socket2_last_byte_time = now; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes = buffer2.Read(socket2); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes <= 0) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->socket2_bytes += bytes; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FD_ISSET(socket1, &write_fds)) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer2.Write(socket1) <= 0) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FD_ISSET(socket2, &write_fds)) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer1.Write(socket2) <= 0) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(socket1); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(socket2); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server->DisposeForwarderInfo(index); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Listens to a server socket. On incoming request, forward it to the host. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* Server::ServerThread(void* arg) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Server* server = reinterpret_cast<Server*>(arg); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!g_killed) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int forwarder_index = server->GetFreeForwarderIndex(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (forwarder_index < 0) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Too many forwarders"; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_in addr; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t addr_len = sizeof(addr); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int socket = HANDLE_EINTR(accept(server->socket_, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<sockaddr*>(&addr), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &addr_len)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket < 0) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to accept: " << strerror(errno); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools::DisableNagle(socket); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int host_socket = tools::ConnectAdbHostSocket(server->forward_to_); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_socket >= 0) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set NONBLOCK flag because we use select(). 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fcntl(host_socket, F_SETFL, fcntl(host_socket, F_GETFL) | O_NONBLOCK); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwarderInfo* forwarder_info = server->GetForwarderInfo(forwarder_index); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_t now = time(NULL); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->start_time = now; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket1 = socket; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket1_last_byte_time = now; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket1_bytes = 0; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket2 = host_socket; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket2_last_byte_time = now; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forwarder_info->socket2_bytes = 0; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_t thread; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_create(&thread, NULL, ForwarderThread, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ForwarderThreadInfo(server, forwarder_index)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the unused client socket which is failed to connect to host. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(socket); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(server->socket_); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server->socket_ = -1; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Format of arg: <Device port>[:<Forward to port>:<Forward to address>] 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Server::InitSocket(const char* arg) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* endptr; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int local_port = static_cast<int>(strtol(arg, &endptr, 10)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (local_port < 0) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*endptr != ':') { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(forward_to_, sizeof(forward_to_), "%d:127.0.0.1", local_port); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(forward_to_, endptr + 1, sizeof(forward_to_) - 1); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = socket(AF_INET, SOCK_STREAM, 0); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_ < 0) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("server socket"); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools::DisableNagle(socket_); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockaddr_in addr; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&addr, 0, sizeof(addr)); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_family = AF_INET; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_port = htons(local_port); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int reuse_addr = 1; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &reuse_addr, sizeof(reuse_addr)); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools::DeferAccept(socket_); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(bind(socket_, reinterpret_cast<sockaddr*>(&addr), 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(addr))) < 0 || 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE_EINTR(listen(socket_, 5)) < 0) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("server bind"); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(socket_); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = -1; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (local_port == 0) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socklen_t addrlen = sizeof(addr); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), &addrlen) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) != 0) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("get listen address"); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(socket_); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = -1; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_port = ntohs(addr.sin_port); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Forwarding device port %d to host %s\n", local_port, forward_to_); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int g_server_count = 0; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Server* g_servers = NULL; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KillHandler(int unused) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_killed = true; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_server_count; i++) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_servers[i].Shutdown(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DumpInformation(int unused) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_server_count; i++) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_servers[i].DumpInformation(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, char** argv) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Android device to host TCP forwarder\n"); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Like 'adb forward' but in the reverse direction\n"); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine command_line(argc, argv); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringVector server_args = command_line.GetArgs(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tools::HasHelpSwitch(command_line) || server_args.empty()) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools::ShowHelp( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv[0], 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<Device port>[:<Forward to port>:<Forward to address>] ...", 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <Forward to port> default is <Device port>\n" 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <Forward to address> default is 127.0.0.1\n" 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "If <Device port> is 0, a port will by dynamically allocated.\n"); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_servers = new Server[server_args.size()]; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_server_count = 0; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int failed_count = 0; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < server_args.size(); i++) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_servers[g_server_count].InitSocket(server_args[i].c_str())) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Couldn't start forwarder server for port spec: %s\n", 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_args[i].c_str()); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++failed_count; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++g_server_count; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_server_count == 0) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("No forwarder servers could be started. Exiting.\n"); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] g_servers; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return failed_count; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tools::HasNoSpawnDaemonSwitch(command_line)) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tools::SpawnDaemon(failed_count); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGTERM, KillHandler); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal(SIGUSR2, DumpInformation); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_server_count; i++) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_servers[i].StartThread(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < g_server_count; i++) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_servers[i].JoinThread(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_server_count = 0; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] g_servers; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 427