/* 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.
*/
#ifndef _PROXY_INT_H
#define _PROXY_INT_H
#include "proxy_common.h"
#include "android/sockets.h"
#include "android/utils/stralloc.h"
extern int proxy_log;
extern void
proxy_LOG(const char* fmt, ...);
#define PROXY_LOG(...) \
do { if (proxy_log) proxy_LOG(__VA_ARGS__); } while (0)
/* ProxySelect is used to handle events */
enum {
PROXY_SELECT_READ = (1 << 0),
PROXY_SELECT_WRITE = (1 << 1),
PROXY_SELECT_ERROR = (1 << 2)
};
typedef struct {
int* pcount;
fd_set* reads;
fd_set* writes;
fd_set* errors;
} ProxySelect;
extern void proxy_select_set( ProxySelect* sel,
int fd,
unsigned flags );
extern unsigned proxy_select_poll( ProxySelect* sel, int fd );
/* sockets proxy manager internals */
typedef struct ProxyConnection ProxyConnection;
typedef struct ProxyService ProxyService;
/* free a given proxified connection */
typedef void (*ProxyConnectionFreeFunc) ( ProxyConnection* conn );
/* modify the ProxySelect to tell which events to listen to */
typedef void (*ProxyConnectionSelectFunc) ( ProxyConnection* conn,
ProxySelect* sel );
/* action a proxy connection when select() returns certain events for its socket */
typedef void (*ProxyConnectionPollFunc) ( ProxyConnection* conn,
ProxySelect* sel );
/* root ProxyConnection object */
struct ProxyConnection {
int socket;
SockAddress address; /* for debugging */
ProxyConnection* next;
ProxyConnection* prev;
ProxyEventFunc ev_func;
void* ev_opaque;
ProxyService* service;
/* the following is useful for all types of services */
char name[64]; /* for debugging purposes */
stralloc_t str[1]; /* network buffer (dynamic) */
int str_pos; /* see proxy_connection_send() */
int str_sent; /* see proxy_connection_send() */
int str_recv; /* see proxy_connection_receive() */
/* connection methods */
ProxyConnectionFreeFunc conn_free;
ProxyConnectionSelectFunc conn_select;
ProxyConnectionPollFunc conn_poll;
/* rest of data depend on exact implementation */
};
extern void
proxy_connection_init( ProxyConnection* conn,
int socket,
SockAddress* address,
ProxyService* service,
ProxyConnectionFreeFunc conn_free,
ProxyConnectionSelectFunc conn_select,
ProxyConnectionPollFunc conn_poll );
extern void
proxy_connection_done( ProxyConnection* conn );
/* free the proxy connection object. this will also
* close the corresponding socket unless the
* 'keep_alive' flag is set to TRUE.
*/
extern void
proxy_connection_free( ProxyConnection* conn,
int keep_alive,
ProxyEvent event );
/* status of data transfer operations */
typedef enum {
DATA_ERROR = -1,
DATA_NEED_MORE = 0,
DATA_COMPLETED = 1
} DataStatus;
/* try to send data from the connection's buffer to a socket.
* starting from offset conn->str_pos in the buffer
*
* returns DATA_COMPLETED if everything could be written
* returns DATA_ERROR for a socket disconnection or error
* returns DATA_NEED_MORE if all data could not be sent.
*
* on exit, conn->str_sent contains the number of bytes
* that were really sent. conn->str_pos will be incremented
* by conn->str_sent as well.
*
* note that in case of success (DATA_COMPLETED), this also
* performs a proxy_connection_rewind which sets conn->str_pos
* to 0.
*/
extern DataStatus
proxy_connection_send( ProxyConnection* conn, int fd );
/* try to read 'wanted' bytes into conn->str from a socket
*
* returns DATA_COMPLETED if all bytes could be read
* returns DATA_NEED_MORE if not all bytes could be read
* returns DATA_ERROR in case of socket disconnection or error
*
* on exit, the amount of data received is in conn->str_recv
*/
extern DataStatus
proxy_connection_receive( ProxyConnection* conn, int fd, int wanted );
/* tries to receive a line of text from the proxy.
* when an entire line is read, the trailing \r\n is stripped
* and replaced by a terminating zero. str->n will be the
* lenght of the line, exclusing the terminating zero.
* returns 1 when a line has been received
* returns 0 if there is still some data to receive
* returns -1 in case of error
*/
extern DataStatus
proxy_connection_receive_line( ProxyConnection* conn, int fd );
/* rewind the string buffer for a new operation */
extern void
proxy_connection_rewind( ProxyConnection* conn );
/* base64 encode a source string, returns size of encoded result,
* or -1 if there was not enough room in the destination buffer
*/
extern int
proxy_base64_encode( const char* src, int srclen,
char* dst, int dstlen );
extern int
proxy_resolve_server( SockAddress* addr,
const char* servername,
int servernamelen,
int serverport );
/* a ProxyService is really a proxy server and associated options */
/* destroy a given proxy service */
typedef void (*ProxyServiceFreeFunc) ( void* opaque );
/* tries to create a new proxified connection, returns NULL if the service can't
* handle this address */
typedef ProxyConnection* (*ProxyServiceConnectFunc)( void* opaque,
SocketType socket_type,
const SockAddress* address );
struct ProxyService {
void* opaque;
ProxyServiceFreeFunc serv_free;
ProxyServiceConnectFunc serv_connect;
};
extern int
proxy_manager_add_service( ProxyService* service );
#endif /* _PROXY_INT_H */