diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_con/ecore_con_socks.c | 496 |
1 files changed, 496 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c b/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c new file mode 100644 index 0000000..aecaff0 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_con/ecore_con_socks.c | |||
@@ -0,0 +1,496 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #include <stdio.h> | ||
6 | #include <string.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <sys/stat.h> | ||
9 | #include <errno.h> | ||
10 | #include <unistd.h> | ||
11 | #include <fcntl.h> | ||
12 | |||
13 | #ifdef HAVE_NETINET_TCP_H | ||
14 | # include <netinet/tcp.h> | ||
15 | #endif | ||
16 | |||
17 | #ifdef HAVE_NET_IF_H | ||
18 | # include <net/if.h> | ||
19 | #endif | ||
20 | |||
21 | /* if net/if.h is not found or if an older versions of net/if.h is provided | ||
22 | which does not define IF_NAMESIZE. We must define it ourselves */ | ||
23 | #ifndef IF_NAMESIZE | ||
24 | # ifdef IFNAMSIZ | ||
25 | # define IF_NAMESIZE IFNAMSIZ | ||
26 | # else | ||
27 | # define IF_NAMESIZE 16 | ||
28 | # endif | ||
29 | #endif | ||
30 | |||
31 | #ifdef HAVE_NETINET_IN_H | ||
32 | # include <netinet/in.h> | ||
33 | #endif | ||
34 | |||
35 | #ifdef HAVE_ARPA_INET_H | ||
36 | # include <arpa/inet.h> | ||
37 | #endif | ||
38 | |||
39 | #ifdef HAVE_SYS_SOCKET_H | ||
40 | # include <sys/socket.h> | ||
41 | #endif | ||
42 | |||
43 | #ifdef HAVE_SYS_UN_H | ||
44 | # include <sys/un.h> | ||
45 | #endif | ||
46 | |||
47 | #ifdef HAVE_WS2TCPIP_H | ||
48 | # include <ws2tcpip.h> | ||
49 | #endif | ||
50 | |||
51 | #ifdef HAVE_EVIL | ||
52 | # include <Evil.h> | ||
53 | #endif | ||
54 | |||
55 | #include "Ecore.h" | ||
56 | #include "ecore_private.h" | ||
57 | #include "Ecore_Con.h" | ||
58 | #include "ecore_con_private.h" | ||
59 | |||
60 | #define _ecore_con_server_kill(svr) do { \ | ||
61 | DBG("KILL %p", (svr)); \ | ||
62 | _ecore_con_server_kill((svr)); \ | ||
63 | } while (0) | ||
64 | |||
65 | Eina_List *ecore_con_socks_proxies = NULL; | ||
66 | |||
67 | static Ecore_Con_Socks * | ||
68 | _ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username) | ||
69 | { | ||
70 | Eina_List *l; | ||
71 | Ecore_Con_Socks *ecs; | ||
72 | |||
73 | if (!ecore_con_socks_proxies) return NULL; | ||
74 | |||
75 | EINA_LIST_FOREACH(ecore_con_socks_proxies, l, ecs) | ||
76 | { | ||
77 | if (ecs->version != version) continue; | ||
78 | if (strcmp(ecs->ip, ip)) continue; | ||
79 | if ((port != -1) && (port != ecs->port)) continue; | ||
80 | if (username && strcmp(ecs->username, username)) continue; | ||
81 | return ecs; | ||
82 | } | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | _ecore_con_socks_free(Ecore_Con_Socks *ecs) | ||
88 | { | ||
89 | ECORE_CON_SOCKS_CAST_ELSE(ecs) return; | ||
90 | |||
91 | if (_ecore_con_proxy_once == ecs) _ecore_con_proxy_once = NULL; | ||
92 | if (_ecore_con_proxy_global == ecs) _ecore_con_proxy_global = NULL; | ||
93 | eina_stringshare_del(ecs->ip); | ||
94 | eina_stringshare_del(ecs->username); | ||
95 | free(ecs); | ||
96 | } | ||
97 | ///////////////////////////////////////////////////////////////////////////////////// | ||
98 | void | ||
99 | ecore_con_socks_shutdown(void) | ||
100 | { | ||
101 | Ecore_Con_Socks *ecs; | ||
102 | EINA_LIST_FREE(ecore_con_socks_proxies, ecs) | ||
103 | _ecore_con_socks_free(ecs); | ||
104 | _ecore_con_proxy_once = NULL; | ||
105 | _ecore_con_proxy_global = NULL; | ||
106 | } | ||
107 | |||
108 | void | ||
109 | ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num) | ||
110 | { | ||
111 | const unsigned char *data; | ||
112 | ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return; | ||
113 | |||
114 | if (svr->ecs_state != ECORE_CON_SOCKS_STATE_READ) return; | ||
115 | |||
116 | if (v4) | ||
117 | { | ||
118 | DBG("SOCKS: %d bytes", num); | ||
119 | if (num < 8) | ||
120 | { | ||
121 | if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); | ||
122 | if (!svr->ecs_recvbuf) goto error; | ||
123 | eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); | ||
124 | /* the slowest connection on earth */ | ||
125 | if (eina_binbuf_length_get(svr->ecs_recvbuf) != 8) return; | ||
126 | data = eina_binbuf_string_get(svr->ecs_recvbuf); | ||
127 | } | ||
128 | else if (num > 8) goto error; | ||
129 | else | ||
130 | data = buf; | ||
131 | |||
132 | /* http://ufasoft.com/doc/socks4_protocol.htm */ | ||
133 | if (data[0]) goto error; | ||
134 | switch (data[1]) | ||
135 | { | ||
136 | case 90: | ||
137 | /* success! */ | ||
138 | break; | ||
139 | case 91: | ||
140 | ecore_con_event_server_error(svr, "proxy request rejected or failed"); | ||
141 | goto error; | ||
142 | case 92: | ||
143 | ecore_con_event_server_error(svr, "proxying SOCKS server could not perform authentication"); | ||
144 | goto error; | ||
145 | case 93: | ||
146 | ecore_con_event_server_error(svr, "proxy request authentication rejected"); | ||
147 | goto error; | ||
148 | default: | ||
149 | ecore_con_event_server_error(svr, "garbage data from proxy"); | ||
150 | goto error; | ||
151 | } | ||
152 | if (svr->ecs->bind) | ||
153 | { | ||
154 | unsigned int nport; | ||
155 | char naddr[IF_NAMESIZE]; | ||
156 | |||
157 | memcpy(&nport, &data[2], 2); | ||
158 | svr->proxyport = ntohl(nport); | ||
159 | |||
160 | if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error; | ||
161 | svr->proxyip = eina_stringshare_add(naddr); | ||
162 | ecore_con_event_proxy_bind(svr); | ||
163 | } | ||
164 | svr->ecs_state = ECORE_CON_SOCKS_STATE_DONE; | ||
165 | INF("PROXY CONNECTED"); | ||
166 | if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf); | ||
167 | svr->ecs_recvbuf = NULL; | ||
168 | svr->ecs_buf_offset = svr->ecs_addrlen = 0; | ||
169 | memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr)); | ||
170 | if (!svr->ssl_state) | ||
171 | ecore_con_event_server_add(svr); | ||
172 | if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf))) | ||
173 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE); | ||
174 | } | ||
175 | return; | ||
176 | error: | ||
177 | _ecore_con_server_kill(svr); | ||
178 | } | ||
179 | |||
180 | Eina_Bool | ||
181 | ecore_con_socks_svr_init(Ecore_Con_Server *svr) | ||
182 | { | ||
183 | unsigned char *sbuf; | ||
184 | ECORE_CON_SOCKS_CAST_ELSE(svr->ecs) return EINA_FALSE; | ||
185 | |||
186 | if (!svr->ip) return EINA_FALSE; | ||
187 | if (svr->ecs_buf) return EINA_FALSE; | ||
188 | if (svr->ecs_state != ECORE_CON_SOCKS_STATE_INIT) return EINA_FALSE; | ||
189 | ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE); | ||
190 | if (v4) | ||
191 | { | ||
192 | size_t addrlen, buflen, ulen = 1; | ||
193 | addrlen = svr->ecs->lookup ? strlen(svr->name) + 1: 0; | ||
194 | if (svr->ecs->username) ulen += strlen(svr->ecs->username); | ||
195 | buflen = sizeof(char) * (8 + ulen + addrlen); | ||
196 | sbuf = malloc(buflen); | ||
197 | if (!sbuf) | ||
198 | { | ||
199 | ecore_con_event_server_error(svr, "Memory allocation failure!"); | ||
200 | _ecore_con_server_kill(svr); | ||
201 | return EINA_FALSE; | ||
202 | } | ||
203 | /* http://en.wikipedia.org/wiki/SOCKS */ | ||
204 | sbuf[0] = 4; | ||
205 | sbuf[1] = v4->bind ? 2 : 1; | ||
206 | sbuf[2] = svr->port >> 8; | ||
207 | sbuf[3] = svr->port & 0xff; | ||
208 | if (addrlen) | ||
209 | { | ||
210 | sbuf[4] = sbuf[5] = sbuf[6] = 0; | ||
211 | sbuf[7] = 1; | ||
212 | } | ||
213 | else | ||
214 | memcpy(sbuf + 4, svr->ecs_addr, 4); | ||
215 | if (svr->ecs->username) | ||
216 | memcpy(sbuf + 8, svr->ecs->username, ulen); | ||
217 | else | ||
218 | sbuf[8] = 0; | ||
219 | if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen); | ||
220 | |||
221 | svr->ecs_buf = eina_binbuf_manage_new_length(sbuf, buflen); | ||
222 | } | ||
223 | return EINA_TRUE; | ||
224 | } | ||
225 | |||
226 | void | ||
227 | ecore_con_socks_dns_cb(const char *canonname __UNUSED__, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr) | ||
228 | { | ||
229 | svr->ip = eina_stringshare_add(ip); | ||
230 | svr->ecs_addrlen = addrlen; | ||
231 | svr->ecs_state++; | ||
232 | if (addr->sa_family == AF_INET) | ||
233 | memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4); | ||
234 | #ifdef HAVE_IPV6 | ||
235 | else | ||
236 | memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, addrlen); | ||
237 | #endif | ||
238 | ecore_con_socks_svr_init(svr); | ||
239 | } | ||
240 | |||
241 | void | ||
242 | ecore_con_socks_init(void) | ||
243 | { | ||
244 | const char *socks; | ||
245 | char *u, *h, *p, *l; | ||
246 | char buf[64]; | ||
247 | int port, lookup = 0; | ||
248 | Ecore_Con_Socks *ecs; | ||
249 | unsigned char addr[sizeof(struct in_addr)]; | ||
250 | |||
251 | /* ECORE_CON_SOCKS_V4=user@host:port:[1|0] */ | ||
252 | socks = getenv("ECORE_CON_SOCKS_V4"); | ||
253 | if ((!socks) || (!socks[0]) || (strlen(socks) > 64)) return; | ||
254 | strncpy(buf, socks, sizeof(buf)); | ||
255 | h = strchr(buf, '@'); | ||
256 | u = NULL; | ||
257 | /* username */ | ||
258 | if (h && (h - buf > 0)) *h++ = 0, u = buf; | ||
259 | else h = buf; | ||
260 | |||
261 | /* host ip; I ain't resolvin shit here */ | ||
262 | p = strchr(h, ':'); | ||
263 | if (!p) return; | ||
264 | *p++ = 0; | ||
265 | if (!inet_pton(AF_INET, h, addr)) return; | ||
266 | |||
267 | errno = 0; | ||
268 | port = strtol(p, &l, 10); | ||
269 | if (errno || (port < 0) || (port > 65535)) return; | ||
270 | if (l && (l[0] == ':')) | ||
271 | lookup = (l[1] == '1'); | ||
272 | ecs = ecore_con_socks4_remote_add(h, port, u); | ||
273 | if (!ecs) return; | ||
274 | ecore_con_socks4_lookup_set(ecs, lookup); | ||
275 | ecore_con_socks_apply_always(ecs); | ||
276 | INF("Added global proxy server %s%s%s:%d - DNS lookup %s", | ||
277 | u ?: "", u ? "@" : "", h, port, lookup ? "ENABLED" : "DISABLED"); | ||
278 | } | ||
279 | |||
280 | ///////////////////////////////////////////////////////////////////////////////////// | ||
281 | |||
282 | /** | ||
283 | * @defgroup Ecore_Con_Socks_Group Ecore Connection SOCKS functions | ||
284 | * @{ | ||
285 | */ | ||
286 | |||
287 | /** | ||
288 | * Add a SOCKS v4 proxy to the proxy list | ||
289 | * | ||
290 | * Use this to create (or return, if previously added) a SOCKS proxy | ||
291 | * object which can be used by any ecore_con servers. | ||
292 | * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) | ||
293 | * @param port The port to connect to on the proxy | ||
294 | * @param username The username to use for the proxy (OPTIONAL) | ||
295 | * @return An allocated proxy object, or NULL on failure | ||
296 | * @note This object NEVER needs to be explicitly freed. | ||
297 | * @since 1.2 | ||
298 | */ | ||
299 | EAPI Ecore_Con_Socks * | ||
300 | ecore_con_socks4_remote_add(const char *ip, int port, const char *username) | ||
301 | { | ||
302 | Ecore_Con_Socks *ecs; | ||
303 | |||
304 | if ((!ip) || (!ip[0]) || (port < 0) || (port > 65535)) return NULL; | ||
305 | |||
306 | ecs = _ecore_con_socks_find(4, ip, port, username); | ||
307 | if (ecs) return ecs; | ||
308 | |||
309 | ecs = calloc(1, sizeof(Ecore_Con_Socks_v4)); | ||
310 | if (!ecs) return NULL; | ||
311 | |||
312 | ecs->version = 4; | ||
313 | ecs->ip = eina_stringshare_add(ip); | ||
314 | ecs->port = port; | ||
315 | ecs->username = eina_stringshare_add(username); | ||
316 | ecore_con_socks_proxies = eina_list_append(ecore_con_socks_proxies, ecs); | ||
317 | return ecs; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * Set DNS lookup mode on an existing SOCKS v4 proxy | ||
322 | * | ||
323 | * According to RFC, SOCKS v4 does not require that a proxy perform | ||
324 | * its own DNS lookups for addresses. SOCKS v4a specifies the protocol | ||
325 | * for this. If you want to enable remote DNS lookup and are sure that your | ||
326 | * proxy supports it, use this function. | ||
327 | * @param ecs The proxy object | ||
328 | * @param enable If true, the proxy will perform the dns lookup | ||
329 | * @note By default, this setting is DISABLED. | ||
330 | * @since 1.2 | ||
331 | */ | ||
332 | EAPI void | ||
333 | ecore_con_socks4_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable) | ||
334 | { | ||
335 | ECORE_CON_SOCKS_CAST_ELSE(ecs) return; | ||
336 | if (v4) v4->lookup = !!enable; | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * Get DNS lookup mode on an existing SOCKS v4 proxy | ||
341 | * | ||
342 | * According to RFC, SOCKS v4 does not require that a proxy perform | ||
343 | * its own DNS lookups for addresses. SOCKS v4a specifies the protocol | ||
344 | * for this. This function returns whether lookups are enabled on a proxy object. | ||
345 | * @param ecs The proxy object | ||
346 | * @return If true, the proxy will perform the dns lookup | ||
347 | * @note By default, this setting is DISABLED. | ||
348 | * @since 1.2 | ||
349 | */ | ||
350 | EAPI Eina_Bool | ||
351 | ecore_con_socks4_lookup_get(Ecore_Con_Socks *ecs) | ||
352 | { | ||
353 | ECORE_CON_SOCKS_CAST_ELSE(ecs) return EINA_FALSE; | ||
354 | return v4 ? v4->lookup : EINA_FALSE; | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * Find a SOCKS v4 proxy in the proxy list | ||
359 | * | ||
360 | * Use this to determine if a SOCKS proxy was previously added by checking | ||
361 | * the proxy list against the parameters given. | ||
362 | * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) | ||
363 | * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip | ||
364 | * @param username The username used for the proxy (OPTIONAL) | ||
365 | * @return true only if a proxy exists matching the given params | ||
366 | * @note This function matches slightly more loosely than ecore_con_socks4_remote_add(), and | ||
367 | * ecore_con_socks4_remote_add() should be used to return the actual object. | ||
368 | * @since 1.2 | ||
369 | */ | ||
370 | EAPI Eina_Bool | ||
371 | ecore_con_socks4_remote_exists(const char *ip, int port, const char *username) | ||
372 | { | ||
373 | if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) | ||
374 | return EINA_FALSE; | ||
375 | return !!_ecore_con_socks_find(4, ip, port, username); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Remove a SOCKS v4 proxy from the proxy list and delete it | ||
380 | * | ||
381 | * Use this to remove a SOCKS proxy from the proxy list by checking | ||
382 | * the list against the parameters given. The proxy will then be deleted. | ||
383 | * @param ip The ip address of the proxy (NOT DOMAIN NAME. IP ADDRESS.) | ||
384 | * @param port The port to connect to on the proxy, or -1 to match the first proxy with @p ip | ||
385 | * @param username The username used for the proxy (OPTIONAL) | ||
386 | * @note This function matches in the same way as ecore_con_socks4_remote_exists(). | ||
387 | * @warning Be aware that deleting a proxy which is being used WILL ruin your life. | ||
388 | * @since 1.2 | ||
389 | */ | ||
390 | EAPI void | ||
391 | ecore_con_socks4_remote_del(const char *ip, int port, const char *username) | ||
392 | { | ||
393 | Ecore_Con_Socks_v4 *v4; | ||
394 | |||
395 | if ((!ip) || (!ip[0]) || (port < -1) || (port > 65535) || (username && (!username[0]))) return; | ||
396 | if (!ecore_con_socks_proxies) return; | ||
397 | |||
398 | v4 = (Ecore_Con_Socks_v4*)_ecore_con_socks_find(4, ip, port, username); | ||
399 | if (!v4) return; | ||
400 | ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, v4); | ||
401 | _ecore_con_socks_free((Ecore_Con_Socks*)v4); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Enable bind mode on a SOCKS proxy | ||
406 | * | ||
407 | * Use this function to enable binding a remote port for use with a remote server. | ||
408 | * For more information, see http://ufasoft.com/doc/socks4_protocol.htm | ||
409 | * @param ecs The proxy object | ||
410 | * @param is_bind If true, the connection established will be a port binding | ||
411 | * @warning Be aware that changing the operation mode of an active proxy may result in undefined behavior | ||
412 | * @since 1.2 | ||
413 | */ | ||
414 | EAPI void | ||
415 | ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind) | ||
416 | { | ||
417 | EINA_SAFETY_ON_NULL_RETURN(ecs); | ||
418 | ecs->bind = !!is_bind; | ||
419 | } | ||
420 | |||
421 | /** | ||
422 | * Return bind mode of a SOCKS proxy | ||
423 | * | ||
424 | * Use this function to return bind mode of a proxy (binding a remote port for use with a remote server). | ||
425 | * For more information, see http://ufasoft.com/doc/socks4_protocol.htm | ||
426 | * @param ecs The proxy object | ||
427 | * @return If true, the connection established will be a port binding | ||
428 | * @since 1.2 | ||
429 | */ | ||
430 | EAPI Eina_Bool | ||
431 | ecore_con_socks_bind_get(Ecore_Con_Socks *ecs) | ||
432 | { | ||
433 | EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, EINA_FALSE); | ||
434 | return ecs->bind; | ||
435 | } | ||
436 | |||
437 | EAPI unsigned int | ||
438 | ecore_con_socks_version_get(Ecore_Con_Socks *ecs) | ||
439 | { | ||
440 | EINA_SAFETY_ON_NULL_RETURN_VAL(ecs, 0); | ||
441 | return ecs->version; | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | * Remove a SOCKS v4 proxy from the proxy list and delete it | ||
446 | * | ||
447 | * Use this to remove a SOCKS proxy from the proxy list by directly deleting the object given. | ||
448 | * @param ecs The proxy object to delete | ||
449 | * @warning Be aware that deleting a proxy which is being used WILL ruin your life. | ||
450 | * @since 1.2 | ||
451 | */ | ||
452 | EAPI void | ||
453 | ecore_con_socks_remote_del(Ecore_Con_Socks *ecs) | ||
454 | { | ||
455 | EINA_SAFETY_ON_NULL_RETURN(ecs); | ||
456 | if (!ecore_con_socks_proxies) return; | ||
457 | |||
458 | ecore_con_socks_proxies = eina_list_remove(ecore_con_socks_proxies, ecs); | ||
459 | _ecore_con_socks_free(ecs); | ||
460 | } | ||
461 | |||
462 | /** | ||
463 | * Set a proxy object to be used with the next server created with ecore_con_server_connect() | ||
464 | * | ||
465 | * This function sets a proxy for the next ecore_con connection. After the next server is created, | ||
466 | * the proxy will NEVER be applied again unless explicitly enabled. | ||
467 | * @param ecs The proxy object | ||
468 | * @see ecore_con_socks_apply_always() | ||
469 | * @since 1.2 | ||
470 | */ | ||
471 | EAPI void | ||
472 | ecore_con_socks_apply_once(Ecore_Con_Socks *ecs) | ||
473 | { | ||
474 | _ecore_con_proxy_once = ecs; | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Set a proxy object to be used with all servers created with ecore_con_server_connect() | ||
479 | * | ||
480 | * This function sets a proxy for all ecore_con connections. It will always be used. | ||
481 | * @param ecs The proxy object | ||
482 | * @see ecore_con_socks_apply_once() | ||
483 | * @since 1.2 | ||
484 | * @note ecore-con supports setting this through environment variables like so: | ||
485 | * ECORE_CON_SOCKS_V4=[user@]server:port:lookup | ||
486 | * user is the OPTIONAL string that would be passed to the proxy as the username | ||
487 | * server is the IP_ADDRESS of the proxy server | ||
488 | * port is the port to connect to on the proxy server | ||
489 | * lookup is 1 if the proxy should perform all DNS lookups, otherwise 0 or omitted | ||
490 | */ | ||
491 | EAPI void | ||
492 | ecore_con_socks_apply_always(Ecore_Con_Socks *ecs) | ||
493 | { | ||
494 | _ecore_con_proxy_global = ecs; | ||
495 | } | ||
496 | /** @} */ | ||