aboutsummaryrefslogtreecommitdiffstats
path: root/proxy/proxy_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'proxy/proxy_common.c')
-rw-r--r--proxy/proxy_common.c532
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;
-}
-
-