18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "proxy_int.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sockets.h" 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h> 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h> 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/misc.h" 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h" 209b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner#include "iolooper.h" 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint proxy_log = 0; 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_LOG(const char* fmt, ...) 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_list args; 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_start(args, fmt); 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vfprintf(stderr, fmt, args); 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end(args); 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "\n"); 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_set_verbose(int mode) 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_log = mode; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** Global connection list 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic ProxyConnection s_connections[1]; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_HEX_DUMP 512 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthex_dump( void* base, int size, const char* prefix ) 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project STRALLOC_DEFINE(s); 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (size > MAX_HEX_DUMP) 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size = MAX_HEX_DUMP; 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_add_hexdump(s, base, size, prefix); 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_LOG( "%s", stralloc_cstr(s) ); 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_reset(s); 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_init( ProxyConnection* conn, 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int socket, 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress* address, 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyService* service, 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnectionFreeFunc conn_free, 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnectionSelectFunc conn_select, 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnectionPollFunc conn_poll ) 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->socket = socket; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->address = address[0]; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->service = service; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->next = NULL; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_free = conn_free; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_select = conn_select; 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_poll = conn_poll; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(socket); 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SocketType type = socket_get_type(socket); 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project snprintf( conn->name, sizeof(conn->name), 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "%s:%s(%d)", 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (type == SOCKET_STREAM) ? "tcp" : "udp", 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_to_string(address), socket ); 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* just in case */ 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->name[sizeof(conn->name)-1] = 0; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_reset(conn->str); 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_pos = 0; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_done( ProxyConnection* conn ) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_reset( conn->str ); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conn->socket >= 0) { 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(conn->socket); 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->socket = -1; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_rewind( ProxyConnection* conn ) 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_t* str = conn->str; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* only keep a small buffer in the heap */ 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_pos = 0; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str->n = 0; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (str->a > 1024) 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_reset(str); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDataStatus 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_send( ProxyConnection* conn, int fd ) 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_t* str = conn->str; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int avail = str->n - conn->str_pos; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_sent = 0; 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (avail <= 0) 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 1; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (proxy_log) { 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: sending %d bytes:", conn->name, avail ); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hex_dump( str->s + conn->str_pos, avail, ">> " ); 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (avail > 0) { 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n = socket_send(fd, str->s + conn->str_pos, avail); 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n == 0) { 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: connection reset by peer (send)", 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->name); 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n < 0) { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno == EWOULDBLOCK || errno == EAGAIN) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_NEED_MORE; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: error: %s", conn->name, errno_str); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_pos += n; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_sent += n; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project avail -= n; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_connection_rewind(conn); 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_COMPLETED; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDataStatus 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_receive( ProxyConnection* conn, int fd, int wanted ) 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_t* str = conn->str; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_recv = 0; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (wanted > 0) { 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_readyplus( str, wanted ); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = socket_recv(fd, str->s + str->n, wanted); 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n == 0) { 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: connection reset by peer (receive)", 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->name); 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n < 0) { 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno == EWOULDBLOCK || errno == EAGAIN) 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_NEED_MORE; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: error: %s", conn->name, errno_str); 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (proxy_log) { 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: received %d bytes:", conn->name, n ); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hex_dump( str->s + str->n, n, "<< " ); 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str->n += n; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wanted -= n; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->str_recv += n; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_COMPLETED; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDataStatus 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_receive_line( ProxyConnection* conn, int fd ) 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_t* str = conn->str; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char c; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n = socket_recv(fd, &c, 1); 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n == 0) { 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: disconnected from server", conn->name ); 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (n < 0) { 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (errno == EWOULDBLOCK || errno == EAGAIN) { 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: blocked", conn->name); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_NEED_MORE; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: error: %s", conn->name, errno_str); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_ERROR; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stralloc_add_c(str, c); 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (c == '\n') { 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str->s[--str->n] = 0; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (str->n > 0 && str->s[str->n-1] == '\r') 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project str->s[--str->n] = 0; 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: received '%s'", conn->name, 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project quote_bytes(str->s, str->n)); 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return DATA_COMPLETED; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_insert( ProxyConnection* conn, ProxyConnection* after ) 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->next = after->next; 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project after->next->prev = conn; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project after->next = conn; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->prev = after; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_remove( ProxyConnection* conn ) 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->prev->next = conn->next; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->next->prev = conn->prev; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->next = conn->prev = conn; 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** Global service list 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_SERVICES 4 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic ProxyService* s_services[ MAX_SERVICES ]; 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int s_num_services; 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int s_init; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void proxy_manager_atexit( void ); 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_init(void) 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s_init = 1; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s_connections->next = s_connections; 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s_connections->prev = s_connections; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project atexit( proxy_manager_atexit ); 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_add_service( ProxyService* service ) 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!service || s_num_services >= MAX_SERVICES) 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s_init) 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_manager_init(); 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s_services[s_num_services++] = service; 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern void 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_atexit( void ) 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* conn = s_connections->next; 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* free all proxy connections */ 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (conn != s_connections) { 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* next = conn->next; 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_free( conn ); 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn = next; 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->next = conn; 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->prev = conn; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* free all proxy services */ 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = s_num_services; n-- > 0;) { 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyService* service = s_services[n]; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project service->serv_free( service->opaque ); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s_num_services = 0; 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_connection_free( ProxyConnection* conn, 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int keep_alive, 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyEvent event ) 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conn) { 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd = conn->socket; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_connection_remove(conn); 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (event != PROXY_EVENT_NONE) 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->ev_func( conn->ev_opaque, fd, event ); 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keep_alive) 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->socket = -1; 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_free(conn); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_add( SockAddress* address, 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SocketType sock_type, 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyEventFunc ev_func, 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* ev_opaque ) 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s_init) { 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_manager_init(); 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (n = 0; n < s_num_services; n++) { 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyService* service = s_services[n]; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* conn = service->serv_connect( service->opaque, 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_type, 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project address ); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conn != NULL) { 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->ev_func = ev_func; 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->ev_opaque = ev_opaque; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_connection_insert(conn, s_connections->prev); 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* remove an on-going proxified socket connection from the manager's list. 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * this is only necessary when the socket connection must be canceled before 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the connection accept/refusal occured 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_del( void* ev_opaque ) 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* conn = s_connections->next; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( ; conn != s_connections; conn = conn->next ) { 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conn->ev_opaque == ev_opaque) { 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_connection_remove(conn); 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_free(conn); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_select_set( ProxySelect* sel, 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd, 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned flags ) 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fd < 0 || !flags) 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*sel->pcount < fd+1) 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *sel->pcount = fd+1; 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & PROXY_SELECT_READ) { 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_SET( fd, sel->reads ); 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_CLR( fd, sel->reads ); 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & PROXY_SELECT_WRITE) { 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_SET( fd, sel->writes ); 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_CLR( fd, sel->writes ); 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (flags & PROXY_SELECT_ERROR) { 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_SET( fd, sel->errors ); 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project FD_CLR( fd, sel->errors ); 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_select_poll( ProxySelect* sel, int fd ) 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned flags = 0; 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fd >= 0) { 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( FD_ISSET(fd, sel->reads) ) 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= PROXY_SELECT_READ; 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( FD_ISSET(fd, sel->writes) ) 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= PROXY_SELECT_WRITE; 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( FD_ISSET(fd, sel->errors) ) 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flags |= PROXY_SELECT_ERROR; 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return flags; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function is called to update the select file descriptor sets 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * with those of the proxified connection sockets that are currently managed */ 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_select_fill( int *pcount, fd_set* read_fds, fd_set* write_fds, fd_set* err_fds) 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* conn; 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxySelect sel[1]; 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!s_init) 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project proxy_manager_init(); 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->pcount = pcount; 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->reads = read_fds; 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->writes = write_fds; 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->errors = err_fds; 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn = s_connections->next; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (conn != s_connections) { 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* next = conn->next; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_select(conn, sel); 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn = next; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function is called to act on proxified connection sockets when network events arrive */ 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_manager_poll( fd_set* read_fds, fd_set* write_fds, fd_set* err_fds ) 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* conn = s_connections->next; 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxySelect sel[1]; 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->pcount = NULL; 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->reads = read_fds; 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->writes = write_fds; 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sel->errors = err_fds; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (conn != s_connections) { 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ProxyConnection* next = conn->next; 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn->conn_poll( conn, sel ); 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conn = next; 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_base64_encode( const char* src, int srclen, 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* dst, int dstlen ) 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char cb64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* srcend = src + srclen; 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = 0; 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (src+3 <= srcend && result+4 <= dstlen) 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+0] = cb64[ src[0] >> 2 ]; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+1] = cb64[ ((src[0] & 3) << 4) | ((src[1] & 0xf0) >> 4) ]; 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+2] = cb64[ ((src[1] & 0xf) << 2) | ((src[2] & 0xc0) >> 6) ]; 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+3] = cb64[ src[2] & 0x3f ]; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src += 3; 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result += 4; 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (src < srcend) { 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char in[4]; 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (result+4 > dstlen) 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in[0] = src[0]; 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in[1] = src+1 < srcend ? src[1] : 0; 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in[2] = src+2 < srcend ? src[2] : 0; 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+0] = cb64[ in[0] >> 2 ]; 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+1] = cb64[ ((in[0] & 3) << 4) | ((in[1] & 0xf0) >> 4) ]; 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+2] = (unsigned char) (src+1 < srcend ? cb64[ ((in[1] & 0xf) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst[result+3] = (unsigned char) (src+2 < srcend ? cb64[ in[2] & 0x3f ] : '='); 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result += 4; 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectproxy_resolve_server( SockAddress* addr, 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* servername, 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int servernamelen, 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int serverport ) 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char name0[64], *name = name0; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = -1; 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (servernamelen < 0) 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project servernamelen = strlen(servername); 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (servernamelen >= sizeof(name0)) { 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AARRAY_NEW(name, servernamelen+1); 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(name, servername, servernamelen); 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project name[servernamelen] = 0; 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_init_resolve( addr, name, serverport, 0 ) < 0) { 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("%s: can't resolve proxy server name '%s'", 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __FUNCTION__, name); 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Exit; 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROXY_LOG("server name '%s' resolved to %s", name, sock_address_to_string(addr)); 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = 0; 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectExit: 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (name != name0) 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AFREE(name); 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5349b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turnerint 5359b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turnerproxy_check_connection( const char* proxyname, 5369b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner int proxyname_len, 5379b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner int proxyport, 5389b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner int timeout_ms ) 5399b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner{ 5409b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner SockAddress addr; 5419b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner int sock; 5429b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner IoLooper* looper; 5439b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner int ret; 5449b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5459b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner if (proxy_resolve_server(&addr, proxyname, proxyname_len, proxyport) < 0) { 5469b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner return -1; 5479b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner } 5489b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5499b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner sock = socket_create(addr.family, SOCKET_STREAM); 5509b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner if (sock < 0) { 5519b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner PROXY_LOG("%s: Could not create socket !?: %s", __FUNCTION__, errno_str); 5529b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner return -1; 5539b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner } 5549b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5559b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner socket_set_nonblock(sock); 5569b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5579b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner /* An immediate connection is very unlikely, but deal with it, just in case */ 5589b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner if (socket_connect(sock, &addr) == 0) { 5599b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner PROXY_LOG("%s: Immediate connection to %.*s:%d: %s !", 5609b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner __FUNCTION__, proxyname_len, proxyname, proxyport); 5619b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner socket_close(sock); 5629b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner return 0; 5639b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner } 5649b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5659b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner /* Ok, create an IoLooper object to wait for the connection */ 5669b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner looper = iolooper_new(); 5679b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner iolooper_add_write(looper, sock); 5689b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5699b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner ret = iolooper_wait(looper, timeout_ms); 5709b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5719b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner iolooper_free(looper); 5729b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner socket_close(sock); 5739b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner 5749b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner if (ret == 0) { 5759b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner errno = ETIMEDOUT; 5769b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner ret = -1; 5779b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner } 5789b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner return ret; 5799b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner} 580