1/* Copyright (C) 2007-2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12#ifndef _PROXY_INT_H
13#define _PROXY_INT_H
14
15#include "proxy_common.h"
16#include "android/sockets.h"
17#include "android/utils/stralloc.h"
18
19extern int  proxy_log;
20
21extern void
22proxy_LOG(const char*  fmt, ...);
23
24#define  PROXY_LOG(...)   \
25    do { if (proxy_log) proxy_LOG(__VA_ARGS__); } while (0)
26
27
28/* ProxySelect is used to handle events */
29
30enum {
31    PROXY_SELECT_READ  = (1 << 0),
32    PROXY_SELECT_WRITE = (1 << 1),
33    PROXY_SELECT_ERROR = (1 << 2)
34};
35
36typedef struct {
37    int*     pcount;
38    fd_set*  reads;
39    fd_set*  writes;
40    fd_set*  errors;
41} ProxySelect;
42
43extern void     proxy_select_set( ProxySelect*  sel,
44                                  int           fd,
45                                  unsigned      flags );
46
47extern unsigned  proxy_select_poll( ProxySelect*  sel, int  fd );
48
49
50/* sockets proxy manager internals */
51
52typedef struct ProxyConnection   ProxyConnection;
53typedef struct ProxyService      ProxyService;
54
55/* free a given proxified connection */
56typedef void              (*ProxyConnectionFreeFunc)   ( ProxyConnection*  conn );
57
58/* modify the ProxySelect to tell which events to listen to */
59typedef void              (*ProxyConnectionSelectFunc) ( ProxyConnection*  conn,
60                                                         ProxySelect*      sel );
61
62/* action a proxy connection when select() returns certain events for its socket */
63typedef void              (*ProxyConnectionPollFunc)   ( ProxyConnection*  conn,
64                                                         ProxySelect*      sel );
65
66
67/* root ProxyConnection object */
68struct ProxyConnection {
69    int                 socket;
70    SockAddress         address;  /* for debugging */
71    ProxyConnection*    next;
72    ProxyConnection*    prev;
73    ProxyEventFunc      ev_func;
74    void*               ev_opaque;
75    ProxyService*       service;
76
77    /* the following is useful for all types of services */
78    char                name[64];    /* for debugging purposes */
79
80    stralloc_t          str[1];      /* network buffer (dynamic) */
81    int                 str_pos;     /* see proxy_connection_send() */
82    int                 str_sent;    /* see proxy_connection_send() */
83    int                 str_recv;    /* see proxy_connection_receive() */
84
85    /* connection methods */
86    ProxyConnectionFreeFunc    conn_free;
87    ProxyConnectionSelectFunc  conn_select;
88    ProxyConnectionPollFunc    conn_poll;
89
90    /* rest of data depend on exact implementation */
91};
92
93
94
95extern void
96proxy_connection_init( ProxyConnection*           conn,
97                       int                        socket,
98                       SockAddress*               address,
99                       ProxyService*              service,
100                       ProxyConnectionFreeFunc    conn_free,
101                       ProxyConnectionSelectFunc  conn_select,
102                       ProxyConnectionPollFunc    conn_poll );
103
104extern void
105proxy_connection_done( ProxyConnection*  conn );
106
107/* free the proxy connection object. this will also
108 * close the corresponding socket unless the
109 * 'keep_alive' flag is set to TRUE.
110 */
111extern void
112proxy_connection_free( ProxyConnection*  conn,
113                       int               keep_alive,
114                       ProxyEvent        event );
115
116/* status of data transfer operations */
117typedef enum {
118    DATA_ERROR     = -1,
119    DATA_NEED_MORE =  0,
120    DATA_COMPLETED =  1
121} DataStatus;
122
123/* try to send data from the connection's buffer to a socket.
124 * starting from offset conn->str_pos in the buffer
125 *
126 * returns DATA_COMPLETED if everything could be written
127 * returns DATA_ERROR for a socket disconnection or error
128 * returns DATA_NEED_MORE if all data could not be sent.
129 *
130 * on exit, conn->str_sent contains the number of bytes
131 * that were really sent. conn->str_pos will be incremented
132 * by conn->str_sent as well.
133 *
134 * note that in case of success (DATA_COMPLETED), this also
135 * performs a proxy_connection_rewind which sets conn->str_pos
136 * to 0.
137 */
138extern DataStatus
139proxy_connection_send( ProxyConnection*  conn, int  fd );
140
141/* try to read 'wanted' bytes into conn->str from a socket
142 *
143 * returns DATA_COMPLETED if all bytes could be read
144 * returns DATA_NEED_MORE if not all bytes could be read
145 * returns DATA_ERROR in case of socket disconnection or error
146 *
147 * on exit, the amount of data received is in conn->str_recv
148 */
149extern DataStatus
150proxy_connection_receive( ProxyConnection*  conn, int  fd, int  wanted );
151
152/* tries to receive a line of text from the proxy.
153 * when an entire line is read, the trailing \r\n is stripped
154 * and replaced by a terminating zero. str->n will be the
155 * lenght of the line, exclusing the terminating zero.
156 * returns 1 when a line has been received
157 * returns 0 if there is still some data to receive
158 * returns -1 in case of error
159 */
160extern DataStatus
161proxy_connection_receive_line( ProxyConnection*  conn, int  fd );
162
163/* rewind the string buffer for a new operation */
164extern void
165proxy_connection_rewind( ProxyConnection*  conn );
166
167/* base64 encode a source string, returns size of encoded result,
168 * or -1 if there was not enough room in the destination buffer
169 */
170extern int
171proxy_base64_encode( const char*  src, int  srclen,
172                     char*        dst, int  dstlen );
173
174extern int
175proxy_resolve_server( SockAddress*   addr,
176                      const char*    servername,
177                      int            servernamelen,
178                      int            serverport );
179
180/* a ProxyService is really a proxy server and associated options */
181
182/* destroy a given proxy service */
183typedef void              (*ProxyServiceFreeFunc)      ( void*  opaque );
184
185/* tries to create a new proxified connection, returns NULL if the service can't
186 * handle this address */
187typedef ProxyConnection*  (*ProxyServiceConnectFunc)( void*               opaque,
188                                                      SocketType          socket_type,
189                                                      const SockAddress*  address );
190
191struct ProxyService {
192    void*                      opaque;
193    ProxyServiceFreeFunc       serv_free;
194    ProxyServiceConnectFunc    serv_connect;
195};
196
197extern int
198proxy_manager_add_service( ProxyService*  service );
199
200
201#endif /* _PROXY_INT_H */
202