The Android Open Source Project | 8b23a6c | 2009-03-03 19:30:32 -0800 | [diff] [blame] | 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 "sockets.h" |
| 17 | #include "android/utils/stralloc.h" |
| 18 | |
| 19 | extern int proxy_log; |
| 20 | |
| 21 | extern void |
| 22 | proxy_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 | |
| 30 | enum { |
| 31 | PROXY_SELECT_READ = (1 << 0), |
| 32 | PROXY_SELECT_WRITE = (1 << 1), |
| 33 | PROXY_SELECT_ERROR = (1 << 2) |
| 34 | }; |
| 35 | |
| 36 | typedef struct { |
| 37 | int* pcount; |
| 38 | fd_set* reads; |
| 39 | fd_set* writes; |
| 40 | fd_set* errors; |
| 41 | } ProxySelect; |
| 42 | |
| 43 | extern void proxy_select_set( ProxySelect* sel, |
| 44 | int fd, |
| 45 | unsigned flags ); |
| 46 | |
| 47 | extern unsigned proxy_select_poll( ProxySelect* sel, int fd ); |
| 48 | |
| 49 | |
| 50 | /* sockets proxy manager internals */ |
| 51 | |
| 52 | typedef struct ProxyConnection ProxyConnection; |
| 53 | typedef struct ProxyService ProxyService; |
| 54 | |
| 55 | /* free a given proxified connection */ |
| 56 | typedef void (*ProxyConnectionFreeFunc) ( ProxyConnection* conn ); |
| 57 | |
| 58 | /* modify the ProxySelect to tell which events to listen to */ |
| 59 | typedef void (*ProxyConnectionSelectFunc) ( ProxyConnection* conn, |
| 60 | ProxySelect* sel ); |
| 61 | |
| 62 | /* action a proxy connection when select() returns certain events for its socket */ |
| 63 | typedef void (*ProxyConnectionPollFunc) ( ProxyConnection* conn, |
| 64 | ProxySelect* sel ); |
| 65 | |
| 66 | |
| 67 | /* root ProxyConnection object */ |
| 68 | struct 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 | |
| 95 | extern void |
| 96 | proxy_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 | |
| 104 | extern void |
| 105 | proxy_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 | */ |
| 111 | extern void |
| 112 | proxy_connection_free( ProxyConnection* conn, |
| 113 | int keep_alive, |
| 114 | ProxyEvent event ); |
| 115 | |
| 116 | /* status of data transfer operations */ |
| 117 | typedef 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 | */ |
| 138 | extern DataStatus |
| 139 | proxy_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 | */ |
| 149 | extern DataStatus |
| 150 | proxy_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 | */ |
| 160 | extern DataStatus |
| 161 | proxy_connection_receive_line( ProxyConnection* conn, int fd ); |
| 162 | |
| 163 | /* rewind the string buffer for a new operation */ |
| 164 | extern void |
| 165 | proxy_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 | */ |
| 170 | extern int |
| 171 | proxy_base64_encode( const char* src, int srclen, |
| 172 | char* dst, int dstlen ); |
| 173 | |
| 174 | extern int |
| 175 | proxy_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 */ |
| 183 | typedef void (*ProxyServiceFreeFunc) ( void* opaque ); |
| 184 | |
| 185 | /* tries to create a new proxified connection, returns NULL if the service can't |
| 186 | * handle this address */ |
| 187 | typedef ProxyConnection* (*ProxyServiceConnectFunc)( void* opaque, |
| 188 | SocketType socket_type, |
| 189 | const SockAddress* address ); |
| 190 | |
| 191 | struct ProxyService { |
| 192 | void* opaque; |
| 193 | ProxyServiceFreeFunc serv_free; |
| 194 | ProxyServiceConnectFunc serv_connect; |
| 195 | }; |
| 196 | |
| 197 | extern int |
| 198 | proxy_manager_add_service( ProxyService* service ); |
| 199 | |
| 200 | |
| 201 | #endif /* _PROXY_INT_H */ |