comparison src/proxy.c @ 14097:7ded3834168f

[gaim-migrate @ 16726] Use the GaimProxyConnectInfo typedef instead of struct _GaimProxyConnectInfo. Sorry, I should have done this in one of my other commits committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 12 Aug 2006 21:07:34 +0000
parents a70c6011dc81
children 7b030f6ed1c3
comparison
equal deleted inserted replaced
14096:a70c6011dc81 14097:7ded3834168f
44 gpointer data; 44 gpointer data;
45 char *host; 45 char *host;
46 int port; 46 int port;
47 guint inpa; 47 guint inpa;
48 GaimProxyInfo *gpi; 48 GaimProxyInfo *gpi;
49
50 /**
51 * This contains alternating length/char* values. The char*
52 * values need to be freed when removed from the linked list.
53 */
49 GSList *hosts; 54 GSList *hosts;
55
50 guchar *write_buffer; 56 guchar *write_buffer;
51 gsize write_buf_len; 57 gsize write_buf_len;
52 gsize written_len; 58 gsize written_len;
53 GaimInputFunction read_cb; 59 GaimInputFunction read_cb;
54 guchar *read_buffer; 60 guchar *read_buffer;
69 }; 75 };
70 76
71 static GaimProxyInfo *global_proxy_info = NULL; 77 static GaimProxyInfo *global_proxy_info = NULL;
72 static GSList *connect_infos = NULL; 78 static GSList *connect_infos = NULL;
73 79
74 static void try_connect(struct _GaimProxyConnectInfo *); 80 static void try_connect(GaimProxyConnectInfo *);
75 81
76 /************************************************************************** 82 /**************************************************************************
77 * Proxy structure API 83 * Proxy structure API
78 **************************************************************************/ 84 **************************************************************************/
79 GaimProxyInfo * 85 GaimProxyInfo *
255 /************************************************************************** 261 /**************************************************************************
256 * Proxy API 262 * Proxy API
257 **************************************************************************/ 263 **************************************************************************/
258 264
259 static void 265 static void
260 gaim_proxy_connect_info_destroy(struct _GaimProxyConnectInfo *connect_info) 266 gaim_proxy_connect_info_destroy(GaimProxyConnectInfo *connect_info)
261 { 267 {
262 connect_infos = g_slist_remove(connect_infos, connect_info); 268 connect_infos = g_slist_remove(connect_infos, connect_info);
263 269
264 if (connect_info->inpa > 0) 270 if (connect_info->inpa > 0)
265 gaim_input_remove(connect_info->inpa); 271 gaim_input_remove(connect_info->inpa);
278 g_free(connect_info->read_buffer); 284 g_free(connect_info->read_buffer);
279 g_free(connect_info); 285 g_free(connect_info);
280 } 286 }
281 287
282 static void 288 static void
283 gaim_proxy_connect_info_connected(struct _GaimProxyConnectInfo *connect_info, int fd) 289 gaim_proxy_connect_info_connected(GaimProxyConnectInfo *connect_info, int fd)
284 { 290 {
285 connect_info->connect_cb(connect_info->data, fd); 291 connect_info->connect_cb(connect_info->data, fd);
286 gaim_proxy_connect_info_destroy(connect_info); 292 gaim_proxy_connect_info_destroy(connect_info);
287 } 293 }
288 294
290 * @param error An error message explaining why the connection 296 * @param error An error message explaining why the connection
291 * failed. This will be passed to the callback function 297 * failed. This will be passed to the callback function
292 * specified in the call to gaim_proxy_connect(). 298 * specified in the call to gaim_proxy_connect().
293 */ 299 */
294 static void 300 static void
295 gaim_proxy_connect_info_error(struct _GaimProxyConnectInfo *connect_info, const gchar *error_message) 301 gaim_proxy_connect_info_error(GaimProxyConnectInfo *connect_info, const gchar *error_message)
296 { 302 {
297 if (connect_info->error_cb == NULL) 303 if (connect_info->error_cb == NULL)
298 { 304 {
299 /* 305 /*
300 * TODO 306 * TODO
988 #endif /* not __unix__ or __APPLE__ or _WIN32 */ 994 #endif /* not __unix__ or __APPLE__ or _WIN32 */
989 995
990 static void 996 static void
991 no_one_calls(gpointer data, gint source, GaimInputCondition cond) 997 no_one_calls(gpointer data, gint source, GaimInputCondition cond)
992 { 998 {
993 struct _GaimProxyConnectInfo *connect_info = data; 999 GaimProxyConnectInfo *connect_info = data;
994 socklen_t len; 1000 socklen_t len;
995 int error=0, ret; 1001 int error=0, ret;
996 1002
997 gaim_debug_info("proxy", "Connected.\n"); 1003 gaim_debug_info("proxy", "Connected.\n");
998 1004
1032 gaim_proxy_connect_info_connected(connect_info, source); 1038 gaim_proxy_connect_info_connected(connect_info, source);
1033 } 1039 }
1034 1040
1035 static gboolean clean_connect(gpointer data) 1041 static gboolean clean_connect(gpointer data)
1036 { 1042 {
1037 struct _GaimProxyConnectInfo *connect_info = data; 1043 GaimProxyConnectInfo *connect_info = data;
1038 1044
1039 gaim_proxy_connect_info_connected(connect_info, connect_info->port); 1045 gaim_proxy_connect_info_connected(connect_info, connect_info->port);
1040 1046
1041 return FALSE; 1047 return FALSE;
1042 } 1048 }
1043 1049
1044 1050
1045 static int 1051 static int
1046 proxy_connect_none(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 1052 proxy_connect_none(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen)
1047 { 1053 {
1048 int fd = -1; 1054 int fd = -1;
1049 1055
1050 gaim_debug_info("proxy", 1056 gaim_debug_info("proxy",
1051 "Connecting to %s:%d with no proxy\n", connect_info->host, connect_info->port); 1057 "Connecting to %s:%d with no proxy\n", connect_info->host, connect_info->port);
1095 } 1101 }
1096 1102
1097 static void 1103 static void
1098 proxy_do_write(gpointer data, gint source, GaimInputCondition cond) 1104 proxy_do_write(gpointer data, gint source, GaimInputCondition cond)
1099 { 1105 {
1100 struct _GaimProxyConnectInfo *connect_info = data; 1106 GaimProxyConnectInfo *connect_info = data;
1101 const guchar *request = connect_info->write_buffer + connect_info->written_len; 1107 const guchar *request = connect_info->write_buffer + connect_info->written_len;
1102 gsize request_len = connect_info->write_buf_len - connect_info->written_len; 1108 gsize request_len = connect_info->write_buf_len - connect_info->written_len;
1103 1109
1104 int ret = write(source, request, request_len); 1110 int ret = write(source, request, request_len);
1105 1111
1133 static void 1139 static void
1134 http_canread(gpointer data, gint source, GaimInputCondition cond) 1140 http_canread(gpointer data, gint source, GaimInputCondition cond)
1135 { 1141 {
1136 int len, headers_len, status = 0; 1142 int len, headers_len, status = 0;
1137 gboolean error; 1143 gboolean error;
1138 struct _GaimProxyConnectInfo *connect_info = data; 1144 GaimProxyConnectInfo *connect_info = data;
1139 guchar *p; 1145 guchar *p;
1140 gsize max_read; 1146 gsize max_read;
1141 gchar *msg; 1147 gchar *msg;
1142 1148
1143 if(connect_info->read_buffer == NULL) { 1149 if(connect_info->read_buffer == NULL) {
1365 static void 1371 static void
1366 http_canwrite(gpointer data, gint source, GaimInputCondition cond) 1372 http_canwrite(gpointer data, gint source, GaimInputCondition cond)
1367 { 1373 {
1368 char request[8192]; 1374 char request[8192];
1369 int request_len = 0; 1375 int request_len = 0;
1370 struct _GaimProxyConnectInfo *connect_info = data; 1376 GaimProxyConnectInfo *connect_info = data;
1371 socklen_t len; 1377 socklen_t len;
1372 int error = ETIMEDOUT; 1378 int error = ETIMEDOUT;
1373 1379
1374 gaim_debug_info("http proxy", "Connected.\n"); 1380 gaim_debug_info("http proxy", "Connected.\n");
1375 1381
1428 1434
1429 proxy_do_write(connect_info, source, cond); 1435 proxy_do_write(connect_info, source, cond);
1430 } 1436 }
1431 1437
1432 static int 1438 static int
1433 proxy_connect_http(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 1439 proxy_connect_http(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen)
1434 { 1440 {
1435 int fd = -1; 1441 int fd = -1;
1436 1442
1437 gaim_debug_info("http proxy", 1443 gaim_debug_info("http proxy",
1438 "Connecting to %s:%d via %s:%d using HTTP\n", 1444 "Connecting to %s:%d via %s:%d using HTTP\n",
1487 1493
1488 1494
1489 static void 1495 static void
1490 s4_canread(gpointer data, gint source, GaimInputCondition cond) 1496 s4_canread(gpointer data, gint source, GaimInputCondition cond)
1491 { 1497 {
1492 struct _GaimProxyConnectInfo *connect_info = data; 1498 GaimProxyConnectInfo *connect_info = data;
1493 guchar *buf; 1499 guchar *buf;
1494 int len, max_read; 1500 int len, max_read;
1495 1501
1496 /* This is really not going to block under normal circumstances, but to 1502 /* This is really not going to block under normal circumstances, but to
1497 * be correct, we deal with the unlikely scenario */ 1503 * be correct, we deal with the unlikely scenario */
1529 static void 1535 static void
1530 s4_canwrite(gpointer data, gint source, GaimInputCondition cond) 1536 s4_canwrite(gpointer data, gint source, GaimInputCondition cond)
1531 { 1537 {
1532 unsigned char packet[9]; 1538 unsigned char packet[9];
1533 struct hostent *hp; 1539 struct hostent *hp;
1534 struct _GaimProxyConnectInfo *connect_info = data; 1540 GaimProxyConnectInfo *connect_info = data;
1535 socklen_t len; 1541 socklen_t len;
1536 int error = ETIMEDOUT; 1542 int error = ETIMEDOUT;
1537 1543
1538 gaim_debug_info("socks4 proxy", "Connected.\n"); 1544 gaim_debug_info("socks4 proxy", "Connected.\n");
1539 1545
1586 1592
1587 proxy_do_write(connect_info, source, cond); 1593 proxy_do_write(connect_info, source, cond);
1588 } 1594 }
1589 1595
1590 static int 1596 static int
1591 proxy_connect_socks4(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 1597 proxy_connect_socks4(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen)
1592 { 1598 {
1593 int fd = -1; 1599 int fd = -1;
1594 1600
1595 gaim_debug_info("socks4 proxy", 1601 gaim_debug_info("socks4 proxy",
1596 "Connecting to %s:%d via %s:%d using SOCKS4\n", 1602 "Connecting to %s:%d via %s:%d using SOCKS4\n",
1638 1644
1639 static void 1645 static void
1640 s5_canread_again(gpointer data, gint source, GaimInputCondition cond) 1646 s5_canread_again(gpointer data, gint source, GaimInputCondition cond)
1641 { 1647 {
1642 guchar *dest, *buf; 1648 guchar *dest, *buf;
1643 struct _GaimProxyConnectInfo *connect_info = data; 1649 GaimProxyConnectInfo *connect_info = data;
1644 int len; 1650 int len;
1645 1651
1646 if (connect_info->read_buffer == NULL) { 1652 if (connect_info->read_buffer == NULL) {
1647 connect_info->read_buf_len = 512; 1653 connect_info->read_buf_len = 512;
1648 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1654 connect_info->read_buffer = g_malloc(connect_info->read_buf_len);
1720 } 1726 }
1721 1727
1722 static void 1728 static void
1723 s5_sendconnect(gpointer data, int source) 1729 s5_sendconnect(gpointer data, int source)
1724 { 1730 {
1725 struct _GaimProxyConnectInfo *connect_info = data; 1731 GaimProxyConnectInfo *connect_info = data;
1726 int hlen = strlen(connect_info->host); 1732 int hlen = strlen(connect_info->host);
1727 connect_info->write_buf_len = 5 + hlen + 2; 1733 connect_info->write_buf_len = 5 + hlen + 2;
1728 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1734 connect_info->write_buffer = g_malloc(connect_info->write_buf_len);
1729 connect_info->written_len = 0; 1735 connect_info->written_len = 0;
1730 1736
1744 } 1750 }
1745 1751
1746 static void 1752 static void
1747 s5_readauth(gpointer data, gint source, GaimInputCondition cond) 1753 s5_readauth(gpointer data, gint source, GaimInputCondition cond)
1748 { 1754 {
1749 struct _GaimProxyConnectInfo *connect_info = data; 1755 GaimProxyConnectInfo *connect_info = data;
1750 int len; 1756 int len;
1751 1757
1752 if (connect_info->read_buffer == NULL) { 1758 if (connect_info->read_buffer == NULL) {
1753 connect_info->read_buf_len = 2; 1759 connect_info->read_buf_len = 2;
1754 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1760 connect_info->read_buffer = g_malloc(connect_info->read_buf_len);
1790 connect_info->read_buffer = NULL; 1796 connect_info->read_buffer = NULL;
1791 1797
1792 s5_sendconnect(connect_info, source); 1798 s5_sendconnect(connect_info, source);
1793 } 1799 }
1794 1800
1795 static void hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response) 1801 static void
1802 hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response)
1796 { 1803 {
1797 GaimCipher *cipher; 1804 GaimCipher *cipher;
1798 GaimCipherContext *ctx; 1805 GaimCipherContext *ctx;
1799 int i; 1806 int i;
1800 unsigned char Kxoripad[65]; 1807 unsigned char Kxoripad[65];
1837 1844
1838 static void 1845 static void
1839 s5_readchap(gpointer data, gint source, GaimInputCondition cond) 1846 s5_readchap(gpointer data, gint source, GaimInputCondition cond)
1840 { 1847 {
1841 guchar *cmdbuf, *buf; 1848 guchar *cmdbuf, *buf;
1842 struct _GaimProxyConnectInfo *connect_info = data; 1849 GaimProxyConnectInfo *connect_info = data;
1843 int len, navas, currentav; 1850 int len, navas, currentav;
1844 1851
1845 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n"); 1852 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n");
1846 1853
1847 if (connect_info->read_buffer == NULL) { 1854 if (connect_info->read_buffer == NULL) {
1970 } 1977 }
1971 1978
1972 static void 1979 static void
1973 s5_canread(gpointer data, gint source, GaimInputCondition cond) 1980 s5_canread(gpointer data, gint source, GaimInputCondition cond)
1974 { 1981 {
1975 struct _GaimProxyConnectInfo *connect_info = data; 1982 GaimProxyConnectInfo *connect_info = data;
1976 int len; 1983 int len;
1977 1984
1978 if (connect_info->read_buffer == NULL) { 1985 if (connect_info->read_buffer == NULL) {
1979 connect_info->read_buf_len = 2; 1986 connect_info->read_buf_len = 2;
1980 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1987 connect_info->read_buffer = g_malloc(connect_info->read_buf_len);
2085 static void 2092 static void
2086 s5_canwrite(gpointer data, gint source, GaimInputCondition cond) 2093 s5_canwrite(gpointer data, gint source, GaimInputCondition cond)
2087 { 2094 {
2088 unsigned char buf[5]; 2095 unsigned char buf[5];
2089 int i; 2096 int i;
2090 struct _GaimProxyConnectInfo *connect_info = data; 2097 GaimProxyConnectInfo *connect_info = data;
2091 socklen_t len; 2098 socklen_t len;
2092 int error = ETIMEDOUT; 2099 int error = ETIMEDOUT;
2093 2100
2094 gaim_debug_info("socks5 proxy", "Connected.\n"); 2101 gaim_debug_info("socks5 proxy", "Connected.\n");
2095 2102
2132 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info); 2139 connect_info->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, connect_info);
2133 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE); 2140 proxy_do_write(connect_info, source, GAIM_INPUT_WRITE);
2134 } 2141 }
2135 2142
2136 static int 2143 static int
2137 proxy_connect_socks5(struct _GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 2144 proxy_connect_socks5(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen)
2138 { 2145 {
2139 int fd = -1; 2146 int fd = -1;
2140 2147
2141 gaim_debug_info("socks5 proxy", 2148 gaim_debug_info("socks5 proxy",
2142 "Connecting to %s:%d via %s:%d using SOCKS5\n", 2149 "Connecting to %s:%d via %s:%d using SOCKS5\n",
2166 } 2173 }
2167 else { 2174 else {
2168 socklen_t len; 2175 socklen_t len;
2169 int error = ETIMEDOUT; 2176 int error = ETIMEDOUT;
2170 2177
2171 gaim_debug_misc("socks5 proxy", 2178 gaim_debug_misc("socks5 proxy", "Connect didn't block.\n");
2172 "Connect didn't block.\n");
2173 2179
2174 len = sizeof(error); 2180 len = sizeof(error);
2175 2181
2176 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 2182 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
2177 close(fd); 2183 close(fd);
2182 } 2188 }
2183 2189
2184 return fd; 2190 return fd;
2185 } 2191 }
2186 2192
2187 static void try_connect(struct _GaimProxyConnectInfo *connect_info) 2193 static void try_connect(GaimProxyConnectInfo *connect_info)
2188 { 2194 {
2189 size_t addrlen; 2195 size_t addrlen;
2190 struct sockaddr *addr; 2196 struct sockaddr *addr;
2191 int ret = -1; 2197 int ret = -1;
2192 2198
2234 2240
2235 static void 2241 static void
2236 connection_host_resolved(GSList *hosts, gpointer data, 2242 connection_host_resolved(GSList *hosts, gpointer data,
2237 const char *error_message) 2243 const char *error_message)
2238 { 2244 {
2239 struct _GaimProxyConnectInfo *connect_info = (struct _GaimProxyConnectInfo*)data; 2245 GaimProxyConnectInfo *connect_info;
2240 2246
2247 connect_info = data;
2241 connect_info->hosts = hosts; 2248 connect_info->hosts = hosts;
2242 2249
2243 try_connect(connect_info); 2250 try_connect(connect_info);
2244 } 2251 }
2245 2252
2314 GaimProxyConnectFunction connect_cb, 2321 GaimProxyConnectFunction connect_cb,
2315 GaimProxyErrorFunction error_cb, gpointer data) 2322 GaimProxyErrorFunction error_cb, gpointer data)
2316 { 2323 {
2317 const char *connecthost = host; 2324 const char *connecthost = host;
2318 int connectport = port; 2325 int connectport = port;
2319 struct _GaimProxyConnectInfo *connect_info; 2326 GaimProxyConnectInfo *connect_info;
2320 2327
2321 g_return_val_if_fail(host != NULL, NULL); 2328 g_return_val_if_fail(host != NULL, NULL);
2322 g_return_val_if_fail(port > 0, NULL); 2329 g_return_val_if_fail(port > 0, NULL);
2323 g_return_val_if_fail(connect_cb != NULL, NULL); 2330 g_return_val_if_fail(connect_cb != NULL, NULL);
2324 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ 2331 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */
2325 2332
2326 connect_info = g_new0(struct _GaimProxyConnectInfo, 1); 2333 connect_info = g_new0(GaimProxyConnectInfo, 1);
2327 connect_info->connect_cb = connect_cb; 2334 connect_info->connect_cb = connect_cb;
2328 connect_info->error_cb = error_cb; 2335 connect_info->error_cb = error_cb;
2329 connect_info->data = data; 2336 connect_info->data = data;
2330 connect_info->host = g_strdup(host); 2337 connect_info->host = g_strdup(host);
2331 connect_info->port = port; 2338 connect_info->port = port;
2376 GaimProxyConnectInfo * 2383 GaimProxyConnectInfo *
2377 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, 2384 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port,
2378 GaimProxyConnectFunction connect_cb, 2385 GaimProxyConnectFunction connect_cb,
2379 GaimProxyErrorFunction error_cb, gpointer data) 2386 GaimProxyErrorFunction error_cb, gpointer data)
2380 { 2387 {
2381 struct _GaimProxyConnectInfo *connect_info; 2388 GaimProxyConnectInfo *connect_info;
2382 2389
2383 g_return_val_if_fail(host != NULL, NULL); 2390 g_return_val_if_fail(host != NULL, NULL);
2384 g_return_val_if_fail(port > 0, NULL); 2391 g_return_val_if_fail(port > 0, NULL);
2385 g_return_val_if_fail(connect_cb != NULL, NULL); 2392 g_return_val_if_fail(connect_cb != NULL, NULL);
2386 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ 2393 /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */
2387 2394
2388 connect_info = g_new0(struct _GaimProxyConnectInfo, 1); 2395 connect_info = g_new0(GaimProxyConnectInfo, 1);
2389 connect_info->connect_cb = connect_cb; 2396 connect_info->connect_cb = connect_cb;
2390 connect_info->error_cb = error_cb; 2397 connect_info->error_cb = error_cb;
2391 connect_info->data = data; 2398 connect_info->data = data;
2392 connect_info->host = g_strdup(host); 2399 connect_info->host = g_strdup(host);
2393 connect_info->port = port; 2400 connect_info->port = port;