diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | f721e3ac031f892af46f255a47d7f54a91317b30 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /proxy/proxy_common.c | |
parent | bae1bc39312d5019bd9a5b8d840a529213a69a17 (diff) | |
download | external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'proxy/proxy_common.c')
-rw-r--r-- | proxy/proxy_common.c | 532 |
1 files changed, 0 insertions, 532 deletions
diff --git a/proxy/proxy_common.c b/proxy/proxy_common.c deleted file mode 100644 index 7794a62..0000000 --- a/proxy/proxy_common.c +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include "proxy_int.h" -#include "sockets.h" -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include "android/utils/misc.h" -#include "android/utils/system.h" -#include <stdlib.h> - -int proxy_log = 0; - -void -proxy_LOG(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, "\n"); -} - -void -proxy_set_verbose(int mode) -{ - proxy_log = mode; -} - -/** Global connection list - **/ - -static ProxyConnection s_connections[1]; - -#define MAX_HEX_DUMP 512 - -static void -hex_dump( void* base, int size, const char* prefix ) -{ - STRALLOC_DEFINE(s); - if (size > MAX_HEX_DUMP) - size = MAX_HEX_DUMP; - stralloc_add_hexdump(s, base, size, prefix); - proxy_LOG( "%s", stralloc_cstr(s) ); - stralloc_reset(s); -} - -void -proxy_connection_init( ProxyConnection* conn, - int socket, - SockAddress* address, - ProxyService* service, - ProxyConnectionFreeFunc conn_free, - ProxyConnectionSelectFunc conn_select, - ProxyConnectionPollFunc conn_poll ) -{ - conn->socket = socket; - conn->address = address[0]; - conn->service = service; - conn->next = NULL; - - conn->conn_free = conn_free; - conn->conn_select = conn_select; - conn->conn_poll = conn_poll; - - socket_set_nonblock(socket); - - { - SocketType type = socket_get_type(socket); - - snprintf( conn->name, sizeof(conn->name), - "%s:%s(%d)", - (type == SOCKET_STREAM) ? "tcp" : "udp", - sock_address_to_string(address), socket ); - - /* just in case */ - conn->name[sizeof(conn->name)-1] = 0; - } - - stralloc_reset(conn->str); - conn->str_pos = 0; -} - -void -proxy_connection_done( ProxyConnection* conn ) -{ - stralloc_reset( conn->str ); - if (conn->socket >= 0) { - socket_close(conn->socket); - conn->socket = -1; - } -} - - -void -proxy_connection_rewind( ProxyConnection* conn ) -{ - stralloc_t* str = conn->str; - - /* only keep a small buffer in the heap */ - conn->str_pos = 0; - str->n = 0; - if (str->a > 1024) - stralloc_reset(str); -} - -DataStatus -proxy_connection_send( ProxyConnection* conn, int fd ) -{ - stralloc_t* str = conn->str; - int avail = str->n - conn->str_pos; - - conn->str_sent = 0; - - if (avail <= 0) - return 1; - - if (proxy_log) { - PROXY_LOG("%s: sending %d bytes:", conn->name, avail ); - hex_dump( str->s + conn->str_pos, avail, ">> " ); - } - - while (avail > 0) { - int n = socket_send(fd, str->s + conn->str_pos, avail); - if (n == 0) { - PROXY_LOG("%s: connection reset by peer (send)", - conn->name); - return DATA_ERROR; - } - if (n < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) - return DATA_NEED_MORE; - - PROXY_LOG("%s: error: %s", conn->name, errno_str); - return DATA_ERROR; - } - conn->str_pos += n; - conn->str_sent += n; - avail -= n; - } - - proxy_connection_rewind(conn); - return DATA_COMPLETED; -} - - -DataStatus -proxy_connection_receive( ProxyConnection* conn, int fd, int wanted ) -{ - stralloc_t* str = conn->str; - - conn->str_recv = 0; - - while (wanted > 0) { - int n; - - stralloc_readyplus( str, wanted ); - n = socket_recv(fd, str->s + str->n, wanted); - if (n == 0) { - PROXY_LOG("%s: connection reset by peer (receive)", - conn->name); - return DATA_ERROR; - } - if (n < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) - return DATA_NEED_MORE; - - PROXY_LOG("%s: error: %s", conn->name, errno_str); - return DATA_ERROR; - } - - if (proxy_log) { - PROXY_LOG("%s: received %d bytes:", conn->name, n ); - hex_dump( str->s + str->n, n, "<< " ); - } - - str->n += n; - wanted -= n; - conn->str_recv += n; - } - return DATA_COMPLETED; -} - - -DataStatus -proxy_connection_receive_line( ProxyConnection* conn, int fd ) -{ - stralloc_t* str = conn->str; - - for (;;) { - char c; - int n = socket_recv(fd, &c, 1); - if (n == 0) { - PROXY_LOG("%s: disconnected from server", conn->name ); - return DATA_ERROR; - } - if (n < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { - PROXY_LOG("%s: blocked", conn->name); - return DATA_NEED_MORE; - } - PROXY_LOG("%s: error: %s", conn->name, errno_str); - return DATA_ERROR; - } - - stralloc_add_c(str, c); - if (c == '\n') { - str->s[--str->n] = 0; - if (str->n > 0 && str->s[str->n-1] == '\r') - str->s[--str->n] = 0; - - PROXY_LOG("%s: received '%s'", conn->name, - quote_bytes(str->s, str->n)); - return DATA_COMPLETED; - } - } -} - -static void -proxy_connection_insert( ProxyConnection* conn, ProxyConnection* after ) -{ - conn->next = after->next; - after->next->prev = conn; - after->next = conn; - conn->prev = after; -} - -static void -proxy_connection_remove( ProxyConnection* conn ) -{ - conn->prev->next = conn->next; - conn->next->prev = conn->prev; - - conn->next = conn->prev = conn; -} - -/** Global service list - **/ - -#define MAX_SERVICES 4 - -static ProxyService* s_services[ MAX_SERVICES ]; -static int s_num_services; -static int s_init; - -static void proxy_manager_atexit( void ); - -static void -proxy_manager_init(void) -{ - s_init = 1; - s_connections->next = s_connections; - s_connections->prev = s_connections; - atexit( proxy_manager_atexit ); -} - - -extern int -proxy_manager_add_service( ProxyService* service ) -{ - if (!service || s_num_services >= MAX_SERVICES) - return -1; - - if (!s_init) - proxy_manager_init(); - - s_services[s_num_services++] = service; - return 0; -} - - -extern void -proxy_manager_atexit( void ) -{ - ProxyConnection* conn = s_connections->next; - int n; - - /* free all proxy connections */ - while (conn != s_connections) { - ProxyConnection* next = conn->next; - conn->conn_free( conn ); - conn = next; - } - conn->next = conn; - conn->prev = conn; - - /* free all proxy services */ - for (n = s_num_services; n-- > 0;) { - ProxyService* service = s_services[n]; - service->serv_free( service->opaque ); - } - s_num_services = 0; -} - - -void -proxy_connection_free( ProxyConnection* conn, - int keep_alive, - ProxyEvent event ) -{ - if (conn) { - int fd = conn->socket; - - proxy_connection_remove(conn); - - if (event != PROXY_EVENT_NONE) - conn->ev_func( conn->ev_opaque, fd, event ); - - if (keep_alive) - conn->socket = -1; - - conn->conn_free(conn); - } -} - - -int -proxy_manager_add( SockAddress* address, - SocketType sock_type, - ProxyEventFunc ev_func, - void* ev_opaque ) -{ - int n; - - if (!s_init) { - proxy_manager_init(); - } - - for (n = 0; n < s_num_services; n++) { - ProxyService* service = s_services[n]; - ProxyConnection* conn = service->serv_connect( service->opaque, - sock_type, - address ); - if (conn != NULL) { - conn->ev_func = ev_func; - conn->ev_opaque = ev_opaque; - proxy_connection_insert(conn, s_connections->prev); - return 0; - } - } - return -1; -} - - -/* remove an on-going proxified socket connection from the manager's list. - * this is only necessary when the socket connection must be canceled before - * the connection accept/refusal occured - */ -void -proxy_manager_del( void* ev_opaque ) -{ - ProxyConnection* conn = s_connections->next; - for ( ; conn != s_connections; conn = conn->next ) { - if (conn->ev_opaque == ev_opaque) { - proxy_connection_remove(conn); - conn->conn_free(conn); - return; - } - } -} - -void -proxy_select_set( ProxySelect* sel, - int fd, - unsigned flags ) -{ - if (fd < 0 || !flags) - return; - - if (*sel->pcount < fd+1) - *sel->pcount = fd+1; - - if (flags & PROXY_SELECT_READ) { - FD_SET( fd, sel->reads ); - } else { - FD_CLR( fd, sel->reads ); - } - if (flags & PROXY_SELECT_WRITE) { - FD_SET( fd, sel->writes ); - } else { - FD_CLR( fd, sel->writes ); - } - if (flags & PROXY_SELECT_ERROR) { - FD_SET( fd, sel->errors ); - } else { - FD_CLR( fd, sel->errors ); - } -} - -unsigned -proxy_select_poll( ProxySelect* sel, int fd ) -{ - unsigned flags = 0; - - if (fd >= 0) { - if ( FD_ISSET(fd, sel->reads) ) - flags |= PROXY_SELECT_READ; - if ( FD_ISSET(fd, sel->writes) ) - flags |= PROXY_SELECT_WRITE; - if ( FD_ISSET(fd, sel->errors) ) - flags |= PROXY_SELECT_ERROR; - } - return flags; -} - -/* this function is called to update the select file descriptor sets - * with those of the proxified connection sockets that are currently managed */ -void -proxy_manager_select_fill( int *pcount, fd_set* read_fds, fd_set* write_fds, fd_set* err_fds) -{ - ProxyConnection* conn; - ProxySelect sel[1]; - - if (!s_init) - proxy_manager_init(); - - sel->pcount = pcount; - sel->reads = read_fds; - sel->writes = write_fds; - sel->errors = err_fds; - - conn = s_connections->next; - while (conn != s_connections) { - ProxyConnection* next = conn->next; - conn->conn_select(conn, sel); - conn = next; - } -} - -/* this function is called to act on proxified connection sockets when network events arrive */ -void -proxy_manager_poll( fd_set* read_fds, fd_set* write_fds, fd_set* err_fds ) -{ - ProxyConnection* conn = s_connections->next; - ProxySelect sel[1]; - - sel->pcount = NULL; - sel->reads = read_fds; - sel->writes = write_fds; - sel->errors = err_fds; - - while (conn != s_connections) { - ProxyConnection* next = conn->next; - conn->conn_poll( conn, sel ); - conn = next; - } -} - - -int -proxy_base64_encode( const char* src, int srclen, - char* dst, int dstlen ) -{ - static const char cb64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const char* srcend = src + srclen; - int result = 0; - - while (src+3 <= srcend && result+4 <= dstlen) - { - dst[result+0] = cb64[ src[0] >> 2 ]; - dst[result+1] = cb64[ ((src[0] & 3) << 4) | ((src[1] & 0xf0) >> 4) ]; - dst[result+2] = cb64[ ((src[1] & 0xf) << 2) | ((src[2] & 0xc0) >> 6) ]; - dst[result+3] = cb64[ src[2] & 0x3f ]; - src += 3; - result += 4; - } - - if (src < srcend) { - unsigned char in[4]; - - if (result+4 > dstlen) - return -1; - - in[0] = src[0]; - in[1] = src+1 < srcend ? src[1] : 0; - in[2] = src+2 < srcend ? src[2] : 0; - - dst[result+0] = cb64[ in[0] >> 2 ]; - dst[result+1] = cb64[ ((in[0] & 3) << 4) | ((in[1] & 0xf0) >> 4) ]; - dst[result+2] = (unsigned char) (src+1 < srcend ? cb64[ ((in[1] & 0xf) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); - dst[result+3] = (unsigned char) (src+2 < srcend ? cb64[ in[2] & 0x3f ] : '='); - result += 4; - } - return result; -} - -int -proxy_resolve_server( SockAddress* addr, - const char* servername, - int servernamelen, - int serverport ) -{ - char name0[64], *name = name0; - int result = -1; - - if (servernamelen < 0) - servernamelen = strlen(servername); - - if (servernamelen >= sizeof(name0)) { - AARRAY_NEW(name, servernamelen+1); - } - - memcpy(name, servername, servernamelen); - name[servernamelen] = 0; - - if (sock_address_init_resolve( addr, name, serverport, 0 ) < 0) { - PROXY_LOG("%s: can't resolve proxy server name '%s'", - __FUNCTION__, name); - goto Exit; - } - - PROXY_LOG("server name '%s' resolved to %s", name, sock_address_to_string(addr)); - result = 0; - -Exit: - if (name != name0) - AFREE(name); - - return result; -} - - |