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 "tools/android/common/adb_connection.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/inet.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/common/net.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tools { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloseSocket(int fd) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fd >= 0) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_errno = errno; 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) close(fd); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = old_errno; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ConnectAdbHostSocket(const char* forward_to) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ADB port forward request format: HHHHtcp:port:address. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HHHH is the hexidecimal length of the "tcp:port:address" part. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kBufferMaxLength = 30; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kLengthOfLength = 4; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kAddressMaxLength = kBufferMaxLength - kLengthOfLength; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char kAddressPrefix[] = { 't', 'c', 'p', ':' }; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_length = arraysize(kAddressPrefix) + strlen(forward_to); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address_length > kBufferMaxLength - kLengthOfLength) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Forward to address is too long: " << forward_to; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char request[kBufferMaxLength]; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(request + kLengthOfLength, kAddressPrefix, arraysize(kAddressPrefix)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(request + kLengthOfLength + arraysize(kAddressPrefix), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forward_to, strlen(forward_to)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char length_buffer[kLengthOfLength + 1]; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(length_buffer, arraysize(length_buffer), "%04X", 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(address_length)); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(request, length_buffer, kLengthOfLength); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int host_socket = socket(AF_INET, SOCK_STREAM, 0); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_socket < 0) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to create adb socket: " << strerror(errno); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisableNagle(host_socket); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kAdbPort = 5037; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sockaddr_in addr; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&addr, 0, sizeof(addr)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_family = AF_INET; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr.sin_port = htons(kAdbPort); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HANDLE_EINTR(connect(host_socket, reinterpret_cast<sockaddr*>(&addr), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(addr))) < 0) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to connect adb socket: " << strerror(errno); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(host_socket); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_remaining = address_length + kLengthOfLength; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_sent = 0; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (bytes_remaining > 0) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = HANDLE_EINTR(send(host_socket, request + bytes_sent, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_remaining, 0)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret < 0) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to send request: " << strerror(errno); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(host_socket); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_sent += ret; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_remaining -= ret; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kAdbStatusLength = 4; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char response[kBufferMaxLength]; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int response_length = HANDLE_EINTR(recv(host_socket, response, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBufferMaxLength, 0)); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (response_length < kAdbStatusLength || 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncmp("OKAY", response, kAdbStatusLength) != 0) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Bad response from ADB: length: " << response_length 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " data: " << DumpBinary(response, response_length); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseSocket(host_socket); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host_socket; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace tools 108