aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_con
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-23 23:30:42 +1000
committerDavid Walter Seikel2012-01-23 23:30:42 +1000
commit825a3d837a33f226c879cd02ad15c3fba57e8b2c (patch)
tree75f57bd9c4253508d338dc79ba8e57a7abc42255 /libraries/ecore/src/lib/ecore_con
parentAdd ability to disable the test harness, or the Lua compile test. (diff)
downloadSledjHamr-825a3d837a33f226c879cd02ad15c3fba57e8b2c.zip
SledjHamr-825a3d837a33f226c879cd02ad15c3fba57e8b2c.tar.gz
SledjHamr-825a3d837a33f226c879cd02ad15c3fba57e8b2c.tar.bz2
SledjHamr-825a3d837a33f226c879cd02ad15c3fba57e8b2c.tar.xz
Update the EFL to what I'm actually using, coz I'm using some stuff not yet released.
Diffstat (limited to '')
-rw-r--r--libraries/ecore/src/lib/ecore_con/Ecore_Con.h124
-rw-r--r--libraries/ecore/src/lib/ecore_con/Makefile.am1
-rw-r--r--libraries/ecore/src/lib/ecore_con/Makefile.in38
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con.c646
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c4
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_ares.c14
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_info.c9
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c29
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_private.h101
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_socks.c496
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c471
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_url.c734
-rw-r--r--libraries/ecore/src/lib/ecore_config/Makefile.in14
13 files changed, 1871 insertions, 810 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/Ecore_Con.h b/libraries/ecore/src/lib/ecore_con/Ecore_Con.h
index e3b68c4..c3af46a 100644
--- a/libraries/ecore/src/lib/ecore_con/Ecore_Con.h
+++ b/libraries/ecore/src/lib/ecore_con/Ecore_Con.h
@@ -234,6 +234,14 @@ typedef struct _Ecore_Con_Server Ecore_Con_Server;
234typedef struct _Ecore_Con_Client Ecore_Con_Client; 234typedef struct _Ecore_Con_Client Ecore_Con_Client;
235 235
236/** 236/**
237 * @typedef Ecore_Con_Socks
238 * An object representing a SOCKS proxy
239 * @ingroup Ecore_Con_Socks_Group
240 * @since 1.2
241 */
242typedef struct Ecore_Con_Socks Ecore_Con_Socks;
243
244/**
237 * @typedef Ecore_Con_Url 245 * @typedef Ecore_Con_Url
238 * A handle to an http upload/download object 246 * A handle to an http upload/download object
239 * @ingroup Ecore_Con_Url_Group 247 * @ingroup Ecore_Con_Url_Group
@@ -325,6 +333,13 @@ typedef struct _Ecore_Con_Event_Client_Write Ecore_Con_Event_Client_Write;
325typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write; 333typedef struct _Ecore_Con_Event_Server_Write Ecore_Con_Event_Server_Write;
326 334
327/** 335/**
336 * @typedef Ecore_Con_Event_Proxy_Bind
337 * Used as the @p data param for the corresponding event
338 * @since 1.2
339 */
340typedef struct _Ecore_Con_Event_Proxy_Bind Ecore_Con_Event_Proxy_Bind;
341
342/**
328 * @typedef Ecore_Con_Event_Url_Data 343 * @typedef Ecore_Con_Event_Url_Data
329 * Used as the @p data param for the corresponding event 344 * Used as the @p data param for the corresponding event
330 * @ingroup Ecore_Con_Url_Group 345 * @ingroup Ecore_Con_Url_Group
@@ -464,6 +479,19 @@ struct _Ecore_Con_Event_Server_Write
464}; 479};
465 480
466/** 481/**
482 * @struct _Ecore_Con_Event_Proxy_Bind
483 * Used as the @p data param for the @ref ECORE_CON_EVENT_PROXY_BIND event
484 * @ingroup Ecore_Con_Socks_Group
485 * @since 1.2
486 */
487struct _Ecore_Con_Event_Proxy_Bind
488{
489 Ecore_Con_Server *server; /**< the server object connected to the proxy */
490 const char *ip; /**< the proxy-bound ip address */
491 int port; /**< the proxy-bound port */
492};
493
494/**
467 * @struct _Ecore_Con_Event_Url_Data 495 * @struct _Ecore_Con_Event_Url_Data
468 * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event 496 * Used as the @p data param for the @ref ECORE_CON_EVENT_URL_DATA event
469 * @ingroup Ecore_Con_Url_Group 497 * @ingroup Ecore_Con_Url_Group
@@ -542,6 +570,10 @@ EAPI extern int ECORE_CON_EVENT_SERVER_WRITE;
542EAPI extern int ECORE_CON_EVENT_CLIENT_DATA; 570EAPI extern int ECORE_CON_EVENT_CLIENT_DATA;
543/** A server connection object has data */ 571/** A server connection object has data */
544EAPI extern int ECORE_CON_EVENT_SERVER_DATA; 572EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
573/** A server connection has successfully negotiated an ip:port binding
574 * @since 1.2
575 */
576EAPI extern int ECORE_CON_EVENT_PROXY_BIND;
545/** A URL object has data */ 577/** A URL object has data */
546EAPI extern int ECORE_CON_EVENT_URL_DATA; 578EAPI extern int ECORE_CON_EVENT_URL_DATA;
547/** A URL object has completed its transfer to and from the server and can be reused */ 579/** A URL object has completed its transfer to and from the server and can be reused */
@@ -605,7 +637,13 @@ typedef enum _Ecore_Con_Type
605 ECORE_CON_REMOTE_UDP = 5, 637 ECORE_CON_REMOTE_UDP = 5,
606 /** Remote broadcast using UDP */ 638 /** Remote broadcast using UDP */
607 ECORE_CON_REMOTE_BROADCAST = 6, 639 ECORE_CON_REMOTE_BROADCAST = 6,
640 /** Remote connection sending packets immediately */
608 ECORE_CON_REMOTE_NODELAY = 7, 641 ECORE_CON_REMOTE_NODELAY = 7,
642 /** Remote connection sending data in large chunks
643 * @note Only available on Linux
644 * @since 1.2
645 */
646 ECORE_CON_REMOTE_CORK = 8,
609 /** Use SSL2: UNSUPPORTED. **/ 647 /** Use SSL2: UNSUPPORTED. **/
610 ECORE_CON_USE_SSL2 = (1 << 4), 648 ECORE_CON_USE_SSL2 = (1 << 4),
611 /** Use SSL3 */ 649 /** Use SSL3 */
@@ -675,6 +713,8 @@ EAPI Eina_Bool ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr, const
675EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file); 713EAPI Eina_Bool ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr, const char *ca_file);
676EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr); 714EAPI void ecore_con_ssl_server_verify(Ecore_Con_Server *svr);
677EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr); 715EAPI void ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr);
716EAPI void ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name);
717EAPI const char *ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr);
678EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type); 718EAPI Eina_Bool ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type compl_type);
679EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type); 719EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type compl_type);
680 720
@@ -682,6 +722,18 @@ EAPI Eina_Bool ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_
682 * @} 722 * @}
683 */ 723 */
684 724
725EAPI Ecore_Con_Socks *ecore_con_socks4_remote_add(const char *ip, int port, const char *username);
726EAPI void ecore_con_socks4_lookup_set(Ecore_Con_Socks *ecs, Eina_Bool enable);
727EAPI Eina_Bool ecore_con_socks4_lookup_get(Ecore_Con_Socks *ecs);
728EAPI Eina_Bool ecore_con_socks4_remote_exists(const char *ip, int port, const char *username);
729EAPI void ecore_con_socks4_remote_del(const char *ip, int port, const char *username);
730EAPI void ecore_con_socks_bind_set(Ecore_Con_Socks *ecs, Eina_Bool is_bind);
731EAPI Eina_Bool ecore_con_socks_bind_get(Ecore_Con_Socks *ecs);
732EAPI unsigned int ecore_con_socks_version_get(Ecore_Con_Socks *ecs);
733EAPI void ecore_con_socks_remote_del(Ecore_Con_Socks *ecs);
734EAPI void ecore_con_socks_apply_once(Ecore_Con_Socks *ecs);
735EAPI void ecore_con_socks_apply_always(Ecore_Con_Socks *ecs);
736
685/** 737/**
686 * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions 738 * @defgroup Ecore_Con_Server_Group Ecore Connection Server Functions
687 * 739 *
@@ -1185,6 +1237,8 @@ EAPI Eina_Bool ecore_con_client_connected_get(Ecore_Con_Client *cl);
1185 */ 1237 */
1186EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl); 1238EAPI int ecore_con_client_port_get(Ecore_Con_Client *cl);
1187 1239
1240
1241
1188/** 1242/**
1189 * @} 1243 * @}
1190 */ 1244 */
@@ -1583,7 +1637,7 @@ EAPI Eina_Bool ecore_con_url_post(Ecore_Con_Url *url_con,
1583 * modification time. 1637 * modification time.
1584 * 1638 *
1585 * @param url_con Ecore_Con_Url to act upon. 1639 * @param url_con Ecore_Con_Url to act upon.
1586 * @param condition Condition to use for HTTP requests. 1640 * @param time_condition Condition to use for HTTP requests.
1587 * @param timestamp Time since 1 Jan 1970 to use in the condition. 1641 * @param timestamp Time since 1 Jan 1970 to use in the condition.
1588 * 1642 *
1589 * This function may set the header "If-Modified-Since" or 1643 * This function may set the header "If-Modified-Since" or
@@ -1791,6 +1845,74 @@ EAPI int ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con,
1791 const char *ca_path); 1845 const char *ca_path);
1792 1846
1793/** 1847/**
1848 * Set HTTP proxy to use.
1849 *
1850 * The parameter should be a char * to a zero terminated string holding
1851 * the host name or dotted IP address. To specify port number in this string,
1852 * append :[port] to the end of the host name.
1853 * The proxy string may be prefixed with [protocol]:// since any such prefix
1854 * will be ignored.
1855 * The proxy's port number may optionally be specified with the separate option.
1856 * If not specified, libcurl will default to using port 1080 for proxies.
1857 *
1858 * @param url_con Connection object that will use the proxy.
1859 * @param proxy Porxy string or @c NULL to disable
1860 *
1861 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1862 * @since 1.2
1863 */
1864EAPI Eina_Bool ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy);
1865
1866/**
1867 * Set zero terminated username to use for proxy.
1868 *
1869 * if socks protocol is used for proxy, protocol should be socks5 and above.
1870 *
1871 * @param url_con Connection object that will use the proxy.
1872 * @param username Username string.
1873 *
1874 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1875 *
1876 * @see ecore_con_url_proxy_set()
1877 *
1878 * @since 1.2
1879 */
1880EAPI Eina_Bool ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username);
1881
1882/**
1883 * Set zero terminated password to use for proxy.
1884 *
1885 * if socks protocol is used for proxy, protocol should be socks5 and above.
1886 *
1887 * @param url_con Connection object that will use the proxy.
1888 * @param password Password string.
1889 *
1890 * @return #EINA_TRUE on success, #EINA_FALSE on error.
1891 *
1892 * @see ecore_con_url_proxy_set()
1893 *
1894 * @since 1.2
1895 */
1896EAPI Eina_Bool ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password);
1897
1898/**
1899 * Set timeout in seconds.
1900 *
1901 * the maximum time in seconds that you allow the ecore con url transfer
1902 * operation to take. Normally, name lookups can take a considerable time
1903 * and limiting operations to less than a few minutes risk aborting perfectly
1904 * normal operations.
1905 *
1906 * @param url_con Connection object that will use the timeout.
1907 * @param timeout time in seconds.
1908 *
1909 * @see ecore_con_url_cookies_jar_file_set()
1910 *
1911 * @since 1.2
1912 */
1913EAPI void ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout);
1914
1915/**
1794 * @} 1916 * @}
1795 */ 1917 */
1796 1918
diff --git a/libraries/ecore/src/lib/ecore_con/Makefile.am b/libraries/ecore/src/lib/ecore_con/Makefile.am
index 300586d..929b30e 100644
--- a/libraries/ecore/src/lib/ecore_con/Makefile.am
+++ b/libraries/ecore/src/lib/ecore_con/Makefile.am
@@ -19,6 +19,7 @@ includesdir = $(includedir)/ecore-@VMAJ@
19 19
20libecore_con_la_SOURCES = \ 20libecore_con_la_SOURCES = \
21ecore_con.c \ 21ecore_con.c \
22ecore_con_socks.c \
22ecore_con_ssl.c \ 23ecore_con_ssl.c \
23ecore_con_url.c \ 24ecore_con_url.c \
24ecore_con_alloc.c 25ecore_con_alloc.c
diff --git a/libraries/ecore/src/lib/ecore_con/Makefile.in b/libraries/ecore/src/lib/ecore_con/Makefile.in
index 5940a83..58811da 100644
--- a/libraries/ecore/src/lib/ecore_con/Makefile.in
+++ b/libraries/ecore/src/lib/ecore_con/Makefile.in
@@ -92,15 +92,17 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"
92LTLIBRARIES = $(lib_LTLIBRARIES) 92LTLIBRARIES = $(lib_LTLIBRARIES)
93libecore_con_la_DEPENDENCIES = \ 93libecore_con_la_DEPENDENCIES = \
94 $(top_builddir)/src/lib/ecore/libecore.la 94 $(top_builddir)/src/lib/ecore/libecore.la
95am__libecore_con_la_SOURCES_DIST = ecore_con.c ecore_con_ssl.c \ 95am__libecore_con_la_SOURCES_DIST = ecore_con.c ecore_con_socks.c \
96 ecore_con_url.c ecore_con_alloc.c ecore_con_local_win32.c \ 96 ecore_con_ssl.c ecore_con_url.c ecore_con_alloc.c \
97 ecore_con_local.c ecore_con_ares.c ecore_con_info.c 97 ecore_con_local_win32.c ecore_con_local.c ecore_con_ares.c \
98 ecore_con_info.c
98@ECORE_HAVE_WIN32_TRUE@am__objects_1 = libecore_con_la-ecore_con_local_win32.lo 99@ECORE_HAVE_WIN32_TRUE@am__objects_1 = libecore_con_la-ecore_con_local_win32.lo
99@ECORE_HAVE_WIN32_FALSE@am__objects_2 = \ 100@ECORE_HAVE_WIN32_FALSE@am__objects_2 = \
100@ECORE_HAVE_WIN32_FALSE@ libecore_con_la-ecore_con_local.lo 101@ECORE_HAVE_WIN32_FALSE@ libecore_con_la-ecore_con_local.lo
101@HAVE_CARES_TRUE@am__objects_3 = libecore_con_la-ecore_con_ares.lo 102@HAVE_CARES_TRUE@am__objects_3 = libecore_con_la-ecore_con_ares.lo
102@HAVE_CARES_FALSE@am__objects_4 = libecore_con_la-ecore_con_info.lo 103@HAVE_CARES_FALSE@am__objects_4 = libecore_con_la-ecore_con_info.lo
103am_libecore_con_la_OBJECTS = libecore_con_la-ecore_con.lo \ 104am_libecore_con_la_OBJECTS = libecore_con_la-ecore_con.lo \
105 libecore_con_la-ecore_con_socks.lo \
104 libecore_con_la-ecore_con_ssl.lo \ 106 libecore_con_la-ecore_con_ssl.lo \
105 libecore_con_la-ecore_con_url.lo \ 107 libecore_con_la-ecore_con_url.lo \
106 libecore_con_la-ecore_con_alloc.lo $(am__objects_1) \ 108 libecore_con_la-ecore_con_alloc.lo $(am__objects_1) \
@@ -263,10 +265,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
263PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ 265PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
264PIXMAN_LIBS = @PIXMAN_LIBS@ 266PIXMAN_LIBS = @PIXMAN_LIBS@
265PKG_CONFIG = @PKG_CONFIG@ 267PKG_CONFIG = @PKG_CONFIG@
266PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
267PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
268POSUB = @POSUB@ 268POSUB = @POSUB@
269RANLIB = @RANLIB@ 269RANLIB = @RANLIB@
270SCIM_CFLAGS = @SCIM_CFLAGS@
271SCIM_LIBS = @SCIM_LIBS@
270SDL_CFLAGS = @SDL_CFLAGS@ 272SDL_CFLAGS = @SDL_CFLAGS@
271SDL_CONFIG = @SDL_CONFIG@ 273SDL_CONFIG = @SDL_CONFIG@
272SDL_LIBS = @SDL_LIBS@ 274SDL_LIBS = @SDL_LIBS@
@@ -285,6 +287,10 @@ TSLIB_LIBS = @TSLIB_LIBS@
285USE_NLS = @USE_NLS@ 287USE_NLS = @USE_NLS@
286VERSION = @VERSION@ 288VERSION = @VERSION@
287VMAJ = @VMAJ@ 289VMAJ = @VMAJ@
290WAYLAND_CFLAGS = @WAYLAND_CFLAGS@
291WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@
292WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@
293WAYLAND_LIBS = @WAYLAND_LIBS@
288WIN32_CFLAGS = @WIN32_CFLAGS@ 294WIN32_CFLAGS = @WIN32_CFLAGS@
289WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ 295WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
290WIN32_LIBS = @WIN32_LIBS@ 296WIN32_LIBS = @WIN32_LIBS@
@@ -398,6 +404,8 @@ ecore_imf_cflags = @ecore_imf_cflags@
398ecore_imf_evas_cflags = @ecore_imf_evas_cflags@ 404ecore_imf_evas_cflags = @ecore_imf_evas_cflags@
399ecore_imf_evas_libs = @ecore_imf_evas_libs@ 405ecore_imf_evas_libs = @ecore_imf_evas_libs@
400ecore_imf_libs = @ecore_imf_libs@ 406ecore_imf_libs = @ecore_imf_libs@
407ecore_imf_scim_cflags = @ecore_imf_scim_cflags@
408ecore_imf_scim_libs = @ecore_imf_scim_libs@
401ecore_imf_xim_cflags = @ecore_imf_xim_cflags@ 409ecore_imf_xim_cflags = @ecore_imf_xim_cflags@
402ecore_imf_xim_libs = @ecore_imf_xim_libs@ 410ecore_imf_xim_libs = @ecore_imf_xim_libs@
403ecore_input_cflags = @ecore_input_cflags@ 411ecore_input_cflags = @ecore_input_cflags@
@@ -410,6 +418,8 @@ ecore_psl1ght_cflags = @ecore_psl1ght_cflags@
410ecore_psl1ght_libs = @ecore_psl1ght_libs@ 418ecore_psl1ght_libs = @ecore_psl1ght_libs@
411ecore_sdl_cflags = @ecore_sdl_cflags@ 419ecore_sdl_cflags = @ecore_sdl_cflags@
412ecore_sdl_libs = @ecore_sdl_libs@ 420ecore_sdl_libs = @ecore_sdl_libs@
421ecore_wayland_cflags = @ecore_wayland_cflags@
422ecore_wayland_libs = @ecore_wayland_libs@
413ecore_win32_cflags = @ecore_win32_cflags@ 423ecore_win32_cflags = @ecore_win32_cflags@
414ecore_win32_libs = @ecore_win32_libs@ 424ecore_win32_libs = @ecore_win32_libs@
415ecore_wince_cflags = @ecore_wince_cflags@ 425ecore_wince_cflags = @ecore_wince_cflags@
@@ -454,12 +464,14 @@ requirements_ecore_fb = @requirements_ecore_fb@
454requirements_ecore_file = @requirements_ecore_file@ 464requirements_ecore_file = @requirements_ecore_file@
455requirements_ecore_imf = @requirements_ecore_imf@ 465requirements_ecore_imf = @requirements_ecore_imf@
456requirements_ecore_imf_evas = @requirements_ecore_imf_evas@ 466requirements_ecore_imf_evas = @requirements_ecore_imf_evas@
467requirements_ecore_imf_scim = @requirements_ecore_imf_scim@
457requirements_ecore_imf_xim = @requirements_ecore_imf_xim@ 468requirements_ecore_imf_xim = @requirements_ecore_imf_xim@
458requirements_ecore_input = @requirements_ecore_input@ 469requirements_ecore_input = @requirements_ecore_input@
459requirements_ecore_input_evas = @requirements_ecore_input_evas@ 470requirements_ecore_input_evas = @requirements_ecore_input_evas@
460requirements_ecore_ipc = @requirements_ecore_ipc@ 471requirements_ecore_ipc = @requirements_ecore_ipc@
461requirements_ecore_psl1ght = @requirements_ecore_psl1ght@ 472requirements_ecore_psl1ght = @requirements_ecore_psl1ght@
462requirements_ecore_sdl = @requirements_ecore_sdl@ 473requirements_ecore_sdl = @requirements_ecore_sdl@
474requirements_ecore_wayland = @requirements_ecore_wayland@
463requirements_ecore_win32 = @requirements_ecore_win32@ 475requirements_ecore_win32 = @requirements_ecore_win32@
464requirements_ecore_wince = @requirements_ecore_wince@ 476requirements_ecore_wince = @requirements_ecore_wince@
465requirements_ecore_x = @requirements_ecore_x@ 477requirements_ecore_x = @requirements_ecore_x@
@@ -493,9 +505,10 @@ AM_CPPFLAGS = \
493lib_LTLIBRARIES = libecore_con.la 505lib_LTLIBRARIES = libecore_con.la
494includes_HEADERS = Ecore_Con.h 506includes_HEADERS = Ecore_Con.h
495includesdir = $(includedir)/ecore-@VMAJ@ 507includesdir = $(includedir)/ecore-@VMAJ@
496libecore_con_la_SOURCES = ecore_con.c ecore_con_ssl.c ecore_con_url.c \ 508libecore_con_la_SOURCES = ecore_con.c ecore_con_socks.c \
497 ecore_con_alloc.c $(am__append_1) $(am__append_2) \ 509 ecore_con_ssl.c ecore_con_url.c ecore_con_alloc.c \
498 $(am__append_3) $(am__append_4) 510 $(am__append_1) $(am__append_2) $(am__append_3) \
511 $(am__append_4)
499libecore_con_la_CFLAGS = @WIN32_CFLAGS@ 512libecore_con_la_CFLAGS = @WIN32_CFLAGS@
500libecore_con_la_LIBADD = \ 513libecore_con_la_LIBADD = \
501$(top_builddir)/src/lib/ecore/libecore.la \ 514$(top_builddir)/src/lib/ecore/libecore.la \
@@ -583,6 +596,7 @@ distclean-compile:
583@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_info.Plo@am__quote@ 596@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_info.Plo@am__quote@
584@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local.Plo@am__quote@ 597@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local.Plo@am__quote@
585@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local_win32.Plo@am__quote@ 598@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_local_win32.Plo@am__quote@
599@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_socks.Plo@am__quote@
586@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo@am__quote@ 600@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo@am__quote@
587@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_url.Plo@am__quote@ 601@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecore_con_la-ecore_con_url.Plo@am__quote@
588 602
@@ -618,6 +632,14 @@ libecore_con_la-ecore_con.lo: ecore_con.c
618@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 632@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
619@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con.lo `test -f 'ecore_con.c' || echo '$(srcdir)/'`ecore_con.c 633@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con.lo `test -f 'ecore_con.c' || echo '$(srcdir)/'`ecore_con.c
620 634
635libecore_con_la-ecore_con_socks.lo: ecore_con_socks.c
636@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_socks.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_socks.Tpo -c -o libecore_con_la-ecore_con_socks.lo `test -f 'ecore_con_socks.c' || echo '$(srcdir)/'`ecore_con_socks.c
637@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_socks.Tpo $(DEPDIR)/libecore_con_la-ecore_con_socks.Plo
638@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
639@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ecore_con_socks.c' object='libecore_con_la-ecore_con_socks.lo' libtool=yes @AMDEPBACKSLASH@
640@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
641@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -c -o libecore_con_la-ecore_con_socks.lo `test -f 'ecore_con_socks.c' || echo '$(srcdir)/'`ecore_con_socks.c
642
621libecore_con_la-ecore_con_ssl.lo: ecore_con_ssl.c 643libecore_con_la-ecore_con_ssl.lo: ecore_con_ssl.c
622@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_ssl.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo -c -o libecore_con_la-ecore_con_ssl.lo `test -f 'ecore_con_ssl.c' || echo '$(srcdir)/'`ecore_con_ssl.c 644@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecore_con_la_CFLAGS) $(CFLAGS) -MT libecore_con_la-ecore_con_ssl.lo -MD -MP -MF $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo -c -o libecore_con_la-ecore_con_ssl.lo `test -f 'ecore_con_ssl.c' || echo '$(srcdir)/'`ecore_con_ssl.c
623@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo 645@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecore_con_la-ecore_con_ssl.Tpo $(DEPDIR)/libecore_con_la-ecore_con_ssl.Plo
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con.c b/libraries/ecore/src/lib/ecore_con/ecore_con.c
index 7bd0358..de291b3 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con.c
@@ -45,7 +45,6 @@
45 45
46static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl); 46static Eina_Bool _ecore_con_client_timer(Ecore_Con_Client *cl);
47static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl); 47static void _ecore_con_cl_timer_update(Ecore_Con_Client *cl);
48
49static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr); 48static Eina_Bool _ecore_con_server_timer(Ecore_Con_Server *svr);
50static void _ecore_con_server_timer_update(Ecore_Con_Server *svr); 49static void _ecore_con_server_timer_update(Ecore_Con_Server *svr);
51 50
@@ -104,6 +103,45 @@ static void _ecore_con_lookup_done(void *data,
104 103
105static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr); 104static const char * _ecore_con_pretty_ip(struct sockaddr *client_addr);
106 105
106
107void
108_ecore_con_client_kill(Ecore_Con_Client *cl)
109{
110 if (cl->delete_me)
111 DBG("Multi kill request for client %p", cl);
112 else
113 ecore_con_event_client_del(cl);
114 INF("Lost client %s", (cl->ip) ? cl->ip : "");
115 if (cl->fd_handler)
116 ecore_main_fd_handler_del(cl->fd_handler);
117
118 cl->fd_handler = NULL;
119}
120
121void
122_ecore_con_server_kill(Ecore_Con_Server *svr)
123{
124 if (svr->delete_me)
125 DBG("Multi kill request for svr %p", svr);
126 else
127 ecore_con_event_server_del(svr);
128
129 if (svr->fd_handler)
130 ecore_main_fd_handler_del(svr->fd_handler);
131
132 svr->fd_handler = NULL;
133}
134
135#define _ecore_con_server_kill(svr) do { \
136 DBG("KILL %p", (svr)); \
137 _ecore_con_server_kill((svr)); \
138} while (0)
139
140#define _ecore_con_client_kill(cl) do { \
141 DBG("KILL %p", (cl)); \
142 _ecore_con_client_kill((cl)); \
143} while (0)
144
107EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0; 145EAPI int ECORE_CON_EVENT_CLIENT_ADD = 0;
108EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0; 146EAPI int ECORE_CON_EVENT_CLIENT_DEL = 0;
109EAPI int ECORE_CON_EVENT_SERVER_ADD = 0; 147EAPI int ECORE_CON_EVENT_SERVER_ADD = 0;
@@ -114,11 +152,14 @@ EAPI int ECORE_CON_EVENT_CLIENT_WRITE = 0;
114EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0; 152EAPI int ECORE_CON_EVENT_SERVER_WRITE = 0;
115EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0; 153EAPI int ECORE_CON_EVENT_CLIENT_ERROR = 0;
116EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0; 154EAPI int ECORE_CON_EVENT_SERVER_ERROR = 0;
155EAPI int ECORE_CON_EVENT_PROXY_BIND = 0;
117 156
118static Eina_List *servers = NULL; 157static Eina_List *servers = NULL;
119static int _ecore_con_init_count = 0; 158static int _ecore_con_init_count = 0;
120static int _ecore_con_event_count = 0; 159static int _ecore_con_event_count = 0;
121int _ecore_con_log_dom = -1; 160int _ecore_con_log_dom = -1;
161Ecore_Con_Socks *_ecore_con_proxy_once = NULL;
162Ecore_Con_Socks *_ecore_con_proxy_global = NULL;
122 163
123EAPI int 164EAPI int
124ecore_con_init(void) 165ecore_con_init(void)
@@ -156,6 +197,7 @@ ecore_con_init(void)
156 ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new(); 197 ECORE_CON_EVENT_SERVER_WRITE = ecore_event_type_new();
157 ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new(); 198 ECORE_CON_EVENT_CLIENT_ERROR = ecore_event_type_new();
158 ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new(); 199 ECORE_CON_EVENT_SERVER_ERROR = ecore_event_type_new();
200 ECORE_CON_EVENT_PROXY_BIND = ecore_event_type_new();
159 201
160 202
161 eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server"); 203 eina_magic_string_set(ECORE_MAGIC_CON_SERVER, "Ecore_Con_Server");
@@ -163,6 +205,7 @@ ecore_con_init(void)
163 eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url"); 205 eina_magic_string_set(ECORE_MAGIC_CON_URL, "Ecore_Con_Url");
164 206
165 /* TODO Remember return value, if it fails, use gethostbyname() */ 207 /* TODO Remember return value, if it fails, use gethostbyname() */
208 ecore_con_socks_init();
166 ecore_con_ssl_init(); 209 ecore_con_ssl_init();
167 ecore_con_info_init(); 210 ecore_con_info_init();
168 211
@@ -182,13 +225,15 @@ ecore_con_shutdown(void)
182 { 225 {
183 Ecore_Con_Event_Server_Add *ev; 226 Ecore_Con_Event_Server_Add *ev;
184 227
185 svr->delete_me = svr->dead = EINA_TRUE; 228 svr->delete_me = EINA_TRUE;
229 INF("svr %p is dead", svr);
186 /* some pointer hacks here to prevent double frees if people are being stupid */ 230 /* some pointer hacks here to prevent double frees if people are being stupid */
187 EINA_LIST_FREE(svr->event_count, ev) 231 EINA_LIST_FREE(svr->event_count, ev)
188 ev->server = NULL; 232 ev->server = NULL;
189 _ecore_con_server_free(svr); 233 _ecore_con_server_free(svr);
190 } 234 }
191 235
236 ecore_con_socks_shutdown();
192 if (!_ecore_con_event_count) ecore_con_mempool_shutdown(); 237 if (!_ecore_con_event_count) ecore_con_mempool_shutdown();
193 238
194 ecore_con_info_shutdown(); 239 ecore_con_info_shutdown();
@@ -301,8 +346,7 @@ ecore_con_server_add(Ecore_Con_Type compl_type,
301 svr->port = port; 346 svr->port = port;
302 svr->data = (void *)data; 347 svr->data = (void *)data;
303 svr->created = EINA_TRUE; 348 svr->created = EINA_TRUE;
304 if (compl_type & ECORE_CON_LOAD_CERT) 349 svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
305 svr->use_cert = EINA_TRUE;
306 svr->reject_excess_clients = EINA_FALSE; 350 svr->reject_excess_clients = EINA_FALSE;
307 svr->client_limit = -1; 351 svr->client_limit = -1;
308 svr->clients = NULL; 352 svr->clients = NULL;
@@ -325,7 +369,8 @@ ecore_con_server_add(Ecore_Con_Type compl_type,
325#endif 369#endif
326 370
327 if ((type == ECORE_CON_REMOTE_TCP) || 371 if ((type == ECORE_CON_REMOTE_TCP) ||
328 (type == ECORE_CON_REMOTE_NODELAY)) 372 (type == ECORE_CON_REMOTE_NODELAY) ||
373 (type == ECORE_CON_REMOTE_CORK))
329 { 374 {
330 /* TCP */ 375 /* TCP */
331 if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen, 376 if (!ecore_con_info_tcp_listen(svr, _ecore_con_cb_tcp_listen,
@@ -395,17 +440,36 @@ ecore_con_server_connect(Ecore_Con_Type compl_type,
395 svr->port = port; 440 svr->port = port;
396 svr->data = (void *)data; 441 svr->data = (void *)data;
397 svr->created = EINA_FALSE; 442 svr->created = EINA_FALSE;
398 svr->use_cert = (compl_type & ECORE_CON_LOAD_CERT); 443 svr->use_cert = (compl_type & ECORE_CON_SSL & ECORE_CON_LOAD_CERT) == ECORE_CON_LOAD_CERT;
399 svr->reject_excess_clients = EINA_FALSE; 444 svr->reject_excess_clients = EINA_FALSE;
400 svr->clients = NULL; 445 svr->clients = NULL;
401 svr->client_limit = -1; 446 svr->client_limit = -1;
402 if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL))
403 goto error;
404 447
405 type = compl_type & ECORE_CON_TYPE; 448 type = compl_type & ECORE_CON_TYPE;
406 449
450 if (type > ECORE_CON_LOCAL_ABSTRACT)
451 {
452 /* never use proxies on local connections */
453 if (_ecore_con_proxy_once)
454 svr->ecs = _ecore_con_proxy_once;
455 else if (_ecore_con_proxy_global)
456 svr->ecs = _ecore_con_proxy_global;
457 _ecore_con_proxy_once = NULL;
458 if (svr->ecs)
459 {
460 if ((!svr->ecs->lookup) &&
461 (!ecore_con_lookup(svr->name, (Ecore_Con_Dns_Cb)ecore_con_socks_dns_cb, svr)))
462 goto error;
463 if (svr->ecs->lookup)
464 svr->ecs_state = ECORE_CON_SOCKS_STATE_RESOLVED;
465 }
466 }
467 if (ecore_con_ssl_server_prepare(svr, compl_type & ECORE_CON_SSL))
468 goto error;
469
407 if (((type == ECORE_CON_REMOTE_TCP) || 470 if (((type == ECORE_CON_REMOTE_TCP) ||
408 (type == ECORE_CON_REMOTE_NODELAY) || 471 (type == ECORE_CON_REMOTE_NODELAY) ||
472 (type == ECORE_CON_REMOTE_CORK) ||
409 (type == ECORE_CON_REMOTE_UDP) || 473 (type == ECORE_CON_REMOTE_UDP) ||
410 (type == ECORE_CON_REMOTE_BROADCAST)) && 474 (type == ECORE_CON_REMOTE_BROADCAST)) &&
411 (port < 0)) 475 (port < 0))
@@ -424,7 +488,8 @@ ecore_con_server_connect(Ecore_Con_Type compl_type,
424#endif 488#endif
425 489
426 if ((type == ECORE_CON_REMOTE_TCP) || 490 if ((type == ECORE_CON_REMOTE_TCP) ||
427 (type == ECORE_CON_REMOTE_NODELAY)) 491 (type == ECORE_CON_REMOTE_NODELAY) ||
492 (type == ECORE_CON_REMOTE_CORK))
428 { 493 {
429 /* TCP */ 494 /* TCP */
430 if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect, 495 if (!ecore_con_info_tcp_connect(svr, _ecore_con_cb_tcp_connect,
@@ -492,8 +557,6 @@ ecore_con_server_timeout_get(Ecore_Con_Server *svr)
492EAPI void * 557EAPI void *
493ecore_con_server_del(Ecore_Con_Server *svr) 558ecore_con_server_del(Ecore_Con_Server *svr)
494{ 559{
495 void *data;
496
497 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) 560 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
498 { 561 {
499 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del"); 562 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_del");
@@ -503,20 +566,8 @@ ecore_con_server_del(Ecore_Con_Server *svr)
503 if (svr->delete_me) 566 if (svr->delete_me)
504 return NULL; 567 return NULL;
505 568
506 data = svr->data; 569 _ecore_con_server_kill(svr);
507 svr->delete_me = EINA_TRUE; 570 return svr->data;
508 if (svr->event_count)
509 {
510 if (svr->fd_handler)
511 {
512 ecore_main_fd_handler_del(svr->fd_handler);
513 svr->fd_handler = NULL;
514 }
515 }
516 else
517 _ecore_con_server_free(svr);
518
519 return data;
520} 571}
521 572
522EAPI void * 573EAPI void *
@@ -524,9 +575,7 @@ ecore_con_server_data_get(Ecore_Con_Server *svr)
524{ 575{
525 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) 576 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
526 { 577 {
527 ECORE_MAGIC_FAIL(svr, 578 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
528 ECORE_MAGIC_CON_SERVER,
529 "ecore_con_server_data_get");
530 return NULL; 579 return NULL;
531 } 580 }
532 581
@@ -541,9 +590,7 @@ ecore_con_server_data_set(Ecore_Con_Server *svr,
541 590
542 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) 591 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
543 { 592 {
544 ECORE_MAGIC_FAIL(svr, 593 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_data_get");
545 ECORE_MAGIC_CON_SERVER,
546 "ecore_con_server_data_get");
547 return NULL; 594 return NULL;
548 } 595 }
549 596
@@ -557,8 +604,7 @@ ecore_con_server_connected_get(Ecore_Con_Server *svr)
557{ 604{
558 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER)) 605 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
559 { 606 {
560 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, 607 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, "ecore_con_server_connected_get");
561 "ecore_con_server_connected_get");
562 return EINA_FALSE; 608 return EINA_FALSE;
563 } 609 }
564 610
@@ -617,7 +663,7 @@ ecore_con_server_send(Ecore_Con_Server *svr,
617 return 0; 663 return 0;
618 } 664 }
619 665
620 EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->dead, 0); 666 EINA_SAFETY_ON_TRUE_RETURN_VAL(svr->delete_me, 0);
621 667
622 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); 668 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
623 669
@@ -630,6 +676,15 @@ ecore_con_server_send(Ecore_Con_Server *svr,
630 { 676 {
631 svr->buf = eina_binbuf_new(); 677 svr->buf = eina_binbuf_new();
632 EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0); 678 EINA_SAFETY_ON_NULL_RETURN_VAL(svr->buf, 0);
679#ifdef TCP_CORK
680 if ((svr->fd >= 0) && ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
681 {
682 int state = 1;
683 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
684 /* realistically this isn't anything serious so we can just log and continue */
685 ERR("corking failed! %s", strerror(errno));
686 }
687#endif
633 } 688 }
634 eina_binbuf_append_length(svr->buf, data, size); 689 eina_binbuf_append_length(svr->buf, data, size);
635 690
@@ -716,7 +771,7 @@ ecore_con_client_send(Ecore_Con_Client *cl,
716 return 0; 771 return 0;
717 } 772 }
718 773
719 EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->dead, 0); 774 EINA_SAFETY_ON_TRUE_RETURN_VAL(cl->delete_me, 0);
720 775
721 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); 776 EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0);
722 777
@@ -732,6 +787,15 @@ ecore_con_client_send(Ecore_Con_Client *cl,
732 { 787 {
733 cl->buf = eina_binbuf_new(); 788 cl->buf = eina_binbuf_new();
734 EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0); 789 EINA_SAFETY_ON_NULL_RETURN_VAL(cl->buf, 0);
790#ifdef TCP_CORK
791 if ((cl->fd >= 0) && ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK))
792 {
793 int state = 1;
794 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
795 /* realistically this isn't anything serious so we can just log and continue */
796 ERR("corking failed! %s", strerror(errno));
797 }
798#endif
735 } 799 }
736 eina_binbuf_append_length(cl->buf, data, size); 800 eina_binbuf_append_length(cl->buf, data, size);
737 801
@@ -761,7 +825,7 @@ ecore_con_client_connected_get(Ecore_Con_Client *cl)
761 return EINA_FALSE; 825 return EINA_FALSE;
762 } 826 }
763 827
764 return !cl->dead; 828 return !cl->delete_me;
765} 829}
766 830
767EAPI void 831EAPI void
@@ -795,36 +859,14 @@ ecore_con_client_timeout_get(Ecore_Con_Client *cl)
795EAPI void * 859EAPI void *
796ecore_con_client_del(Ecore_Con_Client *cl) 860ecore_con_client_del(Ecore_Con_Client *cl)
797{ 861{
798 void *data = NULL;
799
800 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) 862 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
801 { 863 {
802 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del"); 864 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_del");
803 return NULL; 865 return NULL;
804 } 866 }
805 867
806 data = cl->data; 868 _ecore_con_client_kill(cl);
807 cl->delete_me = EINA_TRUE; 869 return cl->data;
808 if (cl->event_count)
809 {
810 if (cl->fd_handler)
811 {
812 ecore_main_fd_handler_del(cl->fd_handler);
813 cl->fd_handler = NULL;
814 }
815 }
816 else
817 {
818 if (cl->host_server)
819 {
820 cl->host_server->clients = eina_list_remove(cl->host_server->clients, cl);
821 --cl->host_server->client_count;
822 }
823
824 _ecore_con_client_free(cl);
825 }
826
827 return data;
828} 870}
829 871
830EAPI void 872EAPI void
@@ -833,9 +875,7 @@ ecore_con_client_data_set(Ecore_Con_Client *cl,
833{ 875{
834 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) 876 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
835 { 877 {
836 ECORE_MAGIC_FAIL(cl, 878 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_set");
837 ECORE_MAGIC_CON_CLIENT,
838 "ecore_con_client_data_set");
839 return; 879 return;
840 } 880 }
841 881
@@ -847,9 +887,7 @@ ecore_con_client_data_get(Ecore_Con_Client *cl)
847{ 887{
848 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT)) 888 if (!ECORE_MAGIC_CHECK(cl, ECORE_MAGIC_CON_CLIENT))
849 { 889 {
850 ECORE_MAGIC_FAIL(cl, 890 ECORE_MAGIC_FAIL(cl, ECORE_MAGIC_CON_CLIENT, "ecore_con_client_data_get");
851 ECORE_MAGIC_CON_CLIENT,
852 "ecore_con_client_data_get");
853 return NULL; 891 return NULL;
854 } 892 }
855 893
@@ -939,6 +977,25 @@ ecore_con_client_fd_get(Ecore_Con_Client *cl)
939 */ 977 */
940 978
941void 979void
980ecore_con_event_proxy_bind(Ecore_Con_Server *svr)
981{
982 Ecore_Con_Event_Proxy_Bind *e;
983 int ev = ECORE_CON_EVENT_PROXY_BIND;
984
985 e = ecore_con_event_proxy_bind_alloc();
986 EINA_SAFETY_ON_NULL_RETURN(e);
987
988 svr->event_count = eina_list_append(svr->event_count, e);
989 _ecore_con_server_timer_update(svr);
990 e->server = svr;
991 e->ip = svr->proxyip;
992 e->port = svr->proxyport;
993 ecore_event_add(ev, e,
994 _ecore_con_event_server_add_free, NULL);
995 _ecore_con_event_count++;
996}
997
998void
942ecore_con_event_server_add(Ecore_Con_Server *svr) 999ecore_con_event_server_add(Ecore_Con_Server *svr)
943{ 1000{
944 /* we got our server! */ 1001 /* we got our server! */
@@ -948,6 +1005,8 @@ ecore_con_event_server_add(Ecore_Con_Server *svr)
948 e = ecore_con_event_server_add_alloc(); 1005 e = ecore_con_event_server_add_alloc();
949 EINA_SAFETY_ON_NULL_RETURN(e); 1006 EINA_SAFETY_ON_NULL_RETURN(e);
950 1007
1008 svr->connecting = EINA_FALSE;
1009 svr->start_time = ecore_time_get();
951 svr->event_count = eina_list_append(svr->event_count, e); 1010 svr->event_count = eina_list_append(svr->event_count, e);
952 _ecore_con_server_timer_update(svr); 1011 _ecore_con_server_timer_update(svr);
953 e->server = svr; 1012 e->server = svr;
@@ -962,12 +1021,20 @@ ecore_con_event_server_del(Ecore_Con_Server *svr)
962{ 1021{
963 Ecore_Con_Event_Server_Del *e; 1022 Ecore_Con_Event_Server_Del *e;
964 1023
1024 svr->delete_me = EINA_TRUE;
1025 INF("svr %p is dead", svr);
965 e = ecore_con_event_server_del_alloc(); 1026 e = ecore_con_event_server_del_alloc();
966 EINA_SAFETY_ON_NULL_RETURN(e); 1027 EINA_SAFETY_ON_NULL_RETURN(e);
967 1028
968 svr->event_count = eina_list_append(svr->event_count, e); 1029 svr->event_count = eina_list_append(svr->event_count, e);
969 _ecore_con_server_timer_update(svr); 1030 _ecore_con_server_timer_update(svr);
970 e->server = svr; 1031 e->server = svr;
1032 if (svr->ecs)
1033 {
1034 svr->ecs_state = svr->ecs->lookup ? ECORE_CON_SOCKS_STATE_RESOLVED : ECORE_CON_SOCKS_STATE_DONE;
1035 eina_stringshare_replace(&svr->proxyip, NULL);
1036 svr->proxyport = 0;
1037 }
971 ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e, 1038 ecore_event_add(ECORE_CON_EVENT_SERVER_DEL, e,
972 _ecore_con_event_server_del_free, NULL); 1039 _ecore_con_event_server_del_free, NULL);
973 _ecore_con_event_count++; 1040 _ecore_con_event_count++;
@@ -981,6 +1048,7 @@ ecore_con_event_server_write(Ecore_Con_Server *svr, int num)
981 e = ecore_con_event_server_write_alloc(); 1048 e = ecore_con_event_server_write_alloc();
982 EINA_SAFETY_ON_NULL_RETURN(e); 1049 EINA_SAFETY_ON_NULL_RETURN(e);
983 1050
1051 INF("Wrote %d bytes", num);
984 svr->event_count = eina_list_append(svr->event_count, e); 1052 svr->event_count = eina_list_append(svr->event_count, e);
985 e->server = svr; 1053 e->server = svr;
986 e->size = num; 1054 e->size = num;
@@ -1044,6 +1112,8 @@ ecore_con_event_client_del(Ecore_Con_Client *cl)
1044 Ecore_Con_Event_Client_Del *e; 1112 Ecore_Con_Event_Client_Del *e;
1045 1113
1046 if (!cl) return; 1114 if (!cl) return;
1115 cl->delete_me = EINA_TRUE;
1116 INF("cl %p is dead", cl);
1047 e = ecore_con_event_client_del_alloc(); 1117 e = ecore_con_event_client_del_alloc();
1048 EINA_SAFETY_ON_NULL_RETURN(e); 1118 EINA_SAFETY_ON_NULL_RETURN(e);
1049 cl->event_count = eina_list_append(cl->event_count, e); 1119 cl->event_count = eina_list_append(cl->event_count, e);
@@ -1112,7 +1182,7 @@ ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info)
1112} 1182}
1113 1183
1114void 1184void
1115ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error) 1185_ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate)
1116{ 1186{
1117 Ecore_Con_Event_Server_Error *e; 1187 Ecore_Con_Event_Server_Error *e;
1118 1188
@@ -1120,7 +1190,7 @@ ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error)
1120 EINA_SAFETY_ON_NULL_RETURN(e); 1190 EINA_SAFETY_ON_NULL_RETURN(e);
1121 1191
1122 e->server = svr; 1192 e->server = svr;
1123 e->error = strdup(error); 1193 e->error = duplicate ? strdup(error) : error;
1124 ERR("%s", error); 1194 ERR("%s", error);
1125 svr->event_count = eina_list_append(svr->event_count, e); 1195 svr->event_count = eina_list_append(svr->event_count, e);
1126 ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL); 1196 ecore_event_add(ECORE_CON_EVENT_SERVER_ERROR, e, (Ecore_End_Cb)_ecore_con_event_server_error_free, NULL);
@@ -1157,16 +1227,9 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
1157 ecore_con_info_data_clear(svr->infos->data); 1227 ecore_con_info_data_clear(svr->infos->data);
1158 svr->infos = eina_list_remove_list(svr->infos, svr->infos); 1228 svr->infos = eina_list_remove_list(svr->infos, svr->infos);
1159 } 1229 }
1160 if ((!svr->buf) && svr->delete_me && (!svr->dead) && (!svr->event_count))
1161 {
1162 /* this is a catch-all for cases when a server is not properly killed. */
1163 svr->dead = EINA_TRUE;
1164 ecore_con_event_server_del(svr);
1165 return;
1166 }
1167 1230
1168 t_start = ecore_time_get(); 1231 t_start = ecore_time_get();
1169 while (svr->buf && (!svr->dead)) 1232 while (svr->buf && (!svr->delete_me))
1170 { 1233 {
1171 _ecore_con_server_flush(svr); 1234 _ecore_con_server_flush(svr);
1172 t = ecore_time_get(); 1235 t = ecore_time_get();
@@ -1196,7 +1259,8 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
1196 /* some pointer hacks here to prevent double frees if people are being stupid */ 1259 /* some pointer hacks here to prevent double frees if people are being stupid */
1197 EINA_LIST_FREE(cl->event_count, ev) 1260 EINA_LIST_FREE(cl->event_count, ev)
1198 ev->server = NULL; 1261 ev->server = NULL;
1199 cl->delete_me = cl->dead = EINA_TRUE; 1262 cl->delete_me = EINA_TRUE;
1263 INF("cl %p is dead", cl);
1200 _ecore_con_client_free(cl); 1264 _ecore_con_client_free(cl);
1201 } 1265 }
1202 if ((svr->created) && (svr->path) && (svr->ppid == getpid())) 1266 if ((svr->created) && (svr->path) && (svr->ppid == getpid()))
@@ -1208,6 +1272,10 @@ _ecore_con_server_free(Ecore_Con_Server *svr)
1208 free(svr->path); 1272 free(svr->path);
1209 1273
1210 eina_stringshare_del(svr->ip); 1274 eina_stringshare_del(svr->ip);
1275 eina_stringshare_del(svr->verify_name);
1276
1277 if (svr->ecs_buf) eina_binbuf_free(svr->ecs_buf);
1278 if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
1211 1279
1212 if (svr->fd_handler) 1280 if (svr->fd_handler)
1213 ecore_main_fd_handler_del(svr->fd_handler); 1281 ecore_main_fd_handler_del(svr->fd_handler);
@@ -1230,17 +1298,8 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
1230 1298
1231 if (cl->event_count) return; 1299 if (cl->event_count) return;
1232 1300
1233 if (cl->delete_me && (!cl->dead) && (!cl->event_count))
1234 {
1235 /* this is a catch-all for cases when a client is not properly killed. */
1236 cl->dead = EINA_TRUE;
1237 ecore_con_event_client_del(cl);
1238 return;
1239 }
1240
1241
1242 t_start = ecore_time_get(); 1301 t_start = ecore_time_get();
1243 while ((cl->buf) && (!cl->dead)) 1302 while ((cl->buf) && (!cl->delete_me))
1244 { 1303 {
1245 _ecore_con_client_flush(cl); 1304 _ecore_con_client_flush(cl);
1246 t = ecore_time_get(); 1305 t = ecore_time_get();
@@ -1284,19 +1343,6 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
1284 return; 1343 return;
1285} 1344}
1286 1345
1287static void
1288_ecore_con_server_kill(Ecore_Con_Server *svr)
1289{
1290 if (!svr->delete_me)
1291 ecore_con_event_server_del(svr);
1292
1293 svr->dead = EINA_TRUE;
1294 if (svr->fd_handler)
1295 ecore_main_fd_handler_del(svr->fd_handler);
1296
1297 svr->fd_handler = NULL;
1298}
1299
1300static Eina_Bool 1346static Eina_Bool
1301_ecore_con_server_timer(Ecore_Con_Server *svr) 1347_ecore_con_server_timer(Ecore_Con_Server *svr)
1302{ 1348{
@@ -1384,40 +1430,25 @@ _ecore_con_cb_tcp_listen(void *data,
1384{ 1430{
1385 Ecore_Con_Server *svr; 1431 Ecore_Con_Server *svr;
1386 struct linger lin; 1432 struct linger lin;
1433 const char *memerr = NULL;
1387 1434
1388 svr = data; 1435 svr = data;
1389 1436
1437 errno = 0;
1390 if (!net_info) /* error message has already been handled */ 1438 if (!net_info) /* error message has already been handled */
1391 goto error; 1439 goto error;
1392 1440
1393 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, 1441 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1394 net_info->info.ai_protocol); 1442 net_info->info.ai_protocol);
1395 if (svr->fd < 0) 1443 if (svr->fd < 0) goto error;
1396 { 1444 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1397 ecore_con_event_server_error(svr, strerror(errno)); 1445 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1398 goto error;
1399 }
1400
1401 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
1402 {
1403 ecore_con_event_server_error(svr, strerror(errno));
1404 goto error;
1405 }
1406
1407 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
1408 {
1409 ecore_con_event_server_error(svr, strerror(errno));
1410 goto error;
1411 }
1412 1446
1413 lin.l_onoff = 1; 1447 lin.l_onoff = 1;
1414 lin.l_linger = 0; 1448 lin.l_linger = 0;
1415 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin, 1449 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
1416 sizeof(struct linger)) < 0) 1450 sizeof(struct linger)) < 0)
1417 { 1451 goto error;
1418 ecore_con_event_server_error(svr, strerror(errno));
1419 goto error;
1420 }
1421 1452
1422 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) 1453 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1423 { 1454 {
@@ -1428,34 +1459,27 @@ _ecore_con_cb_tcp_listen(void *data,
1428 sizeof(int)) < 0) 1459 sizeof(int)) < 0)
1429#endif 1460#endif
1430 { 1461 {
1431 ecore_con_event_server_error(svr, strerror(errno));
1432 goto error; 1462 goto error;
1433 } 1463 }
1434 } 1464 }
1435 1465
1436 if (bind(svr->fd, net_info->info.ai_addr, 1466 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1437 net_info->info.ai_addrlen) < 0) 1467 goto error;
1438 { 1468
1439 ecore_con_event_server_error(svr, strerror(errno)); 1469 if (listen(svr->fd, 4096) < 0) goto error;
1440 goto error;
1441 }
1442 if (listen(svr->fd, 4096) < 0)
1443 {
1444 ecore_con_event_server_error(svr, strerror(errno));
1445 goto error;
1446 }
1447 1470
1448 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, 1471 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1449 _ecore_con_svr_tcp_handler, svr, NULL, NULL); 1472 _ecore_con_svr_tcp_handler, svr, NULL, NULL);
1450 if (!svr->fd_handler) 1473 if (!svr->fd_handler)
1451 { 1474 {
1452 ecore_con_event_server_error(svr, "Memory allocation failure"); 1475 memerr = "Memory allocation failure";
1453 goto error; 1476 goto error;
1454 } 1477 }
1455 1478
1456 return; 1479 return;
1457 1480
1458error: 1481error:
1482 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1459 ecore_con_ssl_server_shutdown(svr); 1483 ecore_con_ssl_server_shutdown(svr);
1460 _ecore_con_server_kill(svr); 1484 _ecore_con_server_kill(svr);
1461} 1485}
@@ -1471,21 +1495,19 @@ _ecore_con_cb_udp_listen(void *data,
1471 struct ipv6_mreq mreq6; 1495 struct ipv6_mreq mreq6;
1472#endif 1496#endif
1473 const int on = 1; 1497 const int on = 1;
1498 const char *memerr = NULL;
1474 1499
1475 svr = data; 1500 svr = data;
1476 type = svr->type; 1501 type = svr->type;
1477 type &= ECORE_CON_TYPE; 1502 type &= ECORE_CON_TYPE;
1478 1503
1504 errno = 0;
1479 if (!net_info) /* error message has already been handled */ 1505 if (!net_info) /* error message has already been handled */
1480 goto error; 1506 goto error;
1481 1507
1482 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, 1508 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1483 net_info->info.ai_protocol); 1509 net_info->info.ai_protocol);
1484 if (svr->fd < 0) 1510 if (svr->fd < 0) goto error;
1485 {
1486 ecore_con_event_server_error(svr, strerror(errno));
1487 goto error;
1488 }
1489 1511
1490 if (type == ECORE_CON_REMOTE_MCAST) 1512 if (type == ECORE_CON_REMOTE_MCAST)
1491 { 1513 {
@@ -1493,69 +1515,41 @@ _ecore_con_cb_udp_listen(void *data,
1493 { 1515 {
1494 if (!inet_pton(net_info->info.ai_family, net_info->ip, 1516 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1495 &mreq.imr_multiaddr)) 1517 &mreq.imr_multiaddr))
1496 { 1518 goto error;
1497 ecore_con_event_server_error(svr, strerror(errno));
1498 goto error;
1499 }
1500 1519
1501 mreq.imr_interface.s_addr = htonl(INADDR_ANY); 1520 mreq.imr_interface.s_addr = htonl(INADDR_ANY);
1502 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 1521 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1503 (const void *)&mreq, sizeof(mreq)) != 0) 1522 (const void *)&mreq, sizeof(mreq)) != 0)
1504 { 1523 goto error;
1505 ecore_con_event_server_error(svr, strerror(errno));
1506 goto error;
1507 }
1508 } 1524 }
1509#ifdef HAVE_IPV6 1525#ifdef HAVE_IPV6
1510 else if (net_info->info.ai_family == AF_INET6) 1526 else if (net_info->info.ai_family == AF_INET6)
1511 { 1527 {
1512 if (!inet_pton(net_info->info.ai_family, net_info->ip, 1528 if (!inet_pton(net_info->info.ai_family, net_info->ip,
1513 &mreq6.ipv6mr_multiaddr)) 1529 &mreq6.ipv6mr_multiaddr))
1514 { 1530 goto error;
1515 ecore_con_event_server_error(svr, strerror(errno));
1516 goto error;
1517 }
1518 mreq6.ipv6mr_interface = htonl(INADDR_ANY); 1531 mreq6.ipv6mr_interface = htonl(INADDR_ANY);
1519 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 1532 if (setsockopt(svr->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1520 (const void *)&mreq6, sizeof(mreq6)) != 0) 1533 (const void *)&mreq6, sizeof(mreq6)) != 0)
1521 { 1534 goto error;
1522 ecore_con_event_server_error(svr, strerror(errno));
1523 goto error;
1524 }
1525 } 1535 }
1526#endif 1536#endif
1527 } 1537 }
1528 1538
1529 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0) 1539 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) != 0)
1530 { 1540 goto error;
1531 ecore_con_event_server_error(svr, strerror(errno)); 1541 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1532 goto error; 1542 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1533 }
1534
1535 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
1536 {
1537 ecore_con_event_server_error(svr, strerror(errno));
1538 goto error;
1539 }
1540
1541 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
1542 {
1543 ecore_con_event_server_error(svr, strerror(errno));
1544 goto error;
1545 }
1546 1543
1547 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) 1544 if (bind(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1548 { 1545 goto error;
1549 ecore_con_event_server_error(svr, strerror(errno));
1550 goto error;
1551 }
1552 1546
1553 svr->fd_handler = 1547 svr->fd_handler =
1554 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ, 1548 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
1555 _ecore_con_svr_udp_handler, svr, NULL, NULL); 1549 _ecore_con_svr_udp_handler, svr, NULL, NULL);
1556 if (!svr->fd_handler) 1550 if (!svr->fd_handler)
1557 { 1551 {
1558 ecore_con_event_server_error(svr, "Memory allocation failure"); 1552 memerr = "Memory allocation failure";
1559 goto error; 1553 goto error;
1560 } 1554 }
1561 1555
@@ -1564,6 +1558,7 @@ _ecore_con_cb_udp_listen(void *data,
1564 return; 1558 return;
1565 1559
1566error: 1560error:
1561 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1567 ecore_con_ssl_server_shutdown(svr); 1562 ecore_con_ssl_server_shutdown(svr);
1568 _ecore_con_server_kill(svr); 1563 _ecore_con_server_kill(svr);
1569} 1564}
@@ -1575,37 +1570,23 @@ _ecore_con_cb_tcp_connect(void *data,
1575 Ecore_Con_Server *svr; 1570 Ecore_Con_Server *svr;
1576 int res; 1571 int res;
1577 int curstate = 0; 1572 int curstate = 0;
1573 const char *memerr = NULL;
1578 1574
1579 svr = data; 1575 svr = data;
1580 1576
1577 errno = 0;
1581 if (!net_info) /* error message has already been handled */ 1578 if (!net_info) /* error message has already been handled */
1582 goto error; 1579 goto error;
1583 1580
1584 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, 1581 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1585 net_info->info.ai_protocol); 1582 net_info->info.ai_protocol);
1586 if (svr->fd < 0) 1583 if (svr->fd < 0) goto error;
1587 {
1588 ecore_con_event_server_error(svr, strerror(errno));
1589 goto error;
1590 }
1591 1584
1592 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) 1585 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1593 { 1586 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1594 ecore_con_event_server_error(svr, strerror(errno));
1595 goto error;
1596 }
1597
1598 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
1599 {
1600 ecore_con_event_server_error(svr, strerror(errno));
1601 goto error;
1602 }
1603 1587
1604 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0) 1588 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate, sizeof(curstate)) < 0)
1605 { 1589 goto error;
1606 ecore_con_event_server_error(svr, strerror(errno));
1607 goto error;
1608 }
1609 1590
1610 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY) 1591 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_NODELAY)
1611 { 1592 {
@@ -1615,7 +1596,6 @@ _ecore_con_cb_tcp_connect(void *data,
1615 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0) 1596 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)) < 0)
1616#endif 1597#endif
1617 { 1598 {
1618 ecore_con_event_server_error(svr, strerror(errno));
1619 goto error; 1599 goto error;
1620 } 1600 }
1621 } 1601 }
@@ -1625,17 +1605,19 @@ _ecore_con_cb_tcp_connect(void *data,
1625 if (res == SOCKET_ERROR) 1605 if (res == SOCKET_ERROR)
1626 { 1606 {
1627 if (WSAGetLastError() != WSAEINPROGRESS) 1607 if (WSAGetLastError() != WSAEINPROGRESS)
1628 goto error; /* FIXME: strerror on windows? */ 1608 {
1609 char *err;
1610 err = evil_format_message(WSAGetLastError());
1611 _ecore_con_event_server_error(svr, err, EINA_FALSE);
1612 ecore_con_ssl_server_shutdown(svr);
1613 _ecore_con_server_kill(svr);
1614 return;
1615 }
1629 1616
1630#else 1617#else
1631 if (res < 0) 1618 if (res < 0)
1632 { 1619 {
1633 if (errno != EINPROGRESS) 1620 if (errno != EINPROGRESS) goto error;
1634 {
1635 ecore_con_event_server_error(svr, strerror(errno));
1636 goto error;
1637 }
1638
1639#endif 1621#endif
1640 svr->connecting = EINA_TRUE; 1622 svr->connecting = EINA_TRUE;
1641 svr->fd_handler = 1623 svr->fd_handler =
@@ -1650,22 +1632,24 @@ _ecore_con_cb_tcp_connect(void *data,
1650 { 1632 {
1651 svr->handshaking = EINA_TRUE; 1633 svr->handshaking = EINA_TRUE;
1652 svr->ssl_state = ECORE_CON_SSL_STATE_INIT; 1634 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
1653 DBG("beginning ssl handshake"); 1635 DBG("%s ssl handshake", svr->ecs_state ? "Queuing" : "Beginning");
1654 if (ecore_con_ssl_server_init(svr)) 1636 if ((!svr->ecs_state) && ecore_con_ssl_server_init(svr))
1655 goto error; 1637 goto error;
1656 } 1638 }
1657 1639
1658 if (!svr->fd_handler) 1640 if (!svr->fd_handler)
1659 { 1641 {
1660 ecore_con_event_server_error(svr, "Memory allocation failure"); 1642 memerr = "Memory allocation failure";
1661 goto error; 1643 goto error;
1662 } 1644 }
1663 1645
1664 svr->ip = eina_stringshare_add(net_info->ip); 1646 if ((!svr->ecs) || (svr->ecs->lookup))
1647 svr->ip = eina_stringshare_add(net_info->ip);
1665 1648
1666 return; 1649 return;
1667 1650
1668error: 1651error:
1652 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1669 ecore_con_ssl_server_shutdown(svr); 1653 ecore_con_ssl_server_shutdown(svr);
1670 _ecore_con_server_kill(svr); 1654 _ecore_con_server_kill(svr);
1671} 1655}
@@ -1677,68 +1661,50 @@ _ecore_con_cb_udp_connect(void *data,
1677 Ecore_Con_Server *svr; 1661 Ecore_Con_Server *svr;
1678 int curstate = 0; 1662 int curstate = 0;
1679 int broadcast = 1; 1663 int broadcast = 1;
1664 const char *memerr = NULL;
1680 svr = data; 1665 svr = data;
1681 1666
1667 errno = 0;
1682 if (!net_info) /* error message has already been handled */ 1668 if (!net_info) /* error message has already been handled */
1683 goto error; 1669 goto error;
1684 1670
1685 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype, 1671 svr->fd = socket(net_info->info.ai_family, net_info->info.ai_socktype,
1686 net_info->info.ai_protocol); 1672 net_info->info.ai_protocol);
1687 if (svr->fd < 0) 1673 if (svr->fd < 0) goto error;
1688 { 1674 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1689 ecore_con_event_server_error(svr, strerror(errno)); 1675 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1690 goto error;
1691 }
1692
1693 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
1694 {
1695 ecore_con_event_server_error(svr, strerror(errno));
1696 goto error;
1697 }
1698
1699 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
1700 {
1701 ecore_con_event_server_error(svr, strerror(errno));
1702 goto error;
1703 }
1704
1705 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST) 1676 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_BROADCAST)
1706 { 1677 {
1707 if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST, 1678 if (setsockopt(svr->fd, SOL_SOCKET, SO_BROADCAST,
1708 (const void *)&broadcast, 1679 (const void *)&broadcast,
1709 sizeof(broadcast)) < 0) 1680 sizeof(broadcast)) < 0)
1710 { 1681 {
1711 ecore_con_event_server_error(svr, strerror(errno));
1712 goto error; 1682 goto error;
1713 } 1683 }
1714 } 1684 }
1715 else if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, 1685 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR,
1716 (const void *)&curstate, sizeof(curstate)) < 0) 1686 (const void *)&curstate, sizeof(curstate)) < 0)
1717 { 1687 goto error;
1718 ecore_con_event_server_error(svr, strerror(errno));
1719 goto error;
1720 }
1721 1688
1722 if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0) 1689 if (connect(svr->fd, net_info->info.ai_addr, net_info->info.ai_addrlen) < 0)
1723 { 1690 goto error;
1724 ecore_con_event_server_error(svr, strerror(errno));
1725 goto error;
1726 }
1727 1691
1728 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE, 1692 svr->fd_handler = ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ | ECORE_FD_WRITE,
1729 _ecore_con_cl_udp_handler, svr, NULL, NULL); 1693 _ecore_con_cl_udp_handler, svr, NULL, NULL);
1730 1694
1731 if (!svr->fd_handler) 1695 if (!svr->fd_handler)
1732 { 1696 {
1733 ecore_con_event_server_error(svr, "Memory allocation failure"); 1697 memerr = "Memory allocation failure";
1734 goto error; 1698 goto error;
1735 } 1699 }
1736 1700
1737 svr->ip = eina_stringshare_add(net_info->ip); 1701 if ((!svr->ecs) || (svr->ecs->lookup))
1702 svr->ip = eina_stringshare_add(net_info->ip);
1738 1703
1739 return; 1704 return;
1740 1705
1741error: 1706error:
1707 if (errno || memerr) ecore_con_event_server_error(svr, memerr ?: strerror(errno));
1742 ecore_con_ssl_server_shutdown(svr); 1708 ecore_con_ssl_server_shutdown(svr);
1743 _ecore_con_server_kill(svr); 1709 _ecore_con_server_kill(svr);
1744} 1710}
@@ -1755,14 +1721,14 @@ svr_try_connect_plain(Ecore_Con_Server *svr)
1755 if (res == SOCKET_ERROR) 1721 if (res == SOCKET_ERROR)
1756 so_err = WSAGetLastError(); 1722 so_err = WSAGetLastError();
1757 1723
1758 if ((so_err == WSAEINPROGRESS) && !svr->dead) 1724 if ((so_err == WSAEINPROGRESS) && !svr->delete_me)
1759 return ECORE_CON_INPROGRESS; 1725 return ECORE_CON_INPROGRESS;
1760 1726
1761#else 1727#else
1762 if (res < 0) 1728 if (res < 0)
1763 so_err = errno; 1729 so_err = errno;
1764 1730
1765 if ((so_err == EINPROGRESS) && !svr->dead) 1731 if ((so_err == EINPROGRESS) && !svr->delete_me)
1766 return ECORE_CON_INPROGRESS; 1732 return ECORE_CON_INPROGRESS;
1767 1733
1768#endif 1734#endif
@@ -1778,15 +1744,19 @@ svr_try_connect_plain(Ecore_Con_Server *svr)
1778 1744
1779 if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting) 1745 if ((!svr->delete_me) && (!svr->handshaking) && svr->connecting)
1780 { 1746 {
1781 svr->connecting = EINA_FALSE; 1747 if (svr->ecs)
1782 svr->start_time = ecore_time_get(); 1748 {
1783 ecore_con_event_server_add(svr); 1749 if (ecore_con_socks_svr_init(svr))
1750 return ECORE_CON_INPROGRESS;
1751 }
1752 else
1753 ecore_con_event_server_add(svr);
1784 } 1754 }
1785 1755
1786 if (svr->fd_handler && (!svr->buf)) 1756 if (svr->fd_handler && (!svr->buf))
1787 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); 1757 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
1788 1758
1789 if (!svr->dead) 1759 if (!svr->delete_me)
1790 return ECORE_CON_CONNECTED; 1760 return ECORE_CON_CONNECTED;
1791 else 1761 else
1792 return ECORE_CON_DISCONNECTED; 1762 return ECORE_CON_DISCONNECTED;
@@ -1838,9 +1808,10 @@ _ecore_con_svr_tcp_handler(void *data,
1838 Ecore_Con_Client *cl = NULL; 1808 Ecore_Con_Client *cl = NULL;
1839 unsigned char client_addr[256]; 1809 unsigned char client_addr[256];
1840 unsigned int client_addr_len; 1810 unsigned int client_addr_len;
1811 const char *clerr = NULL;
1841 1812
1842 svr = data; 1813 svr = data;
1843 if (svr->dead) 1814 if (svr->delete_me)
1844 return ECORE_CALLBACK_RENEW; 1815 return ECORE_CALLBACK_RENEW;
1845 1816
1846 if (svr->delete_me) 1817 if (svr->delete_me)
@@ -1863,34 +1834,19 @@ _ecore_con_svr_tcp_handler(void *data,
1863 client_addr_len = sizeof(client_addr); 1834 client_addr_len = sizeof(client_addr);
1864 memset(&client_addr, 0, client_addr_len); 1835 memset(&client_addr, 0, client_addr_len);
1865 cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len); 1836 cl->fd = accept(svr->fd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addr_len);
1866 if (cl->fd < 0) 1837 if (cl->fd < 0) goto error;
1867 {
1868 ecore_con_event_server_error(svr, strerror(errno));
1869 goto free_cl;
1870 }
1871
1872 if ((svr->client_limit >= 0) && (svr->reject_excess_clients) && 1838 if ((svr->client_limit >= 0) && (svr->reject_excess_clients) &&
1873 (svr->client_count >= (unsigned int)svr->client_limit)) 1839 (svr->client_count >= (unsigned int)svr->client_limit))
1874 { 1840 {
1875 ecore_con_event_server_error(svr, "Maximum client limit reached"); 1841 clerr = "Maximum client limit reached";
1876 goto close_fd; 1842 goto error;
1877 } 1843 }
1878 1844
1879 if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) 1845 if (fcntl(cl->fd, F_SETFL, O_NONBLOCK) < 0) goto error;
1880 { 1846 if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
1881 ecore_con_event_server_error(svr, strerror(errno));
1882 goto close_fd;
1883 }
1884 if (fcntl(cl->fd, F_SETFD, FD_CLOEXEC) < 0)
1885 {
1886 ecore_con_event_server_error(svr, strerror(errno));
1887 goto close_fd;
1888 }
1889 cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ, 1847 cl->fd_handler = ecore_main_fd_handler_add(cl->fd, ECORE_FD_READ,
1890 _ecore_con_svr_cl_handler, cl, NULL, NULL); 1848 _ecore_con_svr_cl_handler, cl, NULL, NULL);
1891 if (!cl->fd_handler) 1849 if (!cl->fd_handler) goto error;
1892 goto close_fd;
1893
1894 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); 1850 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
1895 1851
1896 if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL)) 1852 if ((!svr->upgrade) && (svr->type & ECORE_CON_SSL))
@@ -1898,14 +1854,14 @@ _ecore_con_svr_tcp_handler(void *data,
1898 cl->handshaking = EINA_TRUE; 1854 cl->handshaking = EINA_TRUE;
1899 cl->ssl_state = ECORE_CON_SSL_STATE_INIT; 1855 cl->ssl_state = ECORE_CON_SSL_STATE_INIT;
1900 if (ecore_con_ssl_client_init(cl)) 1856 if (ecore_con_ssl_client_init(cl))
1901 goto del_handler; 1857 goto error;
1902 } 1858 }
1903 1859
1904 cl->client_addr = malloc(client_addr_len); 1860 cl->client_addr = malloc(client_addr_len);
1905 if (!cl->client_addr) 1861 if (!cl->client_addr)
1906 { 1862 {
1907 ecore_con_event_server_error(svr, "Memory allocation failure when attempting to add a new client"); 1863 clerr = "Memory allocation failure when attempting to add a new client";
1908 goto del_handler; 1864 goto error;
1909 } 1865 }
1910 cl->client_addr_len = client_addr_len; 1866 cl->client_addr_len = client_addr_len;
1911 memcpy(cl->client_addr, &client_addr, client_addr_len); 1867 memcpy(cl->client_addr, &client_addr, client_addr_len);
@@ -1918,29 +1874,28 @@ _ecore_con_svr_tcp_handler(void *data,
1918 1874
1919 return ECORE_CALLBACK_RENEW; 1875 return ECORE_CALLBACK_RENEW;
1920 1876
1921 del_handler: 1877error:
1922 ecore_main_fd_handler_del(cl->fd_handler); 1878 if (cl->fd_handler) ecore_main_fd_handler_del(cl->fd_handler);
1923 close_fd: 1879 if (cl->fd >= 0) close(cl->fd);
1924 close(cl->fd);
1925 free_cl:
1926 free(cl); 1880 free(cl);
1927 1881 if (clerr || errno) ecore_con_event_server_error(svr, clerr ?: strerror(errno));
1928 return ECORE_CALLBACK_RENEW; 1882 return ECORE_CALLBACK_RENEW;
1929} 1883}
1930 1884
1931static void 1885static void
1932_ecore_con_cl_read(Ecore_Con_Server *svr) 1886_ecore_con_cl_read(Ecore_Con_Server *svr)
1933{ 1887{
1934 DBG("svr=%p", svr);
1935 int num = 0; 1888 int num = 0;
1936 Eina_Bool lost_server = EINA_TRUE; 1889 Eina_Bool lost_server = EINA_TRUE;
1937 unsigned char buf[READBUFSIZ]; 1890 unsigned char buf[READBUFSIZ];
1938 1891
1892 DBG("svr=%p", svr);
1893
1939 /* only possible with non-ssl connections */ 1894 /* only possible with non-ssl connections */
1940 if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED)) 1895 if (svr->connecting && (svr_try_connect_plain(svr) != ECORE_CON_CONNECTED))
1941 return; 1896 return;
1942 1897
1943 if (svr->handshaking) 1898 if (svr->handshaking && (!svr->ecs_state))
1944 { 1899 {
1945 DBG("Continuing ssl handshake"); 1900 DBG("Continuing ssl handshake");
1946 if (!ecore_con_ssl_server_init(svr)) 1901 if (!ecore_con_ssl_server_init(svr))
@@ -1948,8 +1903,9 @@ _ecore_con_cl_read(Ecore_Con_Server *svr)
1948 _ecore_con_server_timer_update(svr); 1903 _ecore_con_server_timer_update(svr);
1949 } 1904 }
1950 1905
1951 if (!(svr->type & ECORE_CON_SSL)) 1906 if (svr->ecs_state || !(svr->type & ECORE_CON_SSL))
1952 { 1907 {
1908 errno = 0;
1953 num = read(svr->fd, buf, sizeof(buf)); 1909 num = read(svr->fd, buf, sizeof(buf));
1954 /* 0 is not a valid return value for a tcp socket */ 1910 /* 0 is not a valid return value for a tcp socket */
1955 if ((num > 0) || ((num < 0) && (errno == EAGAIN))) 1911 if ((num > 0) || ((num < 0) && (errno == EAGAIN)))
@@ -1966,7 +1922,12 @@ _ecore_con_cl_read(Ecore_Con_Server *svr)
1966 } 1922 }
1967 1923
1968 if ((!svr->delete_me) && (num > 0)) 1924 if ((!svr->delete_me) && (num > 0))
1969 ecore_con_event_server_data(svr, buf, num, EINA_TRUE); 1925 {
1926 if (svr->ecs_state)
1927 ecore_con_socks_read(svr, buf, num);
1928 else
1929 ecore_con_event_server_data(svr, buf, num, EINA_TRUE);
1930 }
1970 1931
1971 if (lost_server) 1932 if (lost_server)
1972 _ecore_con_server_kill(svr); 1933 _ecore_con_server_kill(svr);
@@ -1980,7 +1941,7 @@ _ecore_con_cl_handler(void *data,
1980 Eina_Bool want_read, want_write; 1941 Eina_Bool want_read, want_write;
1981 1942
1982 svr = data; 1943 svr = data;
1983 if (svr->dead) 1944 if (svr->delete_me)
1984 return ECORE_CALLBACK_RENEW; 1945 return ECORE_CALLBACK_RENEW;
1985 1946
1986 if (svr->delete_me) 1947 if (svr->delete_me)
@@ -1989,7 +1950,7 @@ _ecore_con_cl_handler(void *data,
1989 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ); 1950 want_read = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ);
1990 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); 1951 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
1991 1952
1992 if (svr->handshaking && (want_read || want_write)) 1953 if ((!svr->ecs_state) && svr->handshaking && (want_read || want_write))
1993 { 1954 {
1994 DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write"); 1955 DBG("Continuing ssl handshake: preparing to %s...", want_read ? "read" : "write");
1995#ifdef ISCOMFITOR 1956#ifdef ISCOMFITOR
@@ -2005,20 +1966,25 @@ _ecore_con_cl_handler(void *data,
2005 { 1966 {
2006 ERR("ssl handshaking failed!"); 1967 ERR("ssl handshaking failed!");
2007 svr->handshaking = EINA_FALSE; 1968 svr->handshaking = EINA_FALSE;
2008
2009 } 1969 }
2010 else if (!svr->ssl_state) 1970 else if (!svr->ssl_state)
1971 ecore_con_event_server_add(svr);
1972 return ECORE_CALLBACK_RENEW;
1973 }
1974 if (svr->ecs && svr->ecs_state && (svr->ecs_state < ECORE_CON_SOCKS_STATE_READ) && (!svr->ecs_buf))
1975 {
1976 if (svr->ecs_state < ECORE_CON_SOCKS_STATE_INIT)
2011 { 1977 {
2012 svr->connecting = EINA_FALSE; 1978 INF("PROXY STATE++");
2013 svr->start_time = ecore_time_get(); 1979 svr->ecs_state++;
2014 ecore_con_event_server_add(svr);
2015 } 1980 }
1981 if (ecore_con_socks_svr_init(svr)) return ECORE_CALLBACK_RENEW;
2016 } 1982 }
2017 else if (want_read) 1983 if (want_read)
2018 _ecore_con_cl_read(svr); 1984 _ecore_con_cl_read(svr);
2019 else if (want_write) /* only possible with non-ssl connections */ 1985 else if (want_write) /* only possible with non-ssl connections */
2020 { 1986 {
2021 if (svr->connecting && (!svr_try_connect_plain(svr))) 1987 if (svr->connecting && (!svr_try_connect_plain(svr)) && (!svr->ecs_state))
2022 return ECORE_CALLBACK_RENEW; 1988 return ECORE_CALLBACK_RENEW;
2023 1989
2024 _ecore_con_server_flush(svr); 1990 _ecore_con_server_flush(svr);
@@ -2040,7 +2006,7 @@ _ecore_con_cl_udp_handler(void *data,
2040 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE); 2006 want_write = ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE);
2041 2007
2042 svr = data; 2008 svr = data;
2043 if (svr->dead || svr->delete_me || ((!want_read) && (!want_write))) 2009 if (svr->delete_me || svr->delete_me || ((!want_read) && (!want_write)))
2044 return ECORE_CALLBACK_RENEW; 2010 return ECORE_CALLBACK_RENEW;
2045 2011
2046 if (want_write) 2012 if (want_write)
@@ -2076,7 +2042,7 @@ _ecore_con_svr_udp_handler(void *data,
2076 2042
2077 svr = data; 2043 svr = data;
2078 2044
2079 if (svr->delete_me || svr->dead) 2045 if (svr->delete_me)
2080 return ECORE_CALLBACK_RENEW; 2046 return ECORE_CALLBACK_RENEW;
2081 2047
2082 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE)) 2048 if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
@@ -2106,9 +2072,7 @@ _ecore_con_svr_udp_handler(void *data,
2106 ecore_con_event_server_error(svr, strerror(errno)); 2072 ecore_con_event_server_error(svr, strerror(errno));
2107 if (!svr->delete_me) 2073 if (!svr->delete_me)
2108 ecore_con_event_client_del(NULL); 2074 ecore_con_event_client_del(NULL);
2109 2075 _ecore_con_server_kill(svr);
2110 svr->dead = EINA_TRUE;
2111 svr->fd_handler = NULL;
2112 return ECORE_CALLBACK_CANCEL; 2076 return ECORE_CALLBACK_CANCEL;
2113 } 2077 }
2114 2078
@@ -2177,18 +2141,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl)
2177 if ((!cl->delete_me) && (num > 0)) 2141 if ((!cl->delete_me) && (num > 0))
2178 ecore_con_event_client_data(cl, buf, num, EINA_TRUE); 2142 ecore_con_event_client_data(cl, buf, num, EINA_TRUE);
2179 2143
2180 if (lost_client) 2144 if (lost_client) _ecore_con_client_kill(cl);
2181 {
2182 if (!cl->delete_me)
2183 ecore_con_event_client_del(cl);
2184 INF("Lost client %s", (cl->ip) ? cl->ip : "");
2185 cl->dead = EINA_TRUE;
2186 if (cl->fd_handler)
2187 ecore_main_fd_handler_del(cl->fd_handler);
2188
2189 cl->fd_handler = NULL;
2190 return;
2191 }
2192} 2145}
2193 2146
2194static Eina_Bool 2147static Eina_Bool
@@ -2198,9 +2151,6 @@ _ecore_con_svr_cl_handler(void *data,
2198 Ecore_Con_Client *cl; 2151 Ecore_Con_Client *cl;
2199 2152
2200 cl = data; 2153 cl = data;
2201 if (cl->dead)
2202 return ECORE_CALLBACK_RENEW;
2203
2204 if (cl->delete_me) 2154 if (cl->delete_me)
2205 return ECORE_CALLBACK_RENEW; 2155 return ECORE_CALLBACK_RENEW;
2206 2156
@@ -2209,10 +2159,8 @@ _ecore_con_svr_cl_handler(void *data,
2209 if (ecore_con_ssl_client_init(cl)) 2159 if (ecore_con_ssl_client_init(cl))
2210 { 2160 {
2211 ERR("ssl handshaking failed!"); 2161 ERR("ssl handshaking failed!");
2212 cl->handshaking = EINA_FALSE; 2162 _ecore_con_client_kill(cl);
2213 cl->dead = EINA_TRUE; 2163 return ECORE_CALLBACK_RENEW;
2214 INF("Lost client %s", (cl->ip) ? cl->ip : "");
2215 ecore_con_event_client_del(cl);
2216 } 2164 }
2217 else if (!cl->ssl_state) 2165 else if (!cl->ssl_state)
2218 ecore_con_event_client_add(cl); 2166 ecore_con_event_client_add(cl);
@@ -2230,19 +2178,25 @@ static void
2230_ecore_con_server_flush(Ecore_Con_Server *svr) 2178_ecore_con_server_flush(Ecore_Con_Server *svr)
2231{ 2179{
2232 int count, num; 2180 int count, num;
2181 size_t buf_len, buf_offset;
2182 const void *buf;
2233 2183
2184 DBG("(svr=%p,buf=%p)", svr, svr->buf);
2234#ifdef _WIN32 2185#ifdef _WIN32
2235 if (ecore_con_local_win32_server_flush(svr)) 2186 if (ecore_con_local_win32_server_flush(svr))
2236 return; 2187 return;
2237#endif 2188#endif
2238 2189
2239 if ((!svr->buf) && svr->fd_handler) 2190 if ((!svr->buf) && (!svr->ecs_buf) && svr->fd_handler)
2240 { 2191 {
2241 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); 2192 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2242 return; 2193 return;
2243 } 2194 }
2244 2195
2245 num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset; 2196 buf = svr->buf ? eina_binbuf_string_get(svr->buf) : eina_binbuf_string_get(svr->ecs_buf);
2197 buf_len = svr->buf ? eina_binbuf_length_get(svr->buf) : eina_binbuf_length_get(svr->ecs_buf);
2198 buf_offset = svr->buf ? svr->write_buf_offset : svr->ecs_buf_offset;
2199 num = buf_len - buf_offset;
2246 2200
2247 /* check whether we need to write anything at all. 2201 /* check whether we need to write anything at all.
2248 * we must not write zero bytes with SSL_write() since it 2202 * we must not write zero bytes with SSL_write() since it
@@ -2253,7 +2207,7 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
2253 */ 2207 */
2254 if (num <= 0) return; 2208 if (num <= 0) return;
2255 2209
2256 if (svr->handshaking) 2210 if ((!svr->ecs_state) && svr->handshaking)
2257 { 2211 {
2258 DBG("Continuing ssl handshake"); 2212 DBG("Continuing ssl handshake");
2259 if (ecore_con_ssl_server_init(svr)) 2213 if (ecore_con_ssl_server_init(svr))
@@ -2262,10 +2216,10 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
2262 return; 2216 return;
2263 } 2217 }
2264 2218
2265 if (!(svr->type & ECORE_CON_SSL)) 2219 if (svr->ecs_state || (!(svr->type & ECORE_CON_SSL)))
2266 count = write(svr->fd, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); 2220 count = write(svr->fd, buf + buf_offset, num);
2267 else 2221 else
2268 count = ecore_con_ssl_server_write(svr, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num); 2222 count = ecore_con_ssl_server_write(svr, buf + buf_offset, num);
2269 2223
2270 if (count < 0) 2224 if (count < 0)
2271 { 2225 {
@@ -2277,13 +2231,36 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
2277 return; 2231 return;
2278 } 2232 }
2279 2233
2280 if (count) ecore_con_event_server_write(svr, count); 2234 if (count && (!svr->ecs_state)) ecore_con_event_server_write(svr, count);
2281 svr->write_buf_offset += count; 2235 if (svr->ecs_buf)
2282 if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) 2236 buf_offset = svr->ecs_buf_offset += count;
2237 else
2238 buf_offset = svr->write_buf_offset += count;
2239 if (buf_offset >= buf_len)
2283 { 2240 {
2284 svr->write_buf_offset = 0; 2241 if (svr->ecs_buf)
2285 eina_binbuf_free(svr->buf); 2242 {
2286 svr->buf = NULL; 2243 svr->ecs_buf_offset = 0;
2244 eina_binbuf_free(svr->ecs_buf);
2245 svr->ecs_buf = NULL;
2246 INF("PROXY STATE++");
2247 svr->ecs_state++;
2248 }
2249 else
2250 {
2251 svr->write_buf_offset = 0;
2252 eina_binbuf_free(svr->buf);
2253 svr->buf = NULL;
2254#ifdef TCP_CORK
2255 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2256 {
2257 int state = 0;
2258 if (setsockopt(svr->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2259 /* realistically this isn't anything serious so we can just log and continue */
2260 ERR("uncorking failed! %s", strerror(errno));
2261 }
2262#endif
2263 }
2287 if (svr->fd_handler) 2264 if (svr->fd_handler)
2288 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); 2265 ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ);
2289 } 2266 }
@@ -2330,13 +2307,7 @@ _ecore_con_client_flush(Ecore_Con_Client *cl)
2330 if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me)) 2307 if ((errno != EAGAIN) && (errno != EINTR) && (!cl->delete_me))
2331 { 2308 {
2332 ecore_con_event_client_error(cl, strerror(errno)); 2309 ecore_con_event_client_error(cl, strerror(errno));
2333 ecore_con_event_client_del(cl); 2310 _ecore_con_client_kill(cl);
2334 cl->dead = EINA_TRUE;
2335 INF("Lost client %s", (cl->ip) ? cl->ip : "");
2336 if (cl->fd_handler)
2337 ecore_main_fd_handler_del(cl->fd_handler);
2338
2339 cl->fd_handler = NULL;
2340 } 2311 }
2341 2312
2342 return; 2313 return;
@@ -2349,6 +2320,15 @@ _ecore_con_client_flush(Ecore_Con_Client *cl)
2349 cl->buf_offset = 0; 2320 cl->buf_offset = 0;
2350 eina_binbuf_free(cl->buf); 2321 eina_binbuf_free(cl->buf);
2351 cl->buf = NULL; 2322 cl->buf = NULL;
2323#ifdef TCP_CORK
2324 if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_REMOTE_CORK)
2325 {
2326 int state = 0;
2327 if (setsockopt(cl->fd, IPPROTO_TCP, TCP_CORK, (char *)&state, sizeof(int)) < 0)
2328 /* realistically this isn't anything serious so we can just log and continue */
2329 ERR("uncorking failed! %s", strerror(errno));
2330 }
2331#endif
2352 if (cl->fd_handler) 2332 if (cl->fd_handler)
2353 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); 2333 ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);
2354 } 2334 }
@@ -2398,7 +2378,7 @@ _ecore_con_event_client_del_free(Ecore_Con_Server *svr,
2398 if ((!svr->event_count) && (svr->delete_me)) 2378 if ((!svr->event_count) && (svr->delete_me))
2399 _ecore_con_server_free(svr); 2379 _ecore_con_server_free(svr);
2400 } 2380 }
2401 if ((!e->client->event_count) && (e->client->delete_me)) 2381 if (!e->client->event_count)
2402 ecore_con_client_del(e->client); 2382 ecore_con_client_del(e->client);
2403 } 2383 }
2404 ecore_con_event_client_del_free(e); 2384 ecore_con_event_client_del_free(e);
@@ -2490,7 +2470,7 @@ _ecore_con_event_server_del_free(void *data __UNUSED__,
2490 if (e->server) 2470 if (e->server)
2491 { 2471 {
2492 e->server->event_count = eina_list_remove(e->server->event_count, ev); 2472 e->server->event_count = eina_list_remove(e->server->event_count, ev);
2493 if ((!e->server->event_count) && (e->server->delete_me)) 2473 if (!e->server->event_count)
2494 _ecore_con_server_free(e->server); 2474 _ecore_con_server_free(e->server);
2495 } 2475 }
2496 ecore_con_event_server_del_free(e); 2476 ecore_con_event_server_del_free(e);
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c b/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c
index 206948b..d922f20 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_alloc.c
@@ -40,6 +40,7 @@ GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
40GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); 40GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
41GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); 41GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
42GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); 42GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Data, ecore_con_event_server_data);
43GENERIC_ALLOC_FREE(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind);
43 44
44static Ecore_Con_Mempool *mempool_array[] = { 45static Ecore_Con_Mempool *mempool_array[] = {
45 &ecore_con_event_client_add_mp, 46 &ecore_con_event_client_add_mp,
@@ -51,7 +52,8 @@ static Ecore_Con_Mempool *mempool_array[] = {
51 &ecore_con_event_server_add_mp, 52 &ecore_con_event_server_add_mp,
52 &ecore_con_event_server_del_mp, 53 &ecore_con_event_server_del_mp,
53 &ecore_con_event_server_write_mp, 54 &ecore_con_event_server_write_mp,
54 &ecore_con_event_server_data_mp 55 &ecore_con_event_server_data_mp,
56 &ecore_con_event_proxy_bind_mp
55}; 57};
56 58
57void 59void
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c
index dd5a212..5dfe70b 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_ares.c
@@ -309,7 +309,7 @@ ecore_con_info_get(Ecore_Con_Server *svr,
309 memcpy(&cares->hints, hints, sizeof(struct addrinfo)); 309 memcpy(&cares->hints, hints, sizeof(struct addrinfo));
310 } 310 }
311 311
312 if (inet_pton(AF_INET, svr->name, &cares->addr.v4) == 1) 312 if (inet_pton(AF_INET, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v4) == 1)
313 { 313 {
314 cares->byaddr = EINA_TRUE; 314 cares->byaddr = EINA_TRUE;
315 cares->isv6 = EINA_FALSE; 315 cares->isv6 = EINA_FALSE;
@@ -320,7 +320,7 @@ ecore_con_info_get(Ecore_Con_Server *svr,
320 cares); 320 cares);
321 } 321 }
322#ifdef HAVE_IPV6 322#ifdef HAVE_IPV6
323 else if (inet_pton(AF_INET6, svr->name, &cares->addr.v6) == 1) 323 else if (inet_pton(AF_INET6, svr->ecs ? svr->ecs->ip : svr->name, &cares->addr.v6) == 1)
324 { 324 {
325 cares->byaddr = EINA_TRUE; 325 cares->byaddr = EINA_TRUE;
326 cares->isv6 = EINA_TRUE; 326 cares->isv6 = EINA_TRUE;
@@ -334,7 +334,7 @@ ecore_con_info_get(Ecore_Con_Server *svr,
334 else 334 else
335 { 335 {
336 cares->byaddr = EINA_FALSE; 336 cares->byaddr = EINA_FALSE;
337 ares_gethostbyname(info_channel, svr->name, ai_family, 337 ares_gethostbyname(info_channel, svr->ecs ? svr->ecs->ip : svr->name, ai_family,
338 (ares_host_callback)_ecore_con_info_ares_host_cb, 338 (ares_host_callback)_ecore_con_info_ares_host_cb,
339 cares); 339 cares);
340 } 340 }
@@ -457,7 +457,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
457 goto on_mem_error; 457 goto on_mem_error;
458 458
459 addri->sin_family = AF_INET; 459 addri->sin_family = AF_INET;
460 addri->sin_port = htons(arg->svr->port); 460 addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
461 461
462 memcpy(&addri->sin_addr.s_addr, 462 memcpy(&addri->sin_addr.s_addr,
463 hostent->h_addr_list[0], sizeof(struct in_addr)); 463 hostent->h_addr_list[0], sizeof(struct in_addr));
@@ -477,7 +477,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
477 goto on_mem_error; 477 goto on_mem_error;
478 478
479 addri6->sin6_family = AF_INET6; 479 addri6->sin6_family = AF_INET6;
480 addri6->sin6_port = htons(arg->svr->port); 480 addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
481 addri6->sin6_flowinfo = 0; 481 addri6->sin6_flowinfo = 0;
482 addri6->sin6_scope_id = 0; 482 addri6->sin6_scope_id = 0;
483 483
@@ -516,7 +516,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
516 goto on_mem_error; 516 goto on_mem_error;
517 517
518 addri6->sin6_family = AF_INET6; 518 addri6->sin6_family = AF_INET6;
519 addri6->sin6_port = htons(arg->svr->port); 519 addri6->sin6_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
520 addri6->sin6_flowinfo = 0; 520 addri6->sin6_flowinfo = 0;
521 addri6->sin6_scope_id = 0; 521 addri6->sin6_scope_id = 0;
522 522
@@ -537,7 +537,7 @@ _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
537 goto on_mem_error; 537 goto on_mem_error;
538 538
539 addri->sin_family = AF_INET; 539 addri->sin_family = AF_INET;
540 addri->sin_port = htons(arg->svr->port); 540 addri->sin_port = htons(arg->svr->ecs ? arg->svr->ecs->port : arg->svr->port);
541 541
542 memcpy(&addri->sin_addr.s_addr, 542 memcpy(&addri->sin_addr.s_addr,
543 &arg->addr.v4, sizeof(struct in_addr)); 543 &arg->addr.v4, sizeof(struct in_addr));
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_info.c b/libraries/ecore/src/lib/ecore_con/ecore_con_info.c
index 4ece6b0..fdcf0b9 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_info.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_info.c
@@ -244,11 +244,10 @@ ecore_con_info_get(Ecore_Con_Server *svr,
244 unsigned char *tosend = NULL; 244 unsigned char *tosend = NULL;
245 int tosend_len; 245 int tosend_len;
246 int canonname_len = 0; 246 int canonname_len = 0;
247 int err;
248 247
249 eina_convert_itoa(svr->port, service); 248 eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, service);
250 /* CHILD */ 249 /* CHILD */
251 if (!getaddrinfo(svr->name, service, hints, &result) && result) 250 if (!getaddrinfo(svr->ecs ? svr->ecs->ip : svr->name, service, hints, &result) && result)
252 { 251 {
253 if (result->ai_canonname) 252 if (result->ai_canonname)
254 canonname_len = strlen(result->ai_canonname) + 1; 253 canonname_len = strlen(result->ai_canonname) + 1;
@@ -281,13 +280,13 @@ ecore_con_info_get(Ecore_Con_Server *svr,
281 memcpy(container->service, sbuf, sizeof(container->service)); 280 memcpy(container->service, sbuf, sizeof(container->service));
282 } 281 }
283 282
284 err = write(fd[1], tosend, tosend_len); 283 if (write(fd[1], tosend, tosend_len) < 0) perror("write");
285 } 284 }
286 285
287 if (result) 286 if (result)
288 freeaddrinfo(result); 287 freeaddrinfo(result);
289 288
290 err = write(fd[1], "", 1); 289 if (write(fd[1], "", 1) < 0) perror("write");
291 close(fd[1]); 290 close(fd[1]);
292#if defined(__USE_ISOC99) && !defined(__UCLIBC__) 291#if defined(__USE_ISOC99) && !defined(__UCLIBC__)
293 _Exit(0); 292 _Exit(0);
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
index 858daa5..2b7e5c5 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
@@ -75,9 +75,7 @@ _ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handle
75 free(msg); 75 free(msg);
76 } 76 }
77#endif 77#endif
78 if (!cl->delete_me) 78 _ecore_con_client_kill(cl);
79 ecore_con_event_client_del(cl);
80 cl->dead = EINA_TRUE;
81 return ECORE_CALLBACK_CANCEL; 79 return ECORE_CALLBACK_CANCEL;
82 } 80 }
83 81
@@ -110,9 +108,7 @@ _ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handle
110 free(msg); 108 free(msg);
111 } 109 }
112#endif 110#endif
113 if (!cl->host_server->delete_me) 111 _ecore_con_server_kill(cl->host_server);
114 ecore_con_event_server_del(cl->host_server);
115 cl->host_server->dead = EINA_TRUE;
116 return ECORE_CALLBACK_CANCEL; 112 return ECORE_CALLBACK_CANCEL;
117 113
118 ecore_main_win32_handler_del(wh); 114 ecore_main_win32_handler_del(wh);
@@ -140,9 +136,7 @@ _ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handle
140 free(msg); 136 free(msg);
141 } 137 }
142#endif 138#endif
143 if (!svr->delete_me) 139 _ecore_con_server_kill(svr);
144 ecore_con_event_server_del(svr);
145 svr->dead = EINA_TRUE;
146 return ECORE_CALLBACK_CANCEL; 140 return ECORE_CALLBACK_CANCEL;
147 141
148 ecore_main_win32_handler_del(wh); 142 ecore_main_win32_handler_del(wh);
@@ -191,9 +185,7 @@ _ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handle
191 free(msg); 185 free(msg);
192 } 186 }
193#endif 187#endif
194 if (!svr->delete_me) 188 _ecore_con_server_kill(svr);
195 ecore_con_event_server_del(svr);
196 svr->dead = EINA_TRUE;
197 return ECORE_CALLBACK_CANCEL; 189 return ECORE_CALLBACK_CANCEL;
198 } 190 }
199 191
@@ -296,9 +288,6 @@ _ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh)
296 if (!svr->pipe) 288 if (!svr->pipe)
297 return ECORE_CALLBACK_CANCEL; 289 return ECORE_CALLBACK_CANCEL;
298 290
299 if (svr->dead)
300 return ECORE_CALLBACK_CANCEL;
301
302 if (svr->delete_me) 291 if (svr->delete_me)
303 return ECORE_CALLBACK_CANCEL; 292 return ECORE_CALLBACK_CANCEL;
304 293
@@ -698,16 +687,14 @@ ecore_con_local_win32_server_flush(Ecore_Con_Server *svr)
698 ecore_con_event_server_error(svr, msg); 687 ecore_con_event_server_error(svr, msg);
699 free(msg); 688 free(msg);
700 } 689 }
701 if (!svr->delete_me) 690 _ecore_con_server_kill(svr);
702 ecore_con_event_server_del(svr);
703 svr->dead = EINA_TRUE;
704 } 691 }
705 692
706 svr->write_buf_offset += written; 693 svr->write_buf_offset += written;
707 if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf)) 694 if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf))
708 { 695 {
709 svr->write_buf_offset = 0; 696 svr->write_buf_offset = 0;
710 eina_binbuf_free(svr->buf); 697 eina_binbuf_free(svr->buf);
711 svr->buf = NULL; 698 svr->buf = NULL;
712 svr->want_write = 0; 699 svr->want_write = 0;
713 } 700 }
@@ -749,9 +736,7 @@ ecore_con_local_win32_client_flush(Ecore_Con_Client *cl)
749 ecore_con_event_client_error(cl, msg); 736 ecore_con_event_client_error(cl, msg);
750 free(msg); 737 free(msg);
751 } 738 }
752 if (!cl->delete_me) 739 _ecore_con_client_kill(cl);
753 ecore_con_event_client_del(cl);
754 cl->dead = EINA_TRUE;
755 } 740 }
756 741
757 cl->buf_offset += written; 742 cl->buf_offset += written;
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_private.h b/libraries/ecore/src/lib/ecore_con/ecore_con_private.h
index f601465..35f2310 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_private.h
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_private.h
@@ -56,7 +56,8 @@ extern int _ecore_con_log_dom;
56 56
57typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup; 57typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup;
58typedef struct _Ecore_Con_Info Ecore_Con_Info; 58typedef struct _Ecore_Con_Info Ecore_Con_Info;
59 59typedef struct Ecore_Con_Socks_v4 Ecore_Con_Socks_v4;
60typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5;
60typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos); 61typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos);
61 62
62typedef enum _Ecore_Con_State 63typedef enum _Ecore_Con_State
@@ -82,6 +83,14 @@ typedef enum _Ecore_Con_Ssl_Handshake
82 ECORE_CON_SSL_STATE_INIT 83 ECORE_CON_SSL_STATE_INIT
83} Ecore_Con_Ssl_State; 84} Ecore_Con_Ssl_State;
84 85
86typedef enum Ecore_Con_Socks_State
87{
88 ECORE_CON_SOCKS_STATE_DONE = 0,
89 ECORE_CON_SOCKS_STATE_RESOLVED,
90 ECORE_CON_SOCKS_STATE_INIT,
91 ECORE_CON_SOCKS_STATE_READ
92} Ecore_Con_Socks_State;
93
85struct _Ecore_Con_Client 94struct _Ecore_Con_Client
86{ 95{
87 ECORE_MAGIC; 96 ECORE_MAGIC;
@@ -107,9 +116,8 @@ struct _Ecore_Con_Client
107#endif 116#endif
108 Ecore_Con_Ssl_State ssl_state; 117 Ecore_Con_Ssl_State ssl_state;
109 Eina_Bool handshaking : 1; 118 Eina_Bool handshaking : 1;
110 Eina_Bool upgrade : 1; 119 Eina_Bool upgrade : 1; /* STARTTLS queued */
111 Eina_Bool dead : 1; 120 Eina_Bool delete_me : 1; /* del event has been queued */
112 Eina_Bool delete_me : 1;
113}; 121};
114 122
115struct _Ecore_Con_Server 123struct _Ecore_Con_Server
@@ -130,6 +138,18 @@ struct _Ecore_Con_Server
130 Eina_List *event_count; 138 Eina_List *event_count;
131 int client_limit; 139 int client_limit;
132 pid_t ppid; 140 pid_t ppid;
141 /* socks */
142 Ecore_Con_Socks *ecs;
143 Ecore_Con_Socks_State ecs_state;
144 int ecs_addrlen;
145 unsigned char ecs_addr[16];
146 unsigned int ecs_buf_offset;
147 Eina_Binbuf *ecs_buf;
148 Eina_Binbuf *ecs_recvbuf;
149 const char *proxyip;
150 int proxyport;
151 /* endsocks */
152 const char *verify_name;
133#if USE_GNUTLS 153#if USE_GNUTLS
134 gnutls_session_t session; 154 gnutls_session_t session;
135 gnutls_anon_client_credentials_t anoncred_c; 155 gnutls_anon_client_credentials_t anoncred_c;
@@ -149,18 +169,17 @@ struct _Ecore_Con_Server
149 double disconnect_time; 169 double disconnect_time;
150 double client_disconnect_time; 170 double client_disconnect_time;
151 const char *ip; 171 const char *ip;
152 Eina_Bool dead : 1;
153 Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */ 172 Eina_Bool created : 1; /* EINA_TRUE if server is our listening server */
154 Eina_Bool connecting : 1; /* EINA_FALSE if just initialized or connected */ 173 Eina_Bool connecting : 1; /* EINA_FALSE if just initialized or connected */
155 Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */ 174 Eina_Bool handshaking : 1; /* EINA_TRUE if server is ssl handshaking */
156 Eina_Bool upgrade : 1; 175 Eina_Bool upgrade : 1; /* STARTTLS queued */
157 Eina_Bool ssl_prepared : 1; 176 Eina_Bool ssl_prepared : 1;
158 Eina_Bool use_cert : 1; /* EINA_TRUE if using certificate auth */ 177 Eina_Bool use_cert : 1; /* EINA_TRUE if using certificate auth */
159 Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */ 178 Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */
160 Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */ 179 Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */
161 Eina_Bool verify_basic : 1; /* EINA_TRUE if certificates will be verified only against the hostname */ 180 Eina_Bool verify_basic : 1; /* EINA_TRUE if certificates will be verified only against the hostname */
162 Eina_Bool reject_excess_clients : 1; 181 Eina_Bool reject_excess_clients : 1;
163 Eina_Bool delete_me : 1; 182 Eina_Bool delete_me : 1; /* del event has been queued */
164#ifdef _WIN32 183#ifdef _WIN32
165 Eina_Bool want_write : 1; 184 Eina_Bool want_write : 1;
166 Eina_Bool read_stop : 1; 185 Eina_Bool read_stop : 1;
@@ -182,19 +201,18 @@ struct _Ecore_Con_Url
182 Eina_List *additional_headers; 201 Eina_List *additional_headers;
183 Eina_List *response_headers; 202 Eina_List *response_headers;
184 const char *url; 203 const char *url;
204 long proxy_type;
205
206 Ecore_Timer *timer;
185 207
186 Ecore_Con_Url_Time time_condition; 208 Ecore_Con_Url_Time time_condition;
187 double timestamp; 209 double timestamp;
188 void *data; 210 void *data;
189 211
190 Ecore_Fd_Handler *fd_handler; 212 void *post_data;
191 int fd;
192 int flags;
193 213
194 int received; 214 int received;
195 int write_fd; 215 int write_fd;
196
197 Eina_Bool active : 1;
198}; 216};
199#endif 217#endif
200 218
@@ -212,16 +230,68 @@ struct _Ecore_Con_Lookup
212 const void *data; 230 const void *data;
213}; 231};
214 232
233#define ECORE_CON_SOCKS_CAST_ELSE(X) \
234 Ecore_Con_Socks_v4 *v4 = NULL; \
235 Ecore_Con_Socks_v5 *v5 = NULL; \
236 if ((X) && ((X)->version == 4)) \
237 v4 = (Ecore_Con_Socks_v4*)(X); \
238 else if ((X) && ((X)->version == 5)) \
239 v5 = (Ecore_Con_Socks_v5*)(X); \
240 else
241
242struct Ecore_Con_Socks
243{
244 unsigned char version;
245
246 const char *ip;
247 int port;
248 const char *username;
249 Eina_Bool lookup : 1;
250 Eina_Bool bind : 1;
251};
252
253struct Ecore_Con_Socks_v4
254{
255 unsigned char version;
256
257 const char *ip;
258 int port;
259 const char *username;
260 Eina_Bool lookup : 1;
261 Eina_Bool bind : 1;
262};
263
264struct Ecore_Con_Socks_v5
265{
266 unsigned char version;
267
268 const char *ip;
269 int port;
270 const char *username;
271 Eina_Bool lookup : 1;
272 Eina_Bool bind : 1;
273};
274
275extern Ecore_Con_Socks *_ecore_con_proxy_once;
276extern Ecore_Con_Socks *_ecore_con_proxy_global;
277void ecore_con_socks_init(void);
278void ecore_con_socks_shutdown(void);
279Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr);
280void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num);
281void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr);
215/* from ecore_con.c */ 282/* from ecore_con.c */
216void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); 283void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info);
284void ecore_con_event_proxy_bind(Ecore_Con_Server *svr);
217void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); 285void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate);
218void ecore_con_event_server_del(Ecore_Con_Server *svr); 286void ecore_con_event_server_del(Ecore_Con_Server *svr);
219void ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error); 287#define ecore_con_event_server_error(svr, error) _ecore_con_event_server_error((svr), (char*)(error), EINA_TRUE)
288void _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate);
220void ecore_con_event_client_add(Ecore_Con_Client *cl); 289void ecore_con_event_client_add(Ecore_Con_Client *cl);
221void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); 290void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate);
222void ecore_con_event_client_del(Ecore_Con_Client *cl); 291void ecore_con_event_client_del(Ecore_Con_Client *cl);
223void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); 292void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error);
224 293void _ecore_con_server_kill(Ecore_Con_Server *svr);
294void _ecore_con_client_kill(Ecore_Con_Client *cl);
225/* from ecore_local_win32.c */ 295/* from ecore_local_win32.c */
226#ifdef _WIN32 296#ifdef _WIN32
227Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); 297Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr);
@@ -312,6 +382,7 @@ GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add
312GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del); 382GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
313GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write); 383GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
314GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data); 384GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data);
385GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind);
315 386
316void ecore_con_mempool_init(void); 387void ecore_con_mempool_init(void);
317void ecore_con_mempool_shutdown(void); 388void ecore_con_mempool_shutdown(void);
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
65Eina_List *ecore_con_socks_proxies = NULL;
66
67static 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
86static 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/////////////////////////////////////////////////////////////////////////////////////
98void
99ecore_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
108void
109ecore_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;
176error:
177 _ecore_con_server_kill(svr);
178}
179
180Eina_Bool
181ecore_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
226void
227ecore_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
241void
242ecore_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 */
299EAPI Ecore_Con_Socks *
300ecore_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 */
332EAPI void
333ecore_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 */
350EAPI Eina_Bool
351ecore_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 */
370EAPI Eina_Bool
371ecore_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 */
390EAPI void
391ecore_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 */
414EAPI void
415ecore_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 */
430EAPI Eina_Bool
431ecore_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
437EAPI unsigned int
438ecore_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 */
452EAPI void
453ecore_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 */
471EAPI void
472ecore_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 */
491EAPI void
492ecore_con_socks_apply_always(Ecore_Con_Socks *ecs)
493{
494 _ecore_con_proxy_global = ecs;
495}
496/** @} */
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
index c352e94..6104632 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_ssl.c
@@ -16,6 +16,7 @@
16# include <ws2tcpip.h> 16# include <ws2tcpip.h>
17#endif 17#endif
18 18
19#include <sys/stat.h>
19#include "Ecore.h" 20#include "Ecore.h"
20#include "ecore_con_private.h" 21#include "ecore_con_private.h"
21 22
@@ -60,12 +61,34 @@ _gnutls_print_errors(void *conn, int type, int ret)
60 ecore_con_event_server_error(conn, buf); 61 ecore_con_event_server_error(conn, buf);
61} 62}
62 63
64static void
65_gnutls_print_session(const gnutls_datum_t *cert_list, unsigned int cert_list_size)
66{
67 char *c = NULL;
68 gnutls_x509_crt_t crt;
69 unsigned int x;
70
71 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
72 for (x = 0; x < cert_list_size; x++)
73 {
74 gnutls_x509_crt_init(&crt);
75 gnutls_x509_crt_import(crt, &cert_list[x], GNUTLS_X509_FMT_DER);
76 gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, (gnutls_datum_t*)&c);
77 INF("CERTIFICATE:\n%s", c);
78 gnutls_free(c);
79 gnutls_x509_crt_deinit(crt);
80 crt = NULL;
81 }
82}
83
63#ifdef ISCOMFITOR 84#ifdef ISCOMFITOR
64static void 85static void
65_gnutls_log_func(int level, 86_gnutls_log_func(int level,
66 const char *str) 87 const char *str)
67{ 88{
68 DBG("|<%d>| %s", level, str); 89 char buf[128];
90 strncat(buf, str, strlen(str) - 1);
91 DBG("|<%d>| %s", level, buf);
69} 92}
70#endif 93#endif
71 94
@@ -116,6 +139,185 @@ SSL_GNUTLS_PRINT_HANDSHAKE_STATUS(gnutls_handshake_description_t status)
116#elif USE_OPENSSL 139#elif USE_OPENSSL
117 140
118static void 141static void
142_openssl_print_verify_error(int error)
143{
144 switch (error)
145 {
146#define ERROR(X) \
147 case (X): \
148 ERR("%s", #X); \
149 break
150#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
151 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
152#endif
153#ifdef X509_V_ERR_UNABLE_TO_GET_CRL
154 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL);
155#endif
156#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
157 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
158#endif
159#ifdef X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
160 ERROR(X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE);
161#endif
162#ifdef X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
163 ERROR(X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
164#endif
165#ifdef X509_V_ERR_CERT_SIGNATURE_FAILURE
166 ERROR(X509_V_ERR_CERT_SIGNATURE_FAILURE);
167#endif
168#ifdef X509_V_ERR_CRL_SIGNATURE_FAILURE
169 ERROR(X509_V_ERR_CRL_SIGNATURE_FAILURE);
170#endif
171#ifdef X509_V_ERR_CERT_NOT_YET_VALID
172 ERROR(X509_V_ERR_CERT_NOT_YET_VALID);
173#endif
174#ifdef X509_V_ERR_CERT_HAS_EXPIRED
175 ERROR(X509_V_ERR_CERT_HAS_EXPIRED);
176#endif
177#ifdef X509_V_ERR_CRL_NOT_YET_VALID
178 ERROR(X509_V_ERR_CRL_NOT_YET_VALID);
179#endif
180#ifdef X509_V_ERR_CRL_HAS_EXPIRED
181 ERROR(X509_V_ERR_CRL_HAS_EXPIRED);
182#endif
183#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
184 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD);
185#endif
186#ifdef X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
187 ERROR(X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD);
188#endif
189#ifdef X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
190 ERROR(X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD);
191#endif
192#ifdef X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
193 ERROR(X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
194#endif
195#ifdef X509_V_ERR_OUT_OF_MEM
196 ERROR(X509_V_ERR_OUT_OF_MEM);
197#endif
198#ifdef X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
199 ERROR(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
200#endif
201#ifdef X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
202 ERROR(X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
203#endif
204#ifdef X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
205 ERROR(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
206#endif
207#ifdef X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
208 ERROR(X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
209#endif
210#ifdef X509_V_ERR_CERT_CHAIN_TOO_LONG
211 ERROR(X509_V_ERR_CERT_CHAIN_TOO_LONG);
212#endif
213#ifdef X509_V_ERR_CERT_REVOKED
214 ERROR(X509_V_ERR_CERT_REVOKED);
215#endif
216#ifdef X509_V_ERR_INVALID_CA
217 ERROR(X509_V_ERR_INVALID_CA);
218#endif
219#ifdef X509_V_ERR_PATH_LENGTH_EXCEEDED
220 ERROR(X509_V_ERR_PATH_LENGTH_EXCEEDED);
221#endif
222#ifdef X509_V_ERR_INVALID_PURPOSE
223 ERROR(X509_V_ERR_INVALID_PURPOSE);
224#endif
225#ifdef X509_V_ERR_CERT_UNTRUSTED
226 ERROR(X509_V_ERR_CERT_UNTRUSTED);
227#endif
228#ifdef X509_V_ERR_CERT_REJECTED
229 ERROR(X509_V_ERR_CERT_REJECTED);
230#endif
231 /* These are 'informational' when looking for issuer cert */
232#ifdef X509_V_ERR_SUBJECT_ISSUER_MISMATCH
233 ERROR(X509_V_ERR_SUBJECT_ISSUER_MISMATCH);
234#endif
235#ifdef X509_V_ERR_AKID_SKID_MISMATCH
236 ERROR(X509_V_ERR_AKID_SKID_MISMATCH);
237#endif
238#ifdef X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
239 ERROR(X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
240#endif
241#ifdef X509_V_ERR_KEYUSAGE_NO_CERTSIGN
242 ERROR(X509_V_ERR_KEYUSAGE_NO_CERTSIGN);
243#endif
244
245#ifdef X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
246 ERROR(X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER);
247#endif
248#ifdef X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION
249 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION);
250#endif
251#ifdef X509_V_ERR_KEYUSAGE_NO_CRL_SIGN
252 ERROR(X509_V_ERR_KEYUSAGE_NO_CRL_SIGN);
253#endif
254#ifdef X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION
255 ERROR(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
256#endif
257#ifdef X509_V_ERR_INVALID_NON_CA
258 ERROR(X509_V_ERR_INVALID_NON_CA);
259#endif
260#ifdef X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED
261 ERROR(X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
262#endif
263#ifdef X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE
264 ERROR(X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
265#endif
266#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED
267 ERROR(X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
268#endif
269
270#ifdef X509_V_ERR_INVALID_EXTENSION
271 ERROR(X509_V_ERR_INVALID_EXTENSION);
272#endif
273#ifdef X509_V_ERR_INVALID_POLICY_EXTENSION
274 ERROR(X509_V_ERR_INVALID_POLICY_EXTENSION);
275#endif
276#ifdef X509_V_ERR_NO_EXPLICIT_POLICY
277 ERROR(X509_V_ERR_NO_EXPLICIT_POLICY);
278#endif
279#ifdef X509_V_ERR_DIFFERENT_CRL_SCOPE
280 ERROR(X509_V_ERR_DIFFERENT_CRL_SCOPE);
281#endif
282#ifdef X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE
283 ERROR(X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
284#endif
285
286#ifdef X509_V_ERR_UNNESTED_RESOURCE
287 ERROR(X509_V_ERR_UNNESTED_RESOURCE);
288#endif
289
290#ifdef X509_V_ERR_PERMITTED_VIOLATION
291 ERROR(X509_V_ERR_PERMITTED_VIOLATION);
292#endif
293#ifdef X509_V_ERR_EXCLUDED_VIOLATION
294 ERROR(X509_V_ERR_EXCLUDED_VIOLATION);
295#endif
296#ifdef X509_V_ERR_SUBTREE_MINMAX
297 ERROR(X509_V_ERR_SUBTREE_MINMAX);
298#endif
299#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE
300 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
301#endif
302#ifdef X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX
303 ERROR(X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
304#endif
305#ifdef X509_V_ERR_UNSUPPORTED_NAME_SYNTAX
306 ERROR(X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
307#endif
308#ifdef X509_V_ERR_CRL_PATH_VALIDATION_ERROR
309 ERROR(X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
310#endif
311
312 /* The application is not happy */
313#ifdef X509_V_ERR_APPLICATION_VERIFICATION
314 ERROR(X509_V_ERR_APPLICATION_VERIFICATION);
315#endif
316 }
317#undef ERROR
318}
319
320static void
119_openssl_print_errors(void *conn, int type) 321_openssl_print_errors(void *conn, int type)
120{ 322{
121 char buf[1024]; 323 char buf[1024];
@@ -152,13 +354,57 @@ _openssl_name_verify(const char *name, const char *svrname)
152 EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE); 354 EINA_SAFETY_ON_TRUE_RETURN_VAL(!s, EINA_FALSE);
153 /* same as above for the stored name */ 355 /* same as above for the stored name */
154 EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE); 356 EINA_SAFETY_ON_TRUE_RETURN_VAL(!strchr(s + 1, '.'), EINA_FALSE);
155 EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(s, name + 1), EINA_FALSE); 357 if (strcasecmp(s, name + 1))
358 {
359 ERR("%s != %s", s, name + 1);
360 return EINA_FALSE;
361 }
156 } 362 }
157 else 363 else
158 EINA_SAFETY_ON_TRUE_RETURN_VAL(strcasecmp(name, svrname), EINA_FALSE); 364 if (strcasecmp(name, svrname))
365 {
366 ERR("%s != %s", name, svrname);
367 return EINA_FALSE;
368 }
159 return EINA_TRUE; 369 return EINA_TRUE;
160} 370}
161 371
372static void
373_openssl_print_session(SSL *ssl)
374{
375 /* print session info into DBG */
376 SSL_SESSION *s;
377 STACK_OF(X509) *sk;
378 BIO *b;
379 char log[4096], *p;
380 int x;
381
382 if (!eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG)) return;
383
384 memset(log, 0, sizeof(log));
385 b = BIO_new(BIO_s_mem());
386 sk = SSL_get_peer_cert_chain(ssl);
387 if (sk)
388 {
389 DBG("CERTIFICATES:");
390 for (x = 0; x < sk_X509_num(sk); x++)
391 {
392 p = X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, x)), log, sizeof(log));
393 DBG("%2d s:%s", x, p);
394 p = X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, x)), log, sizeof(log));
395 DBG(" i:%s", p);
396 PEM_write_X509(stderr, sk_X509_value(sk, x));
397 }
398 }
399 s = SSL_get_session(ssl);
400 SSL_SESSION_print(b, s);
401 fprintf(stderr, "\n");
402 while (BIO_read(b, log, sizeof(log)) > 0)
403 fprintf(stderr, "%s", log);
404
405 BIO_free(b);
406}
407
162#endif 408#endif
163 409
164#define SSL_ERROR_CHECK_GOTO_ERROR(X) \ 410#define SSL_ERROR_CHECK_GOTO_ERROR(X) \
@@ -356,6 +602,51 @@ ecore_con_ssl_server_verify_basic(Ecore_Con_Server *svr)
356} 602}
357 603
358/** 604/**
605 * @brief Set the hostname to verify against in certificate verification
606 *
607 * Sometimes the certificate hostname will not match the hostname that you are
608 * connecting to, and will instead match a different name. An example of this is
609 * that if you connect to talk.google.com to use Google Talk, you receive Google's
610 * certificate for gmail.com. This certificate should be trusted, and so you must call
611 * this function with "gmail.com" as @p name.
612 * See RFC2818 for more details.
613 * @param svr The server object
614 * @param name The hostname to verify against
615 * @since 1.2
616 */
617EAPI void
618ecore_con_ssl_server_verify_name_set(Ecore_Con_Server *svr, const char *name)
619{
620 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
621 {
622 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
623 return;
624 }
625 eina_stringshare_replace(&svr->verify_name, name);
626}
627
628/**
629 * @brief Get the hostname to verify against in certificate verification
630 *
631 * This function returns the name which will be used to validate the SSL certificate
632 * common name (CN) or alt name (subjectAltName). It will default to the @p name
633 * param in ecore_con_server_connect(), but can be changed with ecore_con_ssl_server_verify_name_set().
634 * @param svr The server object
635 * @return The hostname which will be used
636 * @since 1.2
637 */
638EAPI const char *
639ecore_con_ssl_server_verify_name_get(Ecore_Con_Server *svr)
640{
641 if (!ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_CON_SERVER))
642 {
643 ECORE_MAGIC_FAIL(svr, ECORE_MAGIC_CON_SERVER, __func__);
644 return NULL;
645 }
646 return svr->verify_name ?: svr->name;
647}
648
649/**
359 * @brief Add an ssl certificate for use in ecore_con functions. 650 * @brief Add an ssl certificate for use in ecore_con functions.
360 * 651 *
361 * Use this function to add a SSL PEM certificate. 652 * Use this function to add a SSL PEM certificate.
@@ -375,6 +666,14 @@ ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr,
375 return EINA_FALSE; 666 return EINA_FALSE;
376 } 667 }
377 668
669 if (!svr->ssl_prepared)
670 {
671 svr->use_cert = EINA_TRUE;
672 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
673 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
674 return EINA_FALSE;
675 }
676
378 return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert); 677 return SSL_SUFFIX(_ecore_con_ssl_server_cert_add) (svr, cert);
379} 678}
380 679
@@ -386,6 +685,7 @@ ecore_con_ssl_server_cert_add(Ecore_Con_Server *svr,
386 * If there is an error loading the CAs, an error will automatically be logged. 685 * If there is an error loading the CAs, an error will automatically be logged.
387 * @param ca_file The path to the CA file. 686 * @param ca_file The path to the CA file.
388 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE. 687 * @return EINA_FALSE if the file cannot be loaded, otherwise EINA_TRUE.
688 * @note since 1.2, this function can load directores
389 */ 689 */
390 690
391EAPI Eina_Bool 691EAPI Eina_Bool
@@ -398,6 +698,14 @@ ecore_con_ssl_server_cafile_add(Ecore_Con_Server *svr,
398 return EINA_FALSE; 698 return EINA_FALSE;
399 } 699 }
400 700
701 if (!svr->ssl_prepared)
702 {
703 svr->use_cert = EINA_TRUE;
704 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
705 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
706 return EINA_FALSE;
707 }
708
401 return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file); 709 return SSL_SUFFIX(_ecore_con_ssl_server_cafile_add) (svr, ca_file);
402} 710}
403 711
@@ -422,6 +730,14 @@ ecore_con_ssl_server_privkey_add(Ecore_Con_Server *svr,
422 return EINA_FALSE; 730 return EINA_FALSE;
423 } 731 }
424 732
733 if (!svr->ssl_prepared)
734 {
735 svr->use_cert = EINA_TRUE;
736 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
737 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
738 return EINA_FALSE;
739 }
740
425 return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file); 741 return SSL_SUFFIX(_ecore_con_ssl_server_privkey_add) (svr, key_file);
426} 742}
427 743
@@ -446,6 +762,14 @@ ecore_con_ssl_server_crl_add(Ecore_Con_Server *svr,
446 return EINA_FALSE; 762 return EINA_FALSE;
447 } 763 }
448 764
765 if (!svr->ssl_prepared)
766 {
767 svr->use_cert = EINA_TRUE;
768 svr->type |= ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT;
769 if (ecore_con_ssl_server_prepare(svr, svr->type & ECORE_CON_SSL))
770 return EINA_FALSE;
771 }
772
449 return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file); 773 return SSL_SUFFIX(_ecore_con_ssl_server_crl_add) (svr, crl_file);
450} 774}
451 775
@@ -480,7 +804,8 @@ ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
480 if (ecore_con_ssl_server_prepare(svr, ssl_type)) 804 if (ecore_con_ssl_server_prepare(svr, ssl_type))
481 return EINA_FALSE; 805 return EINA_FALSE;
482 } 806 }
483 svr->type |= ssl_type; 807 if (!svr->use_cert)
808 svr->type |= ssl_type;
484 svr->upgrade = EINA_TRUE; 809 svr->upgrade = EINA_TRUE;
485 svr->handshaking = EINA_TRUE; 810 svr->handshaking = EINA_TRUE;
486 svr->ssl_state = ECORE_CON_SSL_STATE_INIT; 811 svr->ssl_state = ECORE_CON_SSL_STATE_INIT;
@@ -494,7 +819,7 @@ ecore_con_ssl_server_upgrade(Ecore_Con_Server *svr, Ecore_Con_Type ssl_type)
494 * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted. 819 * Once the upgrade has been completed, an ECORE_CON_EVENT_CLIENT_UPGRADE event will be emitted.
495 * The connection should be treated as disconnected until the next event. 820 * The connection should be treated as disconnected until the next event.
496 * @param cl The client object 821 * @param cl The client object
497 * @param compl_type The SSL connection type (ONLY). 822 * @param ssl_type The SSL connection type (ONLY).
498 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE. 823 * @return EINA_FALSE if the connection cannot be upgraded, otherwise EINA_TRUE.
499 * @warning Setting a wrong value for @p compl_type WILL mess up your program. 824 * @warning Setting a wrong value for @p compl_type WILL mess up your program.
500 * @since 1.1 825 * @since 1.1
@@ -517,7 +842,8 @@ ecore_con_ssl_client_upgrade(Ecore_Con_Client *cl, Ecore_Con_Type ssl_type)
517 if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type)) 842 if (ecore_con_ssl_server_prepare(cl->host_server, ssl_type))
518 return EINA_FALSE; 843 return EINA_FALSE;
519 } 844 }
520 cl->host_server->type |= ssl_type; 845 if (!cl->host_server->use_cert)
846 cl->host_server->type |= ssl_type;
521 cl->upgrade = EINA_TRUE; 847 cl->upgrade = EINA_TRUE;
522 cl->host_server->upgrade = EINA_TRUE; 848 cl->host_server->upgrade = EINA_TRUE;
523 cl->handshaking = EINA_TRUE; 849 cl->handshaking = EINA_TRUE;
@@ -546,8 +872,11 @@ _ecore_con_ssl_init_gnutls(void)
546 return ECORE_CON_SSL_ERROR_INIT_FAILED; 872 return ECORE_CON_SSL_ERROR_INIT_FAILED;
547 873
548#ifdef ISCOMFITOR 874#ifdef ISCOMFITOR
549 gnutls_global_set_log_level(9); 875 if (eina_log_domain_level_check(_ecore_con_log_dom, EINA_LOG_LEVEL_DBG))
550 gnutls_global_set_log_function(_gnutls_log_func); 876 {
877 gnutls_global_set_log_level(9);
878 gnutls_global_set_log_function(_gnutls_log_func);
879 }
551#endif 880#endif
552 return ECORE_CON_SSL_ERROR_NONE; 881 return ECORE_CON_SSL_ERROR_NONE;
553} 882}
@@ -728,10 +1057,12 @@ _ecore_con_ssl_server_init_gnutls(Ecore_Con_Server *svr)
728 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size))); 1057 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(svr->session, &cert_list_size)));
729 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); 1058 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
730 1059
1060 _gnutls_print_session(cert_list, cert_list_size);
1061
731 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); 1062 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
732 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); 1063 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER));
733 1064
734 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->name)); 1065 SSL_ERROR_CHECK_GOTO_ERROR(!gnutls_x509_crt_check_hostname(cert, svr->verify_name ?: svr->name));
735 gnutls_x509_crt_deinit(cert); 1066 gnutls_x509_crt_deinit(cert);
736 DBG("SSL certificate verification succeeded!"); 1067 DBG("SSL certificate verification succeeded!");
737 return ECORE_CON_SSL_ERROR_NONE; 1068 return ECORE_CON_SSL_ERROR_NONE;
@@ -755,10 +1086,32 @@ static Eina_Bool
755_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr, 1086_ecore_con_ssl_server_cafile_add_gnutls(Ecore_Con_Server *svr,
756 const char *ca_file) 1087 const char *ca_file)
757{ 1088{
758 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file, 1089 struct stat st;
759 GNUTLS_X509_FMT_PEM) < 1); 1090 Eina_Iterator *it;
1091 const char *file;
1092 Eina_Bool error = EINA_FALSE;
760 1093
761 return EINA_TRUE; 1094 if (stat(ca_file, &st)) return EINA_FALSE;
1095 if (S_ISDIR(st.st_mode))
1096 {
1097 it = eina_file_ls(ca_file);
1098 SSL_ERROR_CHECK_GOTO_ERROR(!it);
1099 EINA_ITERATOR_FOREACH(it, file)
1100 {
1101 if (!error)
1102 {
1103 if (gnutls_certificate_set_x509_trust_file(svr->cert, file, GNUTLS_X509_FMT_PEM) < 1)
1104 error++;
1105 }
1106 eina_stringshare_del(file);
1107 }
1108 eina_iterator_free(it);
1109 }
1110 else
1111 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_certificate_set_x509_trust_file(svr->cert, ca_file,
1112 GNUTLS_X509_FMT_PEM) < 1);
1113
1114 return !error;
762error: 1115error:
763 ERR("Could not load CA file!"); 1116 ERR("Could not load CA file!");
764 return EINA_FALSE; 1117 return EINA_FALSE;
@@ -1026,6 +1379,7 @@ _ecore_con_ssl_client_init_gnutls(Ecore_Con_Client *cl)
1026 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size))); 1379 SSL_ERROR_CHECK_GOTO_ERROR(!(cert_list = gnutls_certificate_get_peers(cl->session, &cert_list_size)));
1027 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size); 1380 SSL_ERROR_CHECK_GOTO_ERROR(!cert_list_size);
1028 1381
1382 _gnutls_print_session(cert_list, cert_list_size);
1029/* 1383/*
1030 gnutls_x509_crt_t cert = NULL; 1384 gnutls_x509_crt_t cert = NULL;
1031 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert)); 1385 SSL_ERROR_CHECK_GOTO_ERROR(gnutls_x509_crt_init(&cert));
@@ -1282,23 +1636,7 @@ _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
1282 break; 1636 break;
1283 } 1637 }
1284 1638
1285#ifdef ISCOMFITOR 1639 _openssl_print_session(svr->ssl);
1286 {
1287 /* print session info into DBG */
1288 SSL_SESSION *s;
1289 BIO *b;
1290 char log[4096];
1291
1292 memset(log, 0, sizeof(log));
1293 s = SSL_get_session(svr->ssl);
1294 b = BIO_new(BIO_s_mem());
1295 SSL_SESSION_print(b, s);
1296 while (BIO_read(b, log, sizeof(log)) > 0)
1297 DBG("%s", log);
1298
1299 BIO_free(b);
1300 }
1301#endif
1302 if ((!svr->verify) && (!svr->verify_basic)) 1640 if ((!svr->verify) && (!svr->verify_basic))
1303 /* not verifying certificates, so we're done! */ 1641 /* not verifying certificates, so we're done! */
1304 return ECORE_CON_SSL_ERROR_NONE; 1642 return ECORE_CON_SSL_ERROR_NONE;
@@ -1310,17 +1648,29 @@ _ecore_con_ssl_server_init_openssl(Ecore_Con_Server *svr)
1310 cert = SSL_get_peer_certificate(svr->ssl); 1648 cert = SSL_get_peer_certificate(svr->ssl);
1311 if (cert) 1649 if (cert)
1312 { 1650 {
1313 char buf[256] = {0}; 1651 char *c;
1652 int clen;
1653 int name = 0;
1654
1314 if (svr->verify) 1655 if (svr->verify)
1315 SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(svr->ssl));
1316 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, buf, sizeof(buf));
1317 if (buf[0])
1318 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name));
1319 else
1320 { 1656 {
1321 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, buf, sizeof(buf)); 1657 int err;
1322 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(buf, svr->name)); 1658
1659 err = SSL_get_verify_result(svr->ssl);
1660 _openssl_print_verify_error(err);
1661 SSL_ERROR_CHECK_GOTO_ERROR(err);
1323 } 1662 }
1663 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_subject_alt_name, NULL, 0);
1664 if (clen > 0)
1665 name = NID_subject_alt_name;
1666 else
1667 clen = X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, NULL, 0);
1668 SSL_ERROR_CHECK_GOTO_ERROR(clen < 1);
1669 if (!name) name = NID_commonName;
1670 c = alloca(++clen);
1671 X509_NAME_get_text_by_NID(X509_get_subject_name(cert), name, c, clen);
1672 INF("CERT NAME: %s\n", c);
1673 SSL_ERROR_CHECK_GOTO_ERROR(!_openssl_name_verify(c, svr->verify_name ?: svr->name));
1324 } 1674 }
1325 } 1675 }
1326 1676
@@ -1338,7 +1688,13 @@ static Eina_Bool
1338_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr, 1688_ecore_con_ssl_server_cafile_add_openssl(Ecore_Con_Server *svr,
1339 const char *ca_file) 1689 const char *ca_file)
1340{ 1690{
1341 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL)); 1691 struct stat st;
1692
1693 if (stat(ca_file, &st)) return EINA_FALSE;
1694 if (S_ISDIR(st.st_mode))
1695 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, NULL, ca_file));
1696 else
1697 SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_load_verify_locations(svr->ssl_ctx, ca_file, NULL));
1342 return EINA_TRUE; 1698 return EINA_TRUE;
1343 1699
1344error: 1700error:
@@ -1543,31 +1899,20 @@ _ecore_con_ssl_client_init_openssl(Ecore_Con_Client *cl)
1543 break; 1899 break;
1544 } 1900 }
1545 1901
1546#ifdef ISCOMFITOR 1902 _openssl_print_session(cl->ssl);
1547 {
1548 /* print session info into DBG */
1549 SSL_SESSION *s;
1550 BIO *b;
1551 char log[4096];
1552
1553 memset(log, 0, sizeof(log));
1554 s = SSL_get_session(cl->ssl);
1555 b = BIO_new(BIO_s_mem());
1556 SSL_SESSION_print(b, s);
1557 while (BIO_read(b, log, sizeof(log)) > 0)
1558 DBG("%s", log);
1559
1560 BIO_free(b);
1561 }
1562#endif
1563
1564 if (!cl->host_server->verify) 1903 if (!cl->host_server->verify)
1565 /* not verifying certificates, so we're done! */ 1904 /* not verifying certificates, so we're done! */
1566 return ECORE_CON_SSL_ERROR_NONE; 1905 return ECORE_CON_SSL_ERROR_NONE;
1567 SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL); 1906 SSL_set_verify(cl->ssl, SSL_VERIFY_PEER, NULL);
1568 /* use CRL/CA lists to verify */ 1907 /* use CRL/CA lists to verify */
1569 if (SSL_get_peer_certificate(cl->ssl)) 1908 if (SSL_get_peer_certificate(cl->ssl))
1570 SSL_ERROR_CHECK_GOTO_ERROR(SSL_get_verify_result(cl->ssl)); 1909 {
1910 int err;
1911
1912 err = SSL_get_verify_result(cl->ssl);
1913 _openssl_print_verify_error(err);
1914 SSL_ERROR_CHECK_GOTO_ERROR(err);
1915 }
1571 1916
1572 return ECORE_CON_SSL_ERROR_NONE; 1917 return ECORE_CON_SSL_ERROR_NONE;
1573 1918
@@ -1679,12 +2024,6 @@ _ecore_con_ssl_server_prepare_none(Ecore_Con_Server *svr __UNUSED__,
1679} 2024}
1680 2025
1681static Ecore_Con_Ssl_Error 2026static Ecore_Con_Ssl_Error
1682_ecore_con_ssl_server_upgrade_none(Ecore_Con_Server *svr __UNUSED__)
1683{
1684 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1685}
1686
1687static Ecore_Con_Ssl_Error
1688_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__) 2027_ecore_con_ssl_server_init_none(Ecore_Con_Server *svr __UNUSED__)
1689{ 2028{
1690 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; 2029 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
@@ -1741,12 +2080,6 @@ _ecore_con_ssl_server_write_none(Ecore_Con_Server *svr __UNUSED__,
1741} 2080}
1742 2081
1743static Ecore_Con_Ssl_Error 2082static Ecore_Con_Ssl_Error
1744_ecore_con_ssl_client_upgrade_none(Ecore_Con_Client *cl __UNUSED__)
1745{
1746 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
1747}
1748
1749static Ecore_Con_Ssl_Error
1750_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__) 2083_ecore_con_ssl_client_init_none(Ecore_Con_Client *cl __UNUSED__)
1751{ 2084{
1752 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED; 2085 return ECORE_CON_SSL_ERROR_NOT_SUPPORTED;
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_url.c b/libraries/ecore/src/lib/ecore_con/ecore_con_url.c
index cfcf095..709b554 100644
--- a/libraries/ecore/src/lib/ecore_con/ecore_con_url.c
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_url.c
@@ -35,8 +35,6 @@ int ECORE_CON_EVENT_URL_COMPLETE = 0;
35int ECORE_CON_EVENT_URL_PROGRESS = 0; 35int ECORE_CON_EVENT_URL_PROGRESS = 0;
36 36
37#ifdef HAVE_CURL 37#ifdef HAVE_CURL
38static Eina_Bool _ecore_con_url_fd_handler(void *data,
39 Ecore_Fd_Handler *fd_handler);
40static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con); 38static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con);
41static size_t _ecore_con_url_header_cb(void *ptr, 39static size_t _ecore_con_url_header_cb(void *ptr,
42 size_t size, 40 size_t size,
@@ -57,50 +55,18 @@ static size_t _ecore_con_url_read_cb(void *ptr,
57 void *stream); 55 void *stream);
58static void _ecore_con_event_url_free(void *data __UNUSED__, 56static void _ecore_con_event_url_free(void *data __UNUSED__,
59 void *ev); 57 void *ev);
60static int _ecore_con_url_process_completed_jobs(
61 Ecore_Con_Url *url_con_to_match);
62static Eina_Bool _ecore_con_url_idler_handler(void *data); 58static Eina_Bool _ecore_con_url_idler_handler(void *data);
59static Eina_Bool _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__);
60static Eina_Bool _ecore_con_url_timeout_cb(void *data);
63 61
64static Ecore_Idler *_fd_idler_handler = NULL;
65static Eina_List *_url_con_list = NULL; 62static Eina_List *_url_con_list = NULL;
63static Eina_List *_fd_hd_list = NULL;
66static CURLM *_curlm = NULL; 64static CURLM *_curlm = NULL;
67static fd_set _current_fd_set; 65static fd_set _current_fd_set;
68static int _init_count = 0; 66static int _init_count = 0;
69static Ecore_Timer *_curl_timeout = NULL; 67static Ecore_Timer *_curl_timeout = NULL;
70static Eina_Bool pipelining = EINA_FALSE; 68static Eina_Bool pipelining = EINA_FALSE;
71 69
72typedef struct _Ecore_Con_Url_Event Ecore_Con_Url_Event;
73struct _Ecore_Con_Url_Event
74{
75 int type;
76 void *ev;
77};
78
79static Eina_Bool
80_url_complete_idler_cb(void *data)
81{
82 Ecore_Con_Url_Event *lev;
83
84 lev = data;
85 ecore_event_add(lev->type, lev->ev, _ecore_con_event_url_free, NULL);
86 free(lev);
87
88 return ECORE_CALLBACK_CANCEL;
89}
90
91static void
92_url_complete_push_event(int type,
93 void *ev)
94{
95 Ecore_Con_Url_Event *lev;
96
97 lev = malloc(sizeof(Ecore_Con_Url_Event));
98 lev->type = type;
99 lev->ev = ev;
100
101 ecore_idler_add(_url_complete_idler_cb, lev);
102}
103
104#endif 70#endif
105 71
106/** 72/**
@@ -113,51 +79,30 @@ EAPI int
113ecore_con_url_init(void) 79ecore_con_url_init(void)
114{ 80{
115#ifdef HAVE_CURL 81#ifdef HAVE_CURL
116 _init_count++; 82 if (++_init_count > 1) return _init_count;
117
118 if (_init_count > 1)
119 return _init_count;
120 83
121 if (!ECORE_CON_EVENT_URL_DATA) 84 if (!ECORE_CON_EVENT_URL_DATA) ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
122 { 85 if (!ECORE_CON_EVENT_URL_COMPLETE) ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
123 ECORE_CON_EVENT_URL_DATA = ecore_event_type_new(); 86 if (!ECORE_CON_EVENT_URL_PROGRESS) ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
124 ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
125 ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
126 }
127 87
128 if (!_curlm) 88 if (!_curlm)
129 { 89 {
130 long ms; 90 long ms;
131 91
132 FD_ZERO(&_current_fd_set); 92 // curl_global_init() is not thread safe!
133 if (curl_global_init(CURL_GLOBAL_ALL)) 93 if (curl_global_init(CURL_GLOBAL_ALL)) return --_init_count;
134 {
135 while (_url_con_list)
136 ecore_con_url_free(eina_list_data_get(_url_con_list));
137 return 0;
138 }
139 94
140 _curlm = curl_multi_init(); 95 _curlm = curl_multi_init();
141 if (!_curlm) 96 if (!_curlm) return --_init_count;
142 {
143 while (_url_con_list)
144 ecore_con_url_free(eina_list_data_get(_url_con_list));
145
146 _init_count--;
147 return 0;
148 }
149 97
150 curl_multi_timeout(_curlm, &ms); 98 curl_multi_timeout(_curlm, &ms);
151 if (ms <= 0) 99 if (ms <= 0) ms = 100;
152 ms = 1000;
153 100
154 _curl_timeout = 101 _curl_timeout = ecore_timer_add((double)ms / 1000, _ecore_con_url_idler_handler, (void *)0xACE);
155 ecore_timer_add((double)ms / 1000, _ecore_con_url_idler_handler,
156 (void *)0xACE);
157 ecore_timer_freeze(_curl_timeout); 102 ecore_timer_freeze(_curl_timeout);
158 } 103 }
159 104
160 return 1; 105 return _init_count;
161#else 106#else
162 return 0; 107 return 0;
163#endif 108#endif
@@ -167,34 +112,31 @@ EAPI int
167ecore_con_url_shutdown(void) 112ecore_con_url_shutdown(void)
168{ 113{
169#ifdef HAVE_CURL 114#ifdef HAVE_CURL
170 if (!_init_count) 115 if (_init_count == 0) return 0;
171 return 0;
172
173 _init_count--;
174 116
175 if (_init_count != 0) 117 if (--_init_count == 0)
176 return _init_count; 118 {
177 119 Ecore_Con_Url *con_url;
178 if (_fd_idler_handler) 120 Ecore_Fd_Handler *fd_handler;
179 ecore_idler_del(_fd_idler_handler);
180
181 _fd_idler_handler = NULL;
182
183 if (_curl_timeout)
184 ecore_timer_del(_curl_timeout);
185
186 _curl_timeout = NULL;
187 121
188 while (_url_con_list) 122 if (_curl_timeout)
189 ecore_con_url_free(eina_list_data_get(_url_con_list)); 123 {
124 ecore_timer_del(_curl_timeout);
125 _curl_timeout = NULL;
126 }
190 127
191 if (_curlm) 128 FD_ZERO(&_current_fd_set);
192 { 129 EINA_LIST_FREE(_url_con_list, con_url) ecore_con_url_free(con_url);
193 curl_multi_cleanup(_curlm); 130 EINA_LIST_FREE(_fd_hd_list, fd_handler) ecore_main_fd_handler_del(fd_handler);
194 _curlm = NULL;
195 }
196 131
197 curl_global_cleanup(); 132 if (_curlm)
133 {
134 curl_multi_cleanup(_curlm);
135 _curlm = NULL;
136 }
137 curl_global_cleanup();
138 }
139 return _init_count;
198#endif 140#endif
199 return 1; 141 return 1;
200} 142}
@@ -237,7 +179,6 @@ ecore_con_url_new(const char *url)
237 if (!url_con) 179 if (!url_con)
238 return NULL; 180 return NULL;
239 181
240 url_con->fd = -1;
241 url_con->write_fd = -1; 182 url_con->write_fd = -1;
242 183
243 url_con->curl_easy = curl_easy_init(); 184 url_con->curl_easy = curl_easy_init();
@@ -255,6 +196,24 @@ ecore_con_url_new(const char *url)
255 return NULL; 196 return NULL;
256 } 197 }
257 198
199 url_con->proxy_type = -1;
200 if (_ecore_con_proxy_global)
201 {
202 if (_ecore_con_proxy_global->ip)
203 {
204 char host[128];
205 if (_ecore_con_proxy_global->port > 0 &&
206 _ecore_con_proxy_global->port <= 65535)
207 snprintf(host, sizeof(host), "socks4://%s:%d",
208 _ecore_con_proxy_global->ip,
209 _ecore_con_proxy_global->port);
210 else
211 snprintf(host, sizeof(host), "socks4://%s",
212 _ecore_con_proxy_global->ip);
213 ecore_con_url_proxy_set(url_con, host);
214 }
215 }
216
258 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate"); 217 ret = curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate");
259 if (ret != CURLE_OK) 218 if (ret != CURLE_OK)
260 { 219 {
@@ -344,43 +303,30 @@ ecore_con_url_free(Ecore_Con_Url *url_con)
344 } 303 }
345 304
346 ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); 305 ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
347 if(url_con->fd != -1)
348 {
349 FD_CLR(url_con->fd, &_current_fd_set);
350 if (url_con->fd_handler)
351 ecore_main_fd_handler_del(url_con->fd_handler);
352
353 url_con->fd = -1;
354 url_con->fd_handler = NULL;
355 }
356 306
357 if (url_con->curl_easy) 307 if (url_con->curl_easy)
358 { 308 {
359 // FIXME: For an unknown reason, progress continue to arrive after destruction
360 // this prevent any further call to the callback.
361 curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL); 309 curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL);
362 curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE); 310 curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE);
363 311
364 if (url_con->active) 312 if (eina_list_data_find(_url_con_list, url_con))
365 { 313 {
366 url_con->active = EINA_FALSE;
367
368 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); 314 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
369 if (ret != CURLM_OK) 315 if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
370 ERR("curl_multi_remove_handle failed: %s", 316 _url_con_list = eina_list_remove(_url_con_list, url_con);
371 curl_multi_strerror(ret));
372 } 317 }
373 318
374 curl_easy_cleanup(url_con->curl_easy); 319 curl_easy_cleanup(url_con->curl_easy);
375 } 320 }
321 if (url_con->timer) ecore_timer_del(url_con->timer);
376 322
377 _url_con_list = eina_list_remove(_url_con_list, url_con);
378 curl_slist_free_all(url_con->headers); 323 curl_slist_free_all(url_con->headers);
379 EINA_LIST_FREE(url_con->additional_headers, s) 324 EINA_LIST_FREE(url_con->additional_headers, s)
380 free(s); 325 free(s);
381 EINA_LIST_FREE(url_con->response_headers, s) 326 EINA_LIST_FREE(url_con->response_headers, s)
382 free(s); 327 free(s);
383 eina_stringshare_del(url_con->url); 328 eina_stringshare_del(url_con->url);
329 if (url_con->post_data) free(url_con->post_data);
384 free(url_con); 330 free(url_con);
385#else 331#else
386 return; 332 return;
@@ -415,8 +361,7 @@ ecore_con_url_url_set(Ecore_Con_Url *url_con,
415 return EINA_FALSE; 361 return EINA_FALSE;
416 } 362 }
417 363
418 if (url_con->active) 364 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
419 return EINA_FALSE;
420 365
421 eina_stringshare_replace(&url_con->url, url); 366 eina_stringshare_replace(&url_con->url, url);
422 367
@@ -660,7 +605,7 @@ _ecore_con_url_send(Ecore_Con_Url *url_con,
660#ifdef HAVE_CURL 605#ifdef HAVE_CURL
661 Eina_List *l; 606 Eina_List *l;
662 const char *s; 607 const char *s;
663 char tmp[256]; 608 char tmp[512];
664 609
665 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) 610 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
666 { 611 {
@@ -668,8 +613,7 @@ _ecore_con_url_send(Ecore_Con_Url *url_con,
668 return EINA_FALSE; 613 return EINA_FALSE;
669 } 614 }
670 615
671 if (url_con->active) 616 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
672 return EINA_FALSE;
673 617
674 if (!url_con->url) 618 if (!url_con->url)
675 return EINA_FALSE; 619 return EINA_FALSE;
@@ -684,16 +628,24 @@ _ecore_con_url_send(Ecore_Con_Url *url_con,
684 628
685 if ((mode == MODE_POST) || (mode == MODE_AUTO)) 629 if ((mode == MODE_POST) || (mode == MODE_AUTO))
686 { 630 {
687 if (data) 631 if (url_con->post_data) free(url_con->post_data);
632 url_con->post_data = NULL;
633 if ((data) && (length > 0))
688 { 634 {
689 if ((content_type) && (strlen(content_type) < 200)) 635 url_con->post_data = malloc(length);
636 if (url_con->post_data)
690 { 637 {
691 snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type); 638 memcpy(url_con->post_data, data, length);
692 url_con->headers = curl_slist_append(url_con->headers, tmp); 639 if ((content_type) && (strlen(content_type) < 450))
640 {
641 snprintf(tmp, sizeof(tmp), "Content-Type: %s", content_type);
642 url_con->headers = curl_slist_append(url_con->headers, tmp);
643 }
644 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, url_con->post_data);
645 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length);
693 } 646 }
694 647 else
695 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDS, data); 648 return EINA_FALSE;
696 curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, length);
697 } 649 }
698 else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0); 650 else curl_easy_setopt(url_con->curl_easy, CURLOPT_POSTFIELDSIZE, 0);
699 if (mode == MODE_POST) 651 if (mode == MODE_POST)
@@ -787,8 +739,7 @@ ecore_con_url_ftp_upload(Ecore_Con_Url *url_con,
787 return EINA_FALSE; 739 return EINA_FALSE;
788 } 740 }
789 741
790 if (url_con->active) 742 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
791 return EINA_FALSE;
792 743
793 if (!url_con->url) 744 if (!url_con->url)
794 return EINA_FALSE; 745 return EINA_FALSE;
@@ -1021,8 +972,7 @@ ecore_con_url_verbose_set(Ecore_Con_Url *url_con,
1021 return; 972 return;
1022 } 973 }
1023 974
1024 if (url_con->active) 975 if (eina_list_data_find(_url_con_list, url_con)) return;
1025 return;
1026 976
1027 if (!url_con->url) 977 if (!url_con->url)
1028 return; 978 return;
@@ -1047,8 +997,7 @@ ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con,
1047 return; 997 return;
1048 } 998 }
1049 999
1050 if (url_con->active) 1000 if (eina_list_data_find(_url_con_list, url_con)) return;
1051 return;
1052 1001
1053 if (!url_con->url) 1002 if (!url_con->url)
1054 return; 1003 return;
@@ -1085,8 +1034,7 @@ ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con,
1085 return; 1034 return;
1086 } 1035 }
1087 1036
1088 if (url_con->active) 1037 if (eina_list_data_find(_url_con_list, url_con)) return;
1089 return;
1090 1038
1091 if (!url_con->url) 1039 if (!url_con->url)
1092 return; 1040 return;
@@ -1129,7 +1077,7 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
1129 return -1; 1077 return -1;
1130 } 1078 }
1131 1079
1132 if (url_con->active) return -1; 1080 if (eina_list_data_find(_url_con_list, url_con)) return -1;
1133 if (!url_con->url) return -1; 1081 if (!url_con->url) return -1;
1134 if (ca_path == NULL) 1082 if (ca_path == NULL)
1135 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0); 1083 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0);
@@ -1148,58 +1096,180 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
1148 return res; 1096 return res;
1149} 1097}
1150 1098
1151 1099EAPI Eina_Bool
1152/** 1100ecore_con_url_proxy_set(Ecore_Con_Url *url_con, const char *proxy)
1153 * @}
1154 */
1155
1156#ifdef HAVE_CURL
1157static int
1158_ecore_con_url_suspend_fd_handler(void)
1159{ 1101{
1160 Eina_List *l; 1102#ifdef HAVE_CURL
1161 Ecore_Con_Url *url_con; 1103 int res = -1;
1162 int deleted = 0; 1104 curl_version_info_data *vers = NULL;
1163 1105
1164 if (!_url_con_list) 1106 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1165 return 0; 1107 {
1108 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_set");
1109 return EINA_FALSE;
1110 }
1166 1111
1167 EINA_LIST_FOREACH(_url_con_list, l, url_con) 1112 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
1113 if (!url_con->url) return EINA_FALSE;
1114
1115 if (!proxy) res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, "");
1116 else
1168 { 1117 {
1169 if (url_con->active && url_con->fd_handler) 1118 // before curl version 7.21.7, socks protocol:// prefix is not supported
1119 // (e.g. socks4://, socks4a://, socks5:// or socks5h://, etc.)
1120 vers = curl_version_info(CURLVERSION_NOW);
1121 if (vers->version_num < 0x71507)
1170 { 1122 {
1171 ecore_main_fd_handler_del(url_con->fd_handler); 1123 url_con->proxy_type = CURLPROXY_HTTP;
1172 url_con->fd_handler = NULL; 1124 if (strstr(proxy, "socks4")) url_con->proxy_type = CURLPROXY_SOCKS4;
1173 deleted++; 1125 else if (strstr(proxy, "socks4a")) url_con->proxy_type = CURLPROXY_SOCKS4A;
1126 else if (strstr(proxy, "socks5")) url_con->proxy_type = CURLPROXY_SOCKS5;
1127 else if (strstr(proxy, "socks5h")) url_con->proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
1128 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXYTYPE, url_con->proxy_type);
1129 if (res != CURLE_OK)
1130 {
1131 ERR("curl proxy type setting failed: %s", curl_easy_strerror(res));
1132 url_con->proxy_type = -1;
1133 return EINA_FALSE;
1134 }
1174 } 1135 }
1136 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PROXY, proxy);
1137 }
1138 if (res != CURLE_OK)
1139 {
1140 ERR("curl proxy setting failed: %s", curl_easy_strerror(res));
1141 url_con->proxy_type = -1;
1142 return EINA_FALSE;
1143 }
1144 return EINA_TRUE;
1145#else
1146 return EINA_FALSE;
1147 (void)url_con;
1148 (void)proxy;
1149#endif
1150}
1151
1152EAPI void
1153ecore_con_url_timeout_set(Ecore_Con_Url *url_con, double timeout)
1154{
1155#ifdef HAVE_CURL
1156 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1157 {
1158 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_timeout_set");
1159 return;
1175 } 1160 }
1176 1161
1177 return deleted; 1162 if (eina_list_data_find(_url_con_list, url_con)) return;
1163 if (!url_con->url || timeout < 0) return;
1164 if (url_con->timer) ecore_timer_del(url_con->timer);
1165 url_con->timer = ecore_timer_add(timeout, _ecore_con_url_timeout_cb, url_con);
1166#else
1167 return;
1168 (void)url_con;
1169 (void)timeout;
1170#endif
1178} 1171}
1179 1172
1180static int 1173EAPI Eina_Bool
1181_ecore_con_url_restart_fd_handler(void) 1174ecore_con_url_proxy_username_set(Ecore_Con_Url *url_con, const char *username)
1182{ 1175{
1183 Eina_List *l; 1176#ifdef HAVE_CURL
1184 Ecore_Con_Url *url_con; 1177 int res = -1;
1185 int activated = 0; 1178 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1179 {
1180 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_username_set");
1181 return EINA_FALSE;
1182 }
1186 1183
1187 if (!_url_con_list) 1184 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
1188 return 0; 1185 if (!url_con->url) return EINA_FALSE;
1186 if (!username) return EINA_FALSE;
1187 if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
1188 {
1189 ERR("Proxy type should be socks5 and above");
1190 return EINA_FALSE;
1191 }
1189 1192
1190 EINA_LIST_FOREACH(_url_con_list, l, url_con) 1193 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_USERNAME, username);
1194 if (res != CURLE_OK)
1191 { 1195 {
1192 if (!url_con->fd_handler && url_con->fd != -1) 1196 ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res));
1193 { 1197 return EINA_FALSE;
1194 url_con->fd_handler = 1198 }
1195 ecore_main_fd_handler_add(url_con->fd, url_con->flags, 1199 return EINA_TRUE;
1196 _ecore_con_url_fd_handler, 1200#else
1197 NULL, NULL, NULL); 1201 return EINA_FALSE;
1198 activated++; 1202 (void)url_con;
1199 } 1203 (void)username;
1204#endif
1205}
1206
1207EAPI Eina_Bool
1208ecore_con_url_proxy_password_set(Ecore_Con_Url *url_con, const char *password)
1209{
1210#ifdef HAVE_CURL
1211 int res = -1;
1212 if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
1213 {
1214 ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_proxy_password_set");
1215 return EINA_FALSE;
1216 }
1217 if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
1218 if (!url_con->url) return EINA_FALSE;
1219 if (!password) return EINA_FALSE;
1220 if (url_con->proxy_type == CURLPROXY_SOCKS4 || url_con->proxy_type == CURLPROXY_SOCKS4A)
1221 {
1222 ERR("Proxy type should be socks5 and above");
1223 return EINA_FALSE;
1224 }
1225
1226 res = curl_easy_setopt(url_con->curl_easy, CURLOPT_PASSWORD, password);
1227 if (res != CURLE_OK)
1228 {
1229 ERR("curl_easy_setopt() failed: %s", curl_easy_strerror(res));
1230 return EINA_FALSE;
1200 } 1231 }
1232 return EINA_TRUE;
1233#else
1234 return EINA_FALSE;
1235 (void)url_con;
1236 (void)password;
1237#endif
1238}
1239
1240/**
1241 * @}
1242 */
1201 1243
1202 return activated; 1244#ifdef HAVE_CURL
1245static Eina_Bool
1246_ecore_con_url_timeout_cb(void *data)
1247{
1248 Ecore_Con_Url *url_con = data;
1249 CURLMcode ret;
1250 Ecore_Con_Event_Url_Complete *e;
1251
1252 if (!url_con) return ECORE_CALLBACK_CANCEL;
1253 if (!url_con->curl_easy) return ECORE_CALLBACK_CANCEL;
1254 if (!eina_list_data_find(_url_con_list, url_con)) return ECORE_CALLBACK_CANCEL;
1255
1256 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
1257 if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
1258 _url_con_list = eina_list_remove(_url_con_list, url_con);
1259
1260 curl_slist_free_all(url_con->headers);
1261 url_con->headers = NULL;
1262
1263 url_con->timer = NULL;
1264
1265 e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
1266 if (e)
1267 {
1268 e->url_con = url_con;
1269 e->status = 0;
1270 ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
1271 }
1272 return ECORE_CALLBACK_CANCEL;
1203} 1273}
1204 1274
1205static size_t 1275static size_t
@@ -1235,8 +1305,7 @@ _ecore_con_url_data_cb(void *buffer,
1235 e->url_con = url_con; 1305 e->url_con = url_con;
1236 e->size = real_size; 1306 e->size = real_size;
1237 memcpy(e->data, buffer, real_size); 1307 memcpy(e->data, buffer, real_size);
1238 ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, 1308 ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, _ecore_con_event_url_free, NULL);
1239 _ecore_con_event_url_free, NULL);
1240 } 1309 }
1241 } 1310 }
1242 else 1311 else
@@ -1266,22 +1335,6 @@ _ecore_con_url_data_cb(void *buffer,
1266 return real_size; 1335 return real_size;
1267} 1336}
1268 1337
1269#define ECORE_CON_URL_TRANSMISSION(Transmit, Event, Url_con, Total, Now) \
1270 { \
1271 Ecore_Con_Event_Url_Progress *e; \
1272 if ((Total != 0) || (Now != 0)) \
1273 { \
1274 e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); \
1275 if (e) \
1276 { \
1277 e->url_con = url_con; \
1278 e->total = Total; \
1279 e->now = Now; \
1280 ecore_event_add(Event, e, _ecore_con_event_url_free, NULL); \
1281 } \
1282 } \
1283 }
1284
1285static size_t 1338static size_t
1286_ecore_con_url_header_cb(void *ptr, 1339_ecore_con_url_header_cb(void *ptr,
1287 size_t size, 1340 size_t size,
@@ -1324,8 +1377,7 @@ _ecore_con_url_progress_cb(void *clientp,
1324 e->down.now = dlnow; 1377 e->down.now = dlnow;
1325 e->up.total = ultotal; 1378 e->up.total = ultotal;
1326 e->up.now = ulnow; 1379 e->up.now = ulnow;
1327 ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, 1380 ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, _ecore_con_event_url_free, NULL);
1328 _ecore_con_event_url_free, NULL);
1329 } 1381 }
1330 1382
1331 return 0; 1383 return 0;
@@ -1358,208 +1410,196 @@ _ecore_con_url_read_cb(void *ptr,
1358 return retcode; 1410 return retcode;
1359} 1411}
1360 1412
1361static Eina_Bool 1413static void
1362_ecore_con_url_perform(Ecore_Con_Url *url_con) 1414_ecore_con_url_info_read(void)
1363{ 1415{
1364 fd_set read_set, write_set, exc_set; 1416 CURLMsg *curlmsg;
1365 int fd_max, fd; 1417 int n_remaining;
1366 int flags, still_running;
1367 int completed_immediately = 0;
1368 CURLMcode ret;
1369
1370 _url_con_list = eina_list_append(_url_con_list, url_con);
1371
1372 url_con->active = EINA_TRUE;
1373 curl_multi_add_handle(_curlm, url_con->curl_easy);
1374 curl_multi_perform(_curlm, &still_running);
1375
1376 completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
1377 1418
1378 if (!completed_immediately) 1419 while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining)))
1379 { 1420 {
1380 if (url_con->fd_handler) 1421 if (curlmsg->msg == CURLMSG_DONE)
1381 ecore_main_fd_handler_del(url_con->fd_handler);
1382
1383 url_con->fd_handler = NULL;
1384
1385 /* url_con still active -- set up an fd_handler */
1386 FD_ZERO(&read_set);
1387 FD_ZERO(&write_set);
1388 FD_ZERO(&exc_set);
1389
1390 /* Stupid curl, why can't I get the fd to the current added job? */
1391 ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set,
1392 &fd_max);
1393 if (ret != CURLM_OK)
1394 { 1422 {
1395 ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret)); 1423 Eina_List *l, *ll;
1396 return EINA_FALSE; 1424 Ecore_Con_Url *url_con;
1397 }
1398 1425
1399 for (fd = 0; fd <= fd_max; fd++) 1426 EINA_LIST_FOREACH_SAFE(_url_con_list, l, ll, url_con)
1400 {
1401 if (!FD_ISSET(fd, &_current_fd_set))
1402 { 1427 {
1403 flags = 0; 1428 if (curlmsg->easy_handle == url_con->curl_easy)
1404 if (FD_ISSET(fd, &read_set)) 1429 {
1405 flags |= ECORE_FD_READ; 1430 CURLMcode ret;
1406 1431 Ecore_Con_Event_Url_Complete *e;
1407 if (FD_ISSET(fd, &write_set))
1408 flags |= ECORE_FD_WRITE;
1409 1432
1410 if (FD_ISSET(fd, &exc_set)) 1433 e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
1411 flags |= ECORE_FD_ERROR; 1434 if (e)
1435 {
1436 e->url_con = url_con;
1437 e->status = 0;
1438 if (curlmsg->data.result == CURLE_OK)
1439 {
1440 long status; /* curl API uses long, not int */
1441 status = 0;
1442 curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
1443 e->status = status;
1444 }
1445 ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
1446 }
1412 1447
1413 if (flags) 1448 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
1414 { 1449 if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
1415 long ms = 0; 1450 _url_con_list = eina_list_remove(_url_con_list, url_con);
1416
1417 ret = curl_multi_timeout(_curlm, &ms);
1418 if (ret != CURLM_OK)
1419 ERR("curl_multi_timeout failed: %s",
1420 curl_multi_strerror(ret));
1421
1422 if (ms == 0)
1423 ms = 1000;
1424
1425 FD_SET(fd, &_current_fd_set);
1426 url_con->fd = fd;
1427 url_con->flags = flags;
1428 url_con->fd_handler =
1429 ecore_main_fd_handler_add(fd, flags,
1430 _ecore_con_url_fd_handler,
1431 NULL, NULL, NULL);
1432 break; 1451 break;
1433 } 1452 }
1434 } 1453 }
1435 } 1454 }
1436 if (!url_con->fd_handler)
1437 {
1438 /* Failed to set up an fd_handler */
1439 ecore_timer_freeze(_curl_timeout);
1440
1441 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
1442 if (ret != CURLM_OK)
1443 ERR("curl_multi_remove_handle failed: %s",
1444 curl_multi_strerror(ret));
1445
1446 url_con->active = EINA_FALSE;
1447 url_con->fd = -1;
1448 return EINA_FALSE;
1449 }
1450
1451 ecore_timer_thaw(_curl_timeout);
1452 } 1455 }
1453
1454 return EINA_TRUE;
1455} 1456}
1456 1457
1457static Eina_Bool 1458static void
1458_ecore_con_url_idler_handler(void *data) 1459_ecore_con_url_curl_clear(void)
1459{ 1460{
1460 int done, still_running; 1461 Ecore_Con_Url *url_con;
1461
1462 done = (curl_multi_perform(_curlm, &still_running) != CURLM_CALL_MULTI_PERFORM);
1463
1464 _ecore_con_url_process_completed_jobs(NULL);
1465 1462
1466 if (done) 1463 FD_ZERO(&_current_fd_set);
1464 if (_fd_hd_list)
1467 { 1465 {
1468 _ecore_con_url_restart_fd_handler(); 1466 Ecore_Fd_Handler *fd_handler;
1469 _fd_idler_handler = NULL; 1467 EINA_LIST_FREE(_fd_hd_list, fd_handler)
1468 {
1469 int fd = ecore_main_fd_handler_fd_get(fd_handler);
1470 FD_CLR(fd, &_current_fd_set);
1471 // FIXME: ecore_main_fd_handler_del() sometimes give errors
1472 // because curl do not make fd itself controlled by users, but it can be ignored.
1473 ecore_main_fd_handler_del(fd_handler);
1474 }
1475 }
1470 1476
1471 if (!_url_con_list) 1477 EINA_LIST_FREE(_url_con_list, url_con)
1472 ecore_timer_freeze(_curl_timeout); 1478 {
1479 CURLMcode ret;
1480 Ecore_Con_Event_Url_Complete *e;
1473 1481
1474 return data == 1482 e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
1475 (void *)0xACE ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL; 1483 if (e)
1484 {
1485 e->url_con = url_con;
1486 e->status = 0;
1487 ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
1488 }
1489 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
1490 if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
1476 } 1491 }
1477
1478 return ECORE_CALLBACK_RENEW;
1479} 1492}
1480 1493
1481static Eina_Bool 1494static Eina_Bool
1482_ecore_con_url_fd_handler(void *data __UNUSED__, 1495_ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
1483 Ecore_Fd_Handler *fd_handler __UNUSED__)
1484{ 1496{
1485 _ecore_con_url_suspend_fd_handler(); 1497 if (_fd_hd_list)
1486 1498 {
1487 if (!_fd_idler_handler) 1499 Ecore_Fd_Handler *fd_handler;
1488 _fd_idler_handler = ecore_idler_add( 1500 EINA_LIST_FREE(_fd_hd_list, fd_handler)
1489 _ecore_con_url_idler_handler, NULL); 1501 {
1490 1502 int fd = ecore_main_fd_handler_fd_get(fd_handler);
1503 FD_CLR(fd, &_current_fd_set);
1504 // FIXME: ecore_main_fd_handler_del() sometimes give errors
1505 // because curl do not make fd itself controlled by users, but it can be ignored.
1506 ecore_main_fd_handler_del(fd_handler);
1507 }
1508 }
1509 ecore_timer_thaw(_curl_timeout);
1491 return ECORE_CALLBACK_RENEW; 1510 return ECORE_CALLBACK_RENEW;
1492} 1511}
1493 1512
1494static int 1513static void
1495_ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match) 1514_ecore_con_url_fdset(void)
1496{ 1515{
1497 Eina_List *l;
1498 Ecore_Con_Url *url_con;
1499 Ecore_Con_Event_Url_Complete *e;
1500 CURLMsg *curlmsg;
1501 CURLMcode ret; 1516 CURLMcode ret;
1502 int n_remaining; 1517 fd_set read_set, write_set, exc_set;
1503 int job_matched = 0; 1518 int fd, fd_max;
1519 Ecore_Fd_Handler *fd_handler;
1504 1520
1505 /* Loop jobs and check if any are done */ 1521 FD_ZERO(&read_set);
1506 while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining))) 1522 FD_ZERO(&write_set);
1523 FD_ZERO(&exc_set);
1524
1525 ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, &fd_max);
1526 if (ret != CURLM_OK)
1507 { 1527 {
1508 if (curlmsg->msg != CURLMSG_DONE) 1528 ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret));
1509 continue; 1529 return;
1530 }
1510 1531
1511 /* find the job which is done */ 1532 for (fd = 0; fd <= fd_max; fd++)
1512 EINA_LIST_FOREACH(_url_con_list, l, url_con) 1533 {
1534 int flags = 0;
1535 if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
1536 if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
1537 if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
1538 if (flags)
1513 { 1539 {
1514 if (curlmsg->easy_handle == url_con->curl_easy) 1540 if (!FD_ISSET(fd, &_current_fd_set))
1515 { 1541 {
1516 if (url_con_to_match && 1542 FD_SET(fd, &_current_fd_set);
1517 (url_con == url_con_to_match)) 1543 fd_handler = ecore_main_fd_handler_add(fd, flags, _ecore_con_url_fd_handler, NULL, NULL, NULL);
1518 job_matched = 1; 1544 if (fd_handler) _fd_hd_list = eina_list_append(_fd_hd_list, fd_handler);
1519 1545 ecore_timer_freeze(_curl_timeout);
1520 if(url_con->fd != -1) 1546 }
1521 { 1547 }
1522 FD_CLR(url_con->fd, &_current_fd_set); 1548 }
1523 if (url_con->fd_handler) 1549}
1524 ecore_main_fd_handler_del(
1525 url_con->fd_handler);
1526 1550
1527 url_con->fd = -1; 1551static Eina_Bool
1528 url_con->fd_handler = NULL; 1552_ecore_con_url_idler_handler(void *data __UNUSED__)
1529 } 1553{
1554 int still_running;
1555 CURLMcode ret;
1530 1556
1531 _url_con_list = eina_list_remove(_url_con_list, url_con); 1557 ret = curl_multi_perform(_curlm, &still_running);
1532 url_con->active = EINA_FALSE; 1558 if (ret == CURLM_CALL_MULTI_PERFORM)
1533 e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete)); 1559 {
1534 if (e) 1560 DBG("Call multiperform again");
1535 { 1561 return ECORE_CALLBACK_RENEW;
1536 e->url_con = url_con; 1562 }
1537 e->status = 0; 1563 else if (ret != CURLM_OK)
1538 if (curlmsg->data.result == CURLE_OK) 1564 {
1539 { 1565 ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret));
1540 long status; /* curl API uses long, not int */ 1566 _ecore_con_url_curl_clear();
1567 ecore_timer_freeze(_curl_timeout);
1568 return ECORE_CALLBACK_RENEW;
1569 }
1541 1570
1542 status = 0; 1571 _ecore_con_url_info_read();
1543 curl_easy_getinfo(curlmsg->easy_handle, 1572 if (still_running)
1544 CURLINFO_RESPONSE_CODE, 1573 {
1545 &status); 1574 DBG("multiperform is still_running");
1546 e->status = status; 1575 _ecore_con_url_fdset();
1547 } 1576 }
1577 else
1578 {
1579 DBG("multiperform ended");
1580 _ecore_con_url_curl_clear();
1581 ecore_timer_freeze(_curl_timeout);
1582 }
1548 1583
1549 _url_complete_push_event(ECORE_CON_EVENT_URL_COMPLETE, e); 1584 return ECORE_CALLBACK_RENEW;
1550 } 1585}
1551 1586
1552 ret = curl_multi_remove_handle(_curlm, url_con->curl_easy); 1587static Eina_Bool
1553 if (ret != CURLM_OK) 1588_ecore_con_url_perform(Ecore_Con_Url *url_con)
1554 ERR("curl_multi_remove_handle failed: %s", 1589{
1555 curl_multi_strerror(ret)); 1590 CURLMcode ret;
1556 1591
1557 break; 1592 ret = curl_multi_add_handle(_curlm, url_con->curl_easy);
1558 } 1593 if (ret != CURLM_OK)
1559 } 1594 {
1595 ERR("curl_multi_add_handle() failed: %s", curl_multi_strerror(ret));
1596 return EINA_FALSE;
1560 } 1597 }
1561 1598
1562 return job_matched; 1599 _url_con_list = eina_list_append(_url_con_list, url_con);
1600 ecore_timer_thaw(_curl_timeout);
1601
1602 return EINA_TRUE;
1563} 1603}
1564 1604
1565static void 1605static void
diff --git a/libraries/ecore/src/lib/ecore_config/Makefile.in b/libraries/ecore/src/lib/ecore_config/Makefile.in
index 1732a34..6870d44 100644
--- a/libraries/ecore/src/lib/ecore_config/Makefile.in
+++ b/libraries/ecore/src/lib/ecore_config/Makefile.in
@@ -260,10 +260,10 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
260PIXMAN_CFLAGS = @PIXMAN_CFLAGS@ 260PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
261PIXMAN_LIBS = @PIXMAN_LIBS@ 261PIXMAN_LIBS = @PIXMAN_LIBS@
262PKG_CONFIG = @PKG_CONFIG@ 262PKG_CONFIG = @PKG_CONFIG@
263PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
264PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
265POSUB = @POSUB@ 263POSUB = @POSUB@
266RANLIB = @RANLIB@ 264RANLIB = @RANLIB@
265SCIM_CFLAGS = @SCIM_CFLAGS@
266SCIM_LIBS = @SCIM_LIBS@
267SDL_CFLAGS = @SDL_CFLAGS@ 267SDL_CFLAGS = @SDL_CFLAGS@
268SDL_CONFIG = @SDL_CONFIG@ 268SDL_CONFIG = @SDL_CONFIG@
269SDL_LIBS = @SDL_LIBS@ 269SDL_LIBS = @SDL_LIBS@
@@ -282,6 +282,10 @@ TSLIB_LIBS = @TSLIB_LIBS@
282USE_NLS = @USE_NLS@ 282USE_NLS = @USE_NLS@
283VERSION = @VERSION@ 283VERSION = @VERSION@
284VMAJ = @VMAJ@ 284VMAJ = @VMAJ@
285WAYLAND_CFLAGS = @WAYLAND_CFLAGS@
286WAYLAND_EGL_CFLAGS = @WAYLAND_EGL_CFLAGS@
287WAYLAND_EGL_LIBS = @WAYLAND_EGL_LIBS@
288WAYLAND_LIBS = @WAYLAND_LIBS@
285WIN32_CFLAGS = @WIN32_CFLAGS@ 289WIN32_CFLAGS = @WIN32_CFLAGS@
286WIN32_CPPFLAGS = @WIN32_CPPFLAGS@ 290WIN32_CPPFLAGS = @WIN32_CPPFLAGS@
287WIN32_LIBS = @WIN32_LIBS@ 291WIN32_LIBS = @WIN32_LIBS@
@@ -395,6 +399,8 @@ ecore_imf_cflags = @ecore_imf_cflags@
395ecore_imf_evas_cflags = @ecore_imf_evas_cflags@ 399ecore_imf_evas_cflags = @ecore_imf_evas_cflags@
396ecore_imf_evas_libs = @ecore_imf_evas_libs@ 400ecore_imf_evas_libs = @ecore_imf_evas_libs@
397ecore_imf_libs = @ecore_imf_libs@ 401ecore_imf_libs = @ecore_imf_libs@
402ecore_imf_scim_cflags = @ecore_imf_scim_cflags@
403ecore_imf_scim_libs = @ecore_imf_scim_libs@
398ecore_imf_xim_cflags = @ecore_imf_xim_cflags@ 404ecore_imf_xim_cflags = @ecore_imf_xim_cflags@
399ecore_imf_xim_libs = @ecore_imf_xim_libs@ 405ecore_imf_xim_libs = @ecore_imf_xim_libs@
400ecore_input_cflags = @ecore_input_cflags@ 406ecore_input_cflags = @ecore_input_cflags@
@@ -407,6 +413,8 @@ ecore_psl1ght_cflags = @ecore_psl1ght_cflags@
407ecore_psl1ght_libs = @ecore_psl1ght_libs@ 413ecore_psl1ght_libs = @ecore_psl1ght_libs@
408ecore_sdl_cflags = @ecore_sdl_cflags@ 414ecore_sdl_cflags = @ecore_sdl_cflags@
409ecore_sdl_libs = @ecore_sdl_libs@ 415ecore_sdl_libs = @ecore_sdl_libs@
416ecore_wayland_cflags = @ecore_wayland_cflags@
417ecore_wayland_libs = @ecore_wayland_libs@
410ecore_win32_cflags = @ecore_win32_cflags@ 418ecore_win32_cflags = @ecore_win32_cflags@
411ecore_win32_libs = @ecore_win32_libs@ 419ecore_win32_libs = @ecore_win32_libs@
412ecore_wince_cflags = @ecore_wince_cflags@ 420ecore_wince_cflags = @ecore_wince_cflags@
@@ -451,12 +459,14 @@ requirements_ecore_fb = @requirements_ecore_fb@
451requirements_ecore_file = @requirements_ecore_file@ 459requirements_ecore_file = @requirements_ecore_file@
452requirements_ecore_imf = @requirements_ecore_imf@ 460requirements_ecore_imf = @requirements_ecore_imf@
453requirements_ecore_imf_evas = @requirements_ecore_imf_evas@ 461requirements_ecore_imf_evas = @requirements_ecore_imf_evas@
462requirements_ecore_imf_scim = @requirements_ecore_imf_scim@
454requirements_ecore_imf_xim = @requirements_ecore_imf_xim@ 463requirements_ecore_imf_xim = @requirements_ecore_imf_xim@
455requirements_ecore_input = @requirements_ecore_input@ 464requirements_ecore_input = @requirements_ecore_input@
456requirements_ecore_input_evas = @requirements_ecore_input_evas@ 465requirements_ecore_input_evas = @requirements_ecore_input_evas@
457requirements_ecore_ipc = @requirements_ecore_ipc@ 466requirements_ecore_ipc = @requirements_ecore_ipc@
458requirements_ecore_psl1ght = @requirements_ecore_psl1ght@ 467requirements_ecore_psl1ght = @requirements_ecore_psl1ght@
459requirements_ecore_sdl = @requirements_ecore_sdl@ 468requirements_ecore_sdl = @requirements_ecore_sdl@
469requirements_ecore_wayland = @requirements_ecore_wayland@
460requirements_ecore_win32 = @requirements_ecore_win32@ 470requirements_ecore_win32 = @requirements_ecore_win32@
461requirements_ecore_wince = @requirements_ecore_wince@ 471requirements_ecore_wince = @requirements_ecore_wince@
462requirements_ecore_x = @requirements_ecore_x@ 472requirements_ecore_x = @requirements_ecore_x@