2009-01-31 10:33:39 -08:00
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
2010-01-04 15:43:16 -08:00
# include <stdio.h>
2010-01-16 05:44:25 -08:00
# include <string.h>
2009-11-20 02:58:19 -08:00
# include <sys/types.h>
2003-09-23 01:09:32 -07:00
# include <sys/stat.h>
# include <errno.h>
2009-01-31 10:33:39 -08:00
# include <unistd.h>
# include <fcntl.h>
2013-03-15 01:12:05 -07:00
# ifdef HAVE_SYS_SOCKET_H
# include <sys / socket.h>
# endif
# ifdef HAVE_NETINET_TCP_H
# include <netinet / tcp.h>
# endif
# ifdef HAVE_NETINET_IN_H
# include <netinet / in.h>
# endif
# ifdef HAVE_ARPA_INET_H
# include <arpa / inet.h>
# endif
2016-11-16 01:26:56 -08:00
# ifdef HAVE_SYS_IOCTL_H
# include <sys / ioctl.h>
# endif
2013-03-09 22:49:54 -08:00
# ifdef HAVE_SYSTEMD
# include <systemd / sd-daemon.h>
# endif
2010-02-20 11:12:52 -08:00
# ifdef HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
# endif
2010-02-20 10:01:50 -08:00
# ifdef HAVE_EVIL
# include <Evil.h>
# endif
# include "Ecore.h"
# include "ecore_private.h"
# include "Ecore_Con.h"
# include "ecore_con_private.h"
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
# ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0 /* noop */
# endif
2013-03-09 22:49:54 -08:00
# ifdef HAVE_SYSTEMD
int sd_fd_index = 0 ;
int sd_fd_max = 0 ;
# endif
2011-12-21 02:13:57 -08:00
2016-10-20 07:44:20 -07:00
EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_CONNECT = 0 ;
EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = 0 ;
EWAPI Eina_Error EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST = 0 ;
EWAPI Eina_Error EFL_NET_DIALER_ERROR_PROXY_AUTHENTICATION_FAILED = 0 ;
2016-09-09 16:09:51 -07:00
2016-10-20 19:15:09 -07:00
EWAPI Eina_Error EFL_NET_SERVER_ERROR_COULDNT_RESOLVE_HOST = 0 ;
2016-10-28 17:48:19 -07:00
EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = 0 ;
EWAPI Eina_Error EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = 0 ;
2009-10-09 22:28:43 -07:00
static int _ecore_con_init_count = 0 ;
2009-12-21 09:32:19 -08:00
int _ecore_con_log_dom = - 1 ;
2003-09-23 01:09:32 -07:00
2016-09-20 11:00:17 -07:00
typedef struct pxProxyFactory_ pxProxyFactory ;
typedef struct _Ecore_Con_Libproxy {
pxProxyFactory * factory ;
char * * ( * px_proxy_factory_get_proxies ) ( pxProxyFactory * factory , const char * url ) ;
void * ( * px_proxy_factory_new ) ( void ) ;
void ( * px_proxy_factory_free ) ( pxProxyFactory * ) ;
Eina_Module * mod ;
} Ecore_Con_Libproxy ;
static Ecore_Con_Libproxy _ecore_con_libproxy ;
2016-09-18 23:19:16 -07:00
2006-01-06 09:58:12 -08:00
EAPI int
2003-09-23 01:09:32 -07:00
ecore_con_init ( void )
{
2009-10-09 22:28:43 -07:00
if ( + + _ecore_con_init_count ! = 1 )
2010-11-03 10:58:37 -07:00
return _ecore_con_init_count ;
2009-10-09 22:28:43 -07:00
2010-01-14 23:44:27 -08:00
# ifdef HAVE_EVIL
if ( ! evil_init ( ) )
2010-11-03 10:58:37 -07:00
return - - _ecore_con_init_count ;
2010-01-14 23:44:27 -08:00
# endif
2009-10-09 22:28:43 -07:00
if ( ! ecore_init ( ) )
2015-02-05 02:26:58 -08:00
goto ecore_err ;
2005-09-07 02:06:06 -07:00
2010-10-07 15:31:46 -07:00
_ecore_con_log_dom = eina_log_domain_register
2010-11-03 10:58:37 -07:00
( " ecore_con " , ECORE_CON_DEFAULT_LOG_COLOR ) ;
2010-11-05 18:22:50 -07:00
if ( _ecore_con_log_dom < 0 )
2015-02-05 02:26:58 -08:00
goto ecore_con_log_error ;
2010-07-26 23:30:27 -07:00
2011-11-06 04:26:00 -08:00
ecore_con_mempool_init ( ) ;
2016-12-07 07:34:28 -08:00
ecore_con_legacy_init ( ) ;
2004-03-31 08:47:45 -08:00
2016-09-09 16:09:51 -07:00
EFL_NET_DIALER_ERROR_COULDNT_CONNECT = eina_error_msg_static_register ( " Couldn't connect to server " ) ;
EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY = eina_error_msg_static_register ( " Couldn't resolve proxy name " ) ;
EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST = eina_error_msg_static_register ( " Couldn't resolve host name " ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EFL_NET_DIALER_ERROR_PROXY_AUTHENTICATION_FAILED = eina_error_msg_static_register ( " Proxy authentication failed " ) ;
2016-09-09 16:09:51 -07:00
2016-10-20 19:15:09 -07:00
EFL_NET_SERVER_ERROR_COULDNT_RESOLVE_HOST = eina_error_msg_static_register ( " Couldn't resolve host name " ) ;
2016-10-28 17:48:19 -07:00
EFL_NET_SOCKET_SSL_ERROR_HANDSHAKE = eina_error_msg_static_register ( " Failed SSL handshake " ) ;
EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED = eina_error_msg_static_register ( " Failed to verify peer's certificate " ) ;
2013-03-09 22:49:54 -08:00
# ifdef HAVE_SYSTEMD
sd_fd_max = sd_listen_fds ( 0 ) ;
# endif
2013-03-27 05:42:55 -07:00
eina_log_timing ( _ecore_con_log_dom ,
2013-12-19 21:07:50 -08:00
EINA_LOG_STATE_STOP ,
EINA_LOG_STATE_INIT ) ;
2013-03-27 05:42:55 -07:00
2009-10-09 22:28:43 -07:00
return _ecore_con_init_count ;
2015-02-05 02:26:58 -08:00
ecore_con_log_error :
EINA_LOG_ERR ( " Failed to create a log domain for Ecore Con. " ) ;
ecore_shutdown ( ) ;
ecore_err :
# ifdef HAVE_EVIL
evil_shutdown ( ) ;
# endif
return - - _ecore_con_init_count ;
2003-09-23 01:09:32 -07:00
}
2006-01-06 09:58:12 -08:00
EAPI int
2003-09-23 01:09:32 -07:00
ecore_con_shutdown ( void )
{
2014-10-29 05:24:53 -07:00
/* _ecore_con_init_count should not go below zero. */
if ( _ecore_con_init_count < 1 )
{
ERR ( " Ecore_Con Shutdown called without calling Ecore_Con Init. \n " ) ;
return 0 ;
}
2009-10-09 22:28:43 -07:00
if ( - - _ecore_con_init_count ! = 0 )
2010-11-03 10:58:37 -07:00
return _ecore_con_init_count ;
2010-01-28 08:07:33 -08:00
2016-09-20 11:00:17 -07:00
if ( _ecore_con_libproxy . factory )
2016-09-18 23:19:16 -07:00
{
2016-09-20 11:00:17 -07:00
_ecore_con_libproxy . px_proxy_factory_free ( _ecore_con_libproxy . factory ) ;
_ecore_con_libproxy . factory = NULL ;
}
if ( _ecore_con_libproxy . mod )
{
eina_module_free ( _ecore_con_libproxy . mod ) ;
_ecore_con_libproxy . mod = NULL ;
2016-09-18 23:19:16 -07:00
}
2013-03-27 05:42:55 -07:00
eina_log_timing ( _ecore_con_log_dom ,
2013-12-19 21:07:50 -08:00
EINA_LOG_STATE_START ,
EINA_LOG_STATE_SHUTDOWN ) ;
2013-03-27 05:42:55 -07:00
2016-12-07 07:34:28 -08:00
ecore_con_legacy_shutdown ( ) ;
2011-11-06 04:26:00 -08:00
2009-12-21 09:32:19 -08:00
eina_log_domain_unregister ( _ecore_con_log_dom ) ;
_ecore_con_log_dom = - 1 ;
2006-01-19 01:11:30 -08:00
ecore_shutdown ( ) ;
2010-01-14 23:44:27 -08:00
# ifdef HAVE_EVIL
evil_shutdown ( ) ;
# endif
2007-08-26 04:17:21 -07:00
2009-10-09 22:28:43 -07:00
return _ecore_con_init_count ;
2003-09-23 01:09:32 -07:00
}
2010-09-20 23:49:07 -07:00
2006-01-06 09:58:12 -08:00
EAPI int
2016-12-07 07:34:28 -08:00
ecore_con_ssl_available_get ( void )
2003-09-23 01:09:32 -07:00
{
2016-12-07 07:34:28 -08:00
# if HAVE_GNUTLS
return 1 ;
# elif HAVE_OPENSSL
return 2 ;
# else
return 0 ;
2015-01-30 05:16:59 -08:00
# endif
2010-07-22 04:32:55 -07:00
}
2010-11-03 10:58:37 -07:00
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
2016-10-27 04:01:19 -07:00
# ifndef _WIN32
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
Eina_Bool
2016-10-26 13:57:37 -07:00
efl_net_unix_fmt ( char * buf , size_t buflen , SOCKET fd , const struct sockaddr_un * addr , socklen_t addrlen )
{
const char * src = addr - > sun_path ;
socklen_t pathlen = addrlen - offsetof ( struct sockaddr_un , sun_path ) ;
if ( addr - > sun_family ! = AF_UNIX )
{
ERR ( " unsupported address family: %d " , addr - > sun_family ) ;
return EINA_FALSE ;
}
if ( addrlen = = offsetof ( struct sockaddr_un , sun_path ) )
{
2016-11-18 06:17:08 -08:00
int r = snprintf ( buf , buflen , " unnamed: " SOCKET_FMT , fd ) ;
2016-10-26 13:57:37 -07:00
if ( r < 0 )
{
ERR ( " snprintf(): %s " , strerror ( errno ) ) ;
return EINA_FALSE ;
}
else if ( ( size_t ) r > buflen )
{
ERR ( " buflen=%zu is too small, required=%d " , buflen , r ) ;
return EINA_FALSE ;
}
return EINA_TRUE ;
}
if ( src [ 0 ] ! = ' \0 ' )
{
if ( buflen < pathlen )
{
ERR ( " buflen=%zu is too small, required=%u " , buflen , pathlen ) ;
return EINA_FALSE ;
}
}
else
{
if ( buflen < pathlen + sizeof ( " abstract: " ) - 2 )
{
ERR ( " buflen=%zu is too small, required=%zu " , buflen , pathlen + sizeof ( " abstract: " ) - 2 ) ;
return EINA_FALSE ;
}
memcpy ( buf , " abstract: " , sizeof ( " abstract: " ) - 1 ) ;
buf + = sizeof ( " abstract: " ) - 1 ;
src + + ;
}
memcpy ( buf , src , pathlen ) ;
buf [ pathlen ] = ' \0 ' ;
return EINA_TRUE ;
}
2016-10-27 04:01:19 -07:00
# endif
2016-10-26 13:57:37 -07:00
2016-12-09 05:42:17 -08:00
/* The reverse of efl_net_ip_port_fmt().
*
* If was parsed , then returns EINA_TRUE , otherwise use getaddrinfo ( )
* or efl_net_ip_resolve_async_new ( ) .
*/
Eina_Bool
efl_net_ip_port_parse ( const char * address , struct sockaddr_storage * storage )
{
char * str ;
const char * host , * port ;
Eina_Bool ret ;
str = strdup ( address ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( str , EINA_FALSE ) ;
if ( ! efl_net_ip_port_split ( str , & host , & port ) )
{
ERR ( " invalid IP:PORT address: %s " , address ) ;
ret = EINA_FALSE ;
}
else
ret = efl_net_ip_port_parse_split ( host , port , storage ) ;
free ( str ) ;
return ret ;
}
Eina_Bool
efl_net_ip_port_parse_split ( const char * host , const char * port , struct sockaddr_storage * storage )
{
int x ;
char * endptr ;
unsigned long p ;
if ( ! port ) port = " 0 " ;
if ( strchr ( host , ' : ' ) ) storage - > ss_family = AF_INET6 ;
else storage - > ss_family = AF_INET ;
errno = 0 ;
p = strtoul ( port , & endptr , 10 ) ;
if ( ( errno ) | | ( endptr = = port ) | | ( * endptr ! = ' \0 ' ) ) return EINA_FALSE ;
else if ( p > UINT16_MAX )
{
ERR ( " invalid port number %lu (out of range) " , p ) ;
return EINA_FALSE ;
}
if ( storage - > ss_family = = AF_INET6 )
{
struct sockaddr_in6 * a = ( struct sockaddr_in6 * ) storage ;
a - > sin6_port = htons ( p ) ;
x = inet_pton ( AF_INET6 , host , & a - > sin6_addr ) ;
}
else
{
struct sockaddr_in * a = ( struct sockaddr_in * ) storage ;
a - > sin_port = htons ( p ) ;
x = inet_pton ( AF_INET , host , & a - > sin_addr ) ;
}
return x = = 1 ;
}
2016-10-26 13:57:37 -07:00
Eina_Bool
efl_net_ip_port_fmt ( char * buf , size_t buflen , const struct sockaddr * addr )
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
{
char p [ INET6_ADDRSTRLEN ] ;
const void * mem ;
unsigned short port ;
int r ;
if ( addr - > sa_family = = AF_INET )
{
const struct sockaddr_in * a = ( const struct sockaddr_in * ) addr ;
mem = & a - > sin_addr ;
port = ntohs ( a - > sin_port ) ;
}
else if ( addr - > sa_family = = AF_INET6 )
{
const struct sockaddr_in6 * a = ( const struct sockaddr_in6 * ) addr ;
mem = & a - > sin6_addr ;
port = ntohs ( a - > sin6_port ) ;
}
else
{
ERR ( " unsupported address family: %d " , addr - > sa_family ) ;
return EINA_FALSE ;
}
if ( ! inet_ntop ( addr - > sa_family , mem , p , sizeof ( p ) ) )
{
ERR ( " inet_ntop(%d, %p, %p, %zd): %s " ,
addr - > sa_family , mem , p , sizeof ( p ) , strerror ( errno ) ) ;
return EINA_FALSE ;
}
if ( addr - > sa_family = = AF_INET )
r = snprintf ( buf , buflen , " %s:%hu " , p , port ) ;
else
r = snprintf ( buf , buflen , " [%s]:%hu " , p , port ) ;
if ( r < 0 )
{
ERR ( " could not snprintf(): %s " , strerror ( errno ) ) ;
return EINA_FALSE ;
}
2016-10-26 13:57:37 -07:00
else if ( ( size_t ) r > buflen )
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
{
2016-10-26 13:57:37 -07:00
ERR ( " buffer is too small: %zu, required %d " , buflen , r ) ;
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
return EINA_FALSE ;
}
return EINA_TRUE ;
}
2016-08-24 08:34:59 -07:00
2016-09-09 16:09:51 -07:00
Eina_Bool
efl_net_ip_port_split ( char * buf , const char * * p_host , const char * * p_port )
{
char * host , * port ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( buf , EINA_FALSE ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( p_host , EINA_FALSE ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( p_port , EINA_FALSE ) ;
host = buf ;
if ( host [ 0 ] = = ' [ ' )
{
/* IPv6 is: [IP]:port */
host + + ;
port = strchr ( host , ' ] ' ) ;
if ( ! port ) return EINA_FALSE ;
* port = ' \0 ' ;
port + + ;
if ( port [ 0 ] = = ' : ' )
port + + ;
else
port = NULL ;
}
else
{
port = strchr ( host , ' : ' ) ;
if ( port )
{
* port = ' \0 ' ;
port + + ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( * port = = ' \0 ' ) port = NULL ;
2016-09-09 16:09:51 -07:00
}
}
* p_host = host ;
* p_port = port ;
return EINA_TRUE ;
}
2016-11-01 11:01:57 -07:00
# ifdef HAVE_SYSTEMD
Eina_Error
efl_net_ip_socket_activate_check ( const char * address , int family , int type , Eina_Bool * listening )
{
SOCKET fd = SD_LISTEN_FDS_START + sd_fd_index ;
int r ;
if ( sd_fd_index > = sd_fd_max ) return ENOENT ;
if ( family = = AF_UNIX )
{
char buf [ sizeof ( struct sockaddr_un ) ] = " " ;
const char * sun_path ;
size_t len ;
if ( strncmp ( address , " abstract: " , strlen ( " abstract: " ) ) = = 0 )
{
const char * path = address + strlen ( " abstract: " ) ;
if ( strlen ( path ) + 2 > sizeof ( buf ) )
{
ERR ( " abstract path is too long: %s " , path ) ;
return EINVAL ;
}
buf [ 0 ] = ' \0 ' ;
memcpy ( buf + 1 , path , strlen ( path ) + 1 ) ;
sun_path = buf ;
len = strlen ( path ) + 2 ;
}
else
{
if ( strlen ( address ) + 1 > sizeof ( buf ) )
{
ERR ( " path is too long: %s " , address ) ;
return EINVAL ;
}
sun_path = address ;
len = strlen ( address ) + 1 ;
}
r = sd_is_socket_unix ( fd , type , 0 , sun_path , len ) ;
if ( r < 0 )
{
2016-11-18 06:17:08 -08:00
ERR ( " socket " SOCKET_FMT " is not of family=%d, type=%d " , fd , family , type ) ;
2016-11-01 11:01:57 -07:00
return EINVAL ;
}
if ( listening ) * listening = ( r = = 1 ) ;
return 0 ;
}
else if ( ( family = = AF_UNSPEC ) | | ( family = = AF_INET ) | | ( family = = AF_INET6 ) )
{
char * str ;
const char * host , * port ;
struct sockaddr_storage sock_addr ;
struct sockaddr_storage want_addr = { . ss_family = family } ;
socklen_t addrlen ;
Eina_Error err ;
int x ;
r = sd_is_socket ( fd , family , type , ( type = = SOCK_DGRAM ) ? - 1 : 0 ) ;
if ( r < 0 )
{
2016-11-18 06:17:08 -08:00
ERR ( " socket " SOCKET_FMT " is not of family=%d, type=%d " , fd , family , type ) ;
2016-11-01 11:01:57 -07:00
return EINVAL ;
}
if ( ( type = = SOCK_DGRAM ) & & ( listening ) ) * listening = EINA_FALSE ;
else if ( listening ) * listening = ( r = = 1 ) ;
addrlen = sizeof ( sock_addr ) ;
if ( getsockname ( fd , ( struct sockaddr * ) & sock_addr , & addrlen ) ! = 0 )
{
err = efl_net_socket_error_get ( ) ;
2016-11-18 06:17:08 -08:00
ERR ( " could not query socket= " SOCKET_FMT " name: %s " , fd , eina_error_msg_get ( err ) ) ;
2016-11-01 11:01:57 -07:00
return err ;
}
str = strdup ( address ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( str , ENOMEM ) ;
if ( ! efl_net_ip_port_split ( str , & host , & port ) )
{
ERR ( " invalid IP:PORT address: %s " , address ) ;
free ( str ) ;
return EINVAL ;
}
if ( ! port ) port = " 0 " ;
2016-12-09 05:42:17 -08:00
if ( efl_net_ip_port_parse_split ( host , port , & want_addr ) )
2016-11-01 11:01:57 -07:00
{
Eina_Bool matches ;
if ( want_addr . ss_family ! = sock_addr . ss_family )
{
2016-11-18 06:17:08 -08:00
ERR ( " socket " SOCKET_FMT " family=%d differs from wanted %d " , fd , sock_addr . ss_family , want_addr . ss_family ) ;
2016-11-01 11:01:57 -07:00
free ( str ) ;
return EINVAL ;
}
2016-12-09 05:42:17 -08:00
else if ( want_addr . ss_family = = AF_INET6 )
matches = memcmp ( & want_addr , & sock_addr , sizeof ( struct sockaddr_in6 ) ) = = 0 ;
2016-11-01 11:01:57 -07:00
else
2016-12-09 05:42:17 -08:00
matches = memcmp ( & want_addr , & sock_addr , sizeof ( struct sockaddr_in ) ) = = 0 ;
2016-11-01 11:01:57 -07:00
if ( ! matches )
{
char buf [ INET6_ADDRSTRLEN + sizeof ( " []:65536 " ) ] = " " ;
efl_net_ip_port_fmt ( buf , sizeof ( buf ) , ( struct sockaddr * ) & sock_addr ) ;
2016-11-18 06:17:08 -08:00
ERR ( " socket " SOCKET_FMT " address %s differs from wanted %s " , fd , buf , address ) ;
2016-11-01 11:01:57 -07:00
free ( str ) ;
return EINVAL ;
}
free ( str ) ;
return 0 ;
}
else
{
/*
* NOTE : this may block , but users should be using the IP : PORT
* as numbers , getting into the fast path above .
*
* This is best - try to help API to be usable , but may
* impact the main loop execution for a while . However
* people doing bind are expected to do so on a local
* address , usually resolves faster without too many DNS
* lookups .
*/
struct addrinfo hints = {
. ai_socktype = type ,
. ai_family = family ,
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
} ;
struct addrinfo * results , * itr ;
DBG ( " resolving '%s', it may block main loop! Consider using IP:PORT " , address ) ;
do
{
x = getaddrinfo ( host , port , & hints , & results ) ;
}
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( x ! = 0 )
{
ERR ( " couldn't resolve host='%s', port='%s': %s " ,
host , port , gai_strerror ( x ) ) ;
free ( str ) ;
return EINVAL ;
}
err = EINVAL ;
for ( itr = results ; itr ! = NULL ; itr = itr - > ai_next )
{
if ( sock_addr . ss_family ! = itr - > ai_family ) continue ;
if ( memcmp ( itr - > ai_addr , & sock_addr , itr - > ai_addrlen ) = = 0 )
{
err = 0 ;
break ;
}
}
freeaddrinfo ( results ) ;
free ( str ) ;
return err ;
}
}
else
{
if ( listening ) * listening = EINA_FALSE ;
ERR ( " unsupported family=%d " , family ) ;
return EINVAL ;
}
}
# endif
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
static void
_cleanup_close ( void * data )
{
2016-10-22 16:49:01 -07:00
SOCKET * p_fd = data ;
SOCKET fd = * p_fd ;
2016-10-22 08:15:16 -07:00
* p_fd = INVALID_SOCKET ;
2016-10-22 16:49:01 -07:00
if ( fd ! = INVALID_SOCKET ) closesocket ( fd ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
2016-09-09 16:09:51 -07:00
2016-10-22 16:49:01 -07:00
SOCKET
2016-08-24 08:34:59 -07:00
efl_net_socket4 ( int domain , int type , int protocol , Eina_Bool close_on_exec )
{
2016-10-22 16:49:01 -07:00
SOCKET fd = INVALID_SOCKET ;
2016-08-24 08:34:59 -07:00
# ifdef SOCK_CLOEXEC
if ( close_on_exec ) type | = SOCK_CLOEXEC ;
# endif
fd = socket ( domain , type , protocol ) ;
2016-10-22 08:15:16 -07:00
# if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC)
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
2016-10-22 08:15:16 -07:00
if ( fd ! = INVALID_SOCKET )
2016-08-24 08:34:59 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( close_on_exec )
2016-08-24 08:34:59 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( fcntl ( fd , F_SETFD , FD_CLOEXEC ) < 0 )
{
int errno_bkp = errno ;
2016-11-18 08:14:37 -08:00
ERR ( " fcntl( " SOCKET_FMT " , F_SETFD, FD_CLOEXEC): %s " , fd , strerror ( errno ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( fd ) ;
2016-10-22 08:15:16 -07:00
fd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
errno = errno_bkp ;
}
2016-08-24 08:34:59 -07:00
}
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_POP ( EINA_FALSE ) ; /* we need fd on success */
2016-08-24 08:34:59 -07:00
# endif
return fd ;
}
2016-09-09 16:09:51 -07:00
2016-10-20 19:15:09 -07:00
typedef struct _Efl_Net_Ip_Resolve_Async_Data
{
Efl_Net_Ip_Resolve_Async_Cb cb ;
const void * data ;
char * host ;
char * port ;
struct addrinfo * result ;
struct addrinfo * hints ;
int gai_error ;
} Efl_Net_Ip_Resolve_Async_Data ;
static void
_efl_net_ip_resolve_async_run ( void * data , Ecore_Thread * thread EINA_UNUSED )
{
Efl_Net_Ip_Resolve_Async_Data * d = data ;
/* allows ecore_thread_cancel() to cancel at some points, see
* man : pthreads ( 7 ) .
*
* no need to set cleanup functions since the main thread will
* handle that with _efl_net_ip_resolve_async_cancel ( ) .
*/
eina_thread_cancellable_set ( EINA_TRUE , NULL ) ;
while ( EINA_TRUE )
{
DBG ( " resolving host='%s' port='%s' " , d - > host , d - > port ) ;
d - > gai_error = getaddrinfo ( d - > host , d - > port , d - > hints , & d - > result ) ;
if ( d - > gai_error = = 0 ) break ;
if ( d - > gai_error = = EAI_AGAIN ) continue ;
if ( ( d - > gai_error = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) continue ;
DBG ( " getaddrinfo( \" %s \" , \" %s \" ) failed: %s " , d - > host , d - > port , gai_strerror ( d - > gai_error ) ) ;
break ;
}
eina_thread_cancellable_set ( EINA_FALSE , NULL ) ;
if ( eina_log_domain_level_check ( _ecore_con_log_dom , EINA_LOG_LEVEL_DBG ) )
{
char buf [ INET6_ADDRSTRLEN + sizeof ( " []:65536 " ) ] = " " ;
const struct addrinfo * addrinfo ;
for ( addrinfo = d - > result ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
if ( efl_net_ip_port_fmt ( buf , sizeof ( buf ) , addrinfo - > ai_addr ) )
DBG ( " resolved host='%s' port='%s': %s " , d - > host , d - > port , buf ) ;
}
}
}
static void
_efl_net_ip_resolve_async_data_free ( Efl_Net_Ip_Resolve_Async_Data * d )
{
free ( d - > hints ) ;
free ( d - > host ) ;
free ( d - > port ) ;
free ( d ) ;
}
static void
_efl_net_ip_resolve_async_end ( void * data , Ecore_Thread * thread EINA_UNUSED )
{
Efl_Net_Ip_Resolve_Async_Data * d = data ;
d - > cb ( ( void * ) d - > data , d - > host , d - > port , d - > hints , d - > result , d - > gai_error ) ;
_efl_net_ip_resolve_async_data_free ( d ) ;
}
static void
_efl_net_ip_resolve_async_cancel ( void * data , Ecore_Thread * thread EINA_UNUSED )
{
Efl_Net_Ip_Resolve_Async_Data * d = data ;
if ( d - > result ) freeaddrinfo ( d - > result ) ;
_efl_net_ip_resolve_async_data_free ( d ) ;
}
Ecore_Thread *
efl_net_ip_resolve_async_new ( const char * host , const char * port , const struct addrinfo * hints , Efl_Net_Ip_Resolve_Async_Cb cb , const void * data )
{
Efl_Net_Ip_Resolve_Async_Data * d ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( host , NULL ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( port , NULL ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( cb , NULL ) ;
d = malloc ( sizeof ( Efl_Net_Ip_Resolve_Async_Data ) ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( d , NULL ) ;
d - > cb = cb ;
d - > data = data ;
d - > host = strdup ( host ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > host , failed_host ) ;
d - > port = strdup ( port ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > port , failed_port ) ;
if ( ! hints ) d - > hints = NULL ;
else
{
d - > hints = malloc ( sizeof ( struct addrinfo ) ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > hints , failed_hints ) ;
memcpy ( d - > hints , hints , sizeof ( struct addrinfo ) ) ;
}
d - > result = NULL ;
return ecore_thread_run ( _efl_net_ip_resolve_async_run ,
_efl_net_ip_resolve_async_end ,
_efl_net_ip_resolve_async_cancel ,
d ) ;
failed_hints :
free ( d - > port ) ;
failed_port :
free ( d - > host ) ;
failed_host :
free ( d ) ;
return NULL ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
typedef struct _Efl_Net_Connect_Async_Data
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Connect_Async_Cb cb ;
2016-09-09 16:09:51 -07:00
const void * data ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
socklen_t addrlen ;
Eina_Bool close_on_exec ;
int type ;
int protocol ;
2016-10-22 16:49:01 -07:00
SOCKET sockfd ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Eina_Error error ;
struct sockaddr addr [ ] ;
} Efl_Net_Connect_Async_Data ;
2016-09-09 16:09:51 -07:00
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_connect_async_run ( void * data , Ecore_Thread * thread EINA_UNUSED )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Connect_Async_Data * d = data ;
2016-11-18 06:32:16 -08:00
char buf [ INET6_ADDRSTRLEN + sizeof ( " []:65536 " )
# ifndef _WIN32
+ sizeof ( struct sockaddr_un )
# endif
] = " " ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
int r ;
2016-09-09 16:09:51 -07:00
eina/ecore: allow threads to be canceled, use in ecore_con.
As discussed in the mailing list, many people will use worker threads
to execute blocking syscalls and mandating ecore_thread_check() for
voluntary preemption reduces the ecore_thread usefulness a lot.
A clear example is ecore_con usage of connect() and getaddrinfo() in
threads. If the connect timeout expires, the thread will be cancelled,
but it was blocked on syscalls and they will hang around for long
time. If the application exits, ecore will print an error saying it
can SEGV.
Then enable access to pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)
via eina_thread_cancellable_set(EINA_TRUE), to pthread_cancel() via
eina_thread_cancel(), to pthread_cleanup_push()/pthread_cleanup_pop()
via EINA_THREAD_CLEANUP_PUSH()/EINA_THREAD_CLEANUP_POP() and so on.
Ecore threads will enforce non-cancellable threads on its own code,
but the user may decide to enable that and allow cancellation, that's
not an issue since ecore_thread now plays well and use cleanup
functions.
Ecore con connect/resolve make use of that and enable cancellable
state, efl_net_dialer_tcp benefits a lot from that.
A good comparison of the benefit is to run:
./src/examples/ecore/efl_io_copier_example tcp://google.com:1234 :stdout:
before and after. It will timeout after 30s and with this patch the
thread is gone, no ecore error is printed about possible SEGV.
2016-09-13 21:38:58 -07:00
/* allows ecore_thread_cancel() to cancel at some points, see
* man : pthreads ( 7 ) .
*
* no need to set cleanup functions since the main thread will
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
* handle that with _efl_net_connect_async_cancel ( ) .
eina/ecore: allow threads to be canceled, use in ecore_con.
As discussed in the mailing list, many people will use worker threads
to execute blocking syscalls and mandating ecore_thread_check() for
voluntary preemption reduces the ecore_thread usefulness a lot.
A clear example is ecore_con usage of connect() and getaddrinfo() in
threads. If the connect timeout expires, the thread will be cancelled,
but it was blocked on syscalls and they will hang around for long
time. If the application exits, ecore will print an error saying it
can SEGV.
Then enable access to pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)
via eina_thread_cancellable_set(EINA_TRUE), to pthread_cancel() via
eina_thread_cancel(), to pthread_cleanup_push()/pthread_cleanup_pop()
via EINA_THREAD_CLEANUP_PUSH()/EINA_THREAD_CLEANUP_POP() and so on.
Ecore threads will enforce non-cancellable threads on its own code,
but the user may decide to enable that and allow cancellation, that's
not an issue since ecore_thread now plays well and use cleanup
functions.
Ecore con connect/resolve make use of that and enable cancellable
state, efl_net_dialer_tcp benefits a lot from that.
A good comparison of the benefit is to run:
./src/examples/ecore/efl_io_copier_example tcp://google.com:1234 :stdout:
before and after. It will timeout after 30s and with this patch the
thread is gone, no ecore error is printed about possible SEGV.
2016-09-13 21:38:58 -07:00
*/
eina_thread_cancellable_set ( EINA_TRUE , NULL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d - > error = 0 ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
/* always close-on-exec since it's not a point to pass an
* under construction socket to a child process .
*/
d - > sockfd = efl_net_socket4 ( d - > addr - > sa_family , d - > type , d - > protocol , EINA_TRUE ) ;
2016-10-22 08:15:16 -07:00
if ( d - > sockfd = = INVALID_SOCKET )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
2016-10-22 08:15:16 -07:00
d - > error = efl_net_socket_error_get ( ) ;
DBG ( " socket(%d, %d, %d) failed: %s " , d - > addr - > sa_family , d - > type , d - > protocol , eina_error_msg_get ( d - > error ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
return ;
2016-09-09 16:09:51 -07:00
}
if ( eina_log_domain_level_check ( _ecore_con_log_dom , EINA_LOG_LEVEL_DBG ) )
2016-10-26 13:57:37 -07:00
{
2016-10-27 04:01:19 -07:00
# ifndef _WIN32
2016-10-26 13:57:37 -07:00
if ( d - > addr - > sa_family = = AF_UNIX )
efl_net_unix_fmt ( buf , sizeof ( buf ) , d - > sockfd , ( const struct sockaddr_un * ) d - > addr , d - > addrlen ) ;
else
2016-10-27 04:01:19 -07:00
# endif
2016-10-26 13:57:37 -07:00
efl_net_ip_port_fmt ( buf , sizeof ( buf ) , d - > addr ) ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
2016-11-18 06:17:08 -08:00
DBG ( " connecting fd= " SOCKET_FMT " to %s " , d - > sockfd , buf ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
r = connect ( d - > sockfd , d - > addr , d - > addrlen ) ;
2016-10-22 08:15:16 -07:00
if ( r ! = 0 )
2016-09-09 16:09:51 -07:00
{
2016-10-22 16:49:01 -07:00
SOCKET fd = d - > sockfd ;
2016-10-22 08:15:16 -07:00
d - > error = efl_net_socket_error_get ( ) ;
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
/* close() is a cancellation point, thus unset sockfd before
* closing , so the main thread _efl_net_connect_async_cancel ( )
* won ' t close it again .
*/
2016-10-22 16:49:01 -07:00
closesocket ( fd ) ;
2016-11-18 06:17:08 -08:00
DBG ( " connect( " SOCKET_FMT " , %s) failed: %s " , fd , buf , eina_error_msg_get ( d - > error ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
return ;
2016-09-09 16:09:51 -07:00
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
2016-11-18 06:17:08 -08:00
DBG ( " connected fd= " SOCKET_FMT " to %s " , d - > sockfd , buf ) ;
2016-09-09 16:09:51 -07:00
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_connect_async_data_free ( Efl_Net_Connect_Async_Data * d )
2016-09-09 16:09:51 -07:00
{
free ( d ) ;
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_connect_async_end ( void * data , Ecore_Thread * thread EINA_UNUSED )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Connect_Async_Data * d = data ;
# ifdef FD_CLOEXEC
/* if it wasn't a close on exec, release the socket to be passed to child */
2016-10-22 08:15:16 -07:00
if ( ( ! d - > close_on_exec ) & & ( d - > sockfd ! = INVALID_SOCKET ) )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
int flags = fcntl ( d - > sockfd , F_GETFD ) ;
if ( flags < 0 )
{
d - > error = errno ;
2016-11-18 06:17:08 -08:00
ERR ( " fcntl( " SOCKET_FMT " , F_GETFD): %s " , d - > sockfd , eina_error_msg_get ( d - > error ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( d - > sockfd ) ;
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
else
{
flags & = ( ~ FD_CLOEXEC ) ;
if ( fcntl ( d - > sockfd , F_SETFD , flags ) < 0 )
{
d - > error = errno ;
2016-11-18 06:17:08 -08:00
ERR ( " fcntl( " SOCKET_FMT " , F_SETFD, %#x): %s " , d - > sockfd , flags , eina_error_msg_get ( d - > error ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( d - > sockfd ) ;
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
# endif
d - > cb ( ( void * ) d - > data , d - > addr , d - > addrlen , d - > sockfd , d - > error ) ;
_efl_net_connect_async_data_free ( d ) ;
2016-09-09 16:09:51 -07:00
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_connect_async_cancel ( void * data , Ecore_Thread * thread EINA_UNUSED )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Connect_Async_Data * d = data ;
2016-10-22 16:49:01 -07:00
if ( d - > sockfd ! = INVALID_SOCKET ) closesocket ( d - > sockfd ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_connect_async_data_free ( d ) ;
2016-09-09 16:09:51 -07:00
}
Ecore_Thread *
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
efl_net_connect_async_new ( const struct sockaddr * addr , socklen_t addrlen , int type , int protocol , Eina_Bool close_on_exec , Efl_Net_Connect_Async_Cb cb , const void * data )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Connect_Async_Data * d ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( addr , NULL ) ;
EINA_SAFETY_ON_TRUE_RETURN_VAL ( addrlen < 1 , NULL ) ;
2016-09-09 16:09:51 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( cb , NULL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d = malloc ( sizeof ( Efl_Net_Connect_Async_Data ) + addrlen ) ;
2016-09-09 16:09:51 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( d , NULL ) ;
d - > cb = cb ;
d - > data = data ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d - > addrlen = addrlen ;
d - > close_on_exec = close_on_exec ;
d - > type = type ;
d - > protocol = protocol ;
memcpy ( d - > addr , addr , addrlen ) ;
2016-09-09 16:09:51 -07:00
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d - > error = 0 ;
return ecore_thread_run ( _efl_net_connect_async_run ,
_efl_net_connect_async_end ,
_efl_net_connect_async_cancel ,
d ) ;
}
static Eina_Bool
_efl_net_ip_no_proxy ( const char * host , char * const * no_proxy_strv )
{
char * const * itr ;
size_t host_len ;
if ( ! no_proxy_strv )
return EINA_FALSE ;
host_len = strlen ( host ) ;
for ( itr = no_proxy_strv ; * itr ! = NULL ; itr + + )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
const char * s = * itr ;
size_t slen ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
/* '*' is not a glob/pattern, it matches all */
if ( * s = = ' * ' ) return EINA_TRUE ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
/* old timers use leading dot to avoid matching partial names
* due implementation bugs not required anymore
*/
if ( * s = = ' . ' ) s + + ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
slen = strlen ( s ) ;
if ( slen = = 0 ) continue ;
if ( host_len < slen ) continue ;
if ( memcmp ( host + host_len - slen , s , slen ) = = 0 )
{
if ( slen = = host_len )
return EINA_TRUE ;
if ( host [ host_len - slen - 1 ] = = ' . ' )
return EINA_TRUE ;
}
}
return EINA_FALSE ;
2016-09-09 16:09:51 -07:00
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
typedef struct _Efl_Net_Ip_Connect_Async_Data
2016-09-09 16:09:51 -07:00
{
Efl_Net_Connect_Async_Cb cb ;
const void * data ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
char * address ;
char * proxy ;
char * proxy_env ;
char * * no_proxy_strv ;
2016-09-09 16:09:51 -07:00
socklen_t addrlen ;
Eina_Bool close_on_exec ;
int type ;
int protocol ;
2016-10-22 16:49:01 -07:00
SOCKET sockfd ;
2016-09-09 16:09:51 -07:00
Eina_Error error ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
union {
struct sockaddr_in addr4 ;
struct sockaddr_in6 addr6 ;
struct sockaddr addr ;
} ;
} Efl_Net_Ip_Connect_Async_Data ;
static Eina_Error
2016-11-18 06:17:08 -08:00
_efl_net_ip_connect ( const struct addrinfo * addr , SOCKET * sockfd )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
2016-10-22 16:49:01 -07:00
SOCKET fd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Eina_Error ret = 0 ;
/* always close-on-exec since it's not a point to pass an
* under construction socket to a child process .
*/
fd = efl_net_socket4 ( addr - > ai_family , addr - > ai_socktype , addr - > ai_protocol , EINA_TRUE ) ;
2016-10-22 08:15:16 -07:00
if ( fd = = INVALID_SOCKET ) ret = efl_net_socket_error_get ( ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
char buf [ INET6_ADDRSTRLEN + sizeof ( " []:65536 " ) ] = " " ;
int r ;
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
if ( eina_log_domain_level_check ( _ecore_con_log_dom , EINA_LOG_LEVEL_DBG ) )
{
if ( efl_net_ip_port_fmt ( buf , sizeof ( buf ) , addr - > ai_addr ) )
2016-11-18 06:17:08 -08:00
DBG ( " connect fd= " SOCKET_FMT " to %s " , fd , buf ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
r = connect ( fd , addr - > ai_addr , addr - > ai_addrlen ) ;
if ( r = = 0 )
{
2016-11-18 06:17:08 -08:00
DBG ( " connected fd= " SOCKET_FMT " to %s " , fd , buf ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
* sockfd = fd ;
}
else
{
2016-10-22 08:15:16 -07:00
ret = efl_net_socket_error_get ( ) ;
2016-11-18 06:17:08 -08:00
DBG ( " couldn't connect fd= " SOCKET_FMT " to %s: %s " , fd , buf , eina_error_msg_get ( ret ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( fd ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
EINA_THREAD_CLEANUP_POP ( EINA_FALSE ) ; /* we need sockfd on success */
}
return ret ;
}
static Eina_Error
2016-11-18 06:17:08 -08:00
_efl_net_ip_resolve_and_connect ( const char * host , const char * port , int type , int protocol , SOCKET * sockfd , struct sockaddr * addr , socklen_t * p_addrlen )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
struct addrinfo * results = NULL ;
struct addrinfo hints = {
. ai_socktype = type ,
. ai_protocol = protocol ,
. ai_family = AF_UNSPEC ,
2016-10-22 04:41:26 -07:00
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
} ;
Eina_Error ret = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
int r ;
if ( strchr ( host , ' : ' ) ) hints . ai_family = AF_INET6 ;
do
r = getaddrinfo ( host , port , & hints , & results ) ;
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( r ! = 0 )
{
DBG ( " couldn't resolve host='%s', port='%s': %s " ,
host , port , gai_strerror ( r ) ) ;
ret = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST ;
2016-10-22 08:15:16 -07:00
* sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
else
{
const struct addrinfo * addrinfo ;
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) freeaddrinfo , results ) ;
for ( addrinfo = results ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
if ( addrinfo - > ai_socktype ! = type ) continue ;
if ( addrinfo - > ai_protocol ! = protocol ) continue ;
ret = _efl_net_ip_connect ( addrinfo , sockfd ) ;
if ( ret = = 0 )
{
memcpy ( addr , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
* p_addrlen = addrinfo - > ai_addrlen ;
break ;
}
}
if ( ret ! = 0 )
2016-12-09 06:08:29 -08:00
{
if ( results )
{
memcpy ( addr , results - > ai_addr , results - > ai_addrlen ) ;
* p_addrlen = results - > ai_addrlen ;
}
ret = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ;
}
return ret ;
}
2016-09-09 16:09:51 -07:00
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_ip_connect_async_run_direct ( Efl_Net_Ip_Connect_Async_Data * d , const char * host , const char * port )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
DBG ( " direct connection to %s:%s " , host , port ) ;
d - > error = _efl_net_ip_resolve_and_connect ( host , port , d - > type , d - > protocol , & d - > sockfd , & d - > addr , & d - > addrlen ) ;
}
static Eina_Bool
_efl_net_ip_port_user_pass_split ( char * buf , const char * * p_host , const char * * p_port , const char * * p_user , const char * * p_pass )
{
char * p ;
p = strchr ( buf , ' @ ' ) ;
if ( ! p )
{
p = buf ;
* p_user = NULL ;
* p_pass = NULL ;
}
else
{
char * s ;
* p_user = buf ;
* p = ' \0 ' ;
p + + ;
s = strchr ( * p_user , ' : ' ) ;
if ( ! s )
* p_pass = NULL ;
else
{
* s = ' \0 ' ;
s + + ;
* p_pass = s ;
}
}
return efl_net_ip_port_split ( p , p_host , p_port ) ;
}
typedef enum _Efl_Net_Socks4_Request_Command {
EFL_NET_SOCKS4_REQUEST_COMMAND_CONNECT = 0x01 ,
EFL_NET_SOCKS4_REQUEST_COMMAND_BIND = 0x02
} Efl_Net_Socks4_Request_Command ;
typedef struct _Efl_Net_Socks4_Request {
uint8_t version ; /* = 0x4 */
uint8_t command ; /* Efl_Net_Socks4_Request_Command */
uint16_t port ;
uint8_t ipv4 [ 4 ] ;
char indent [ ] ;
} Efl_Net_Socks4_Request ;
typedef enum _Efl_Net_Socks4_Reply_Status {
EFL_NET_SOCKS4_REPLY_STATUS_GRANTED = 0x5a ,
EFL_NET_SOCKS4_REPLY_STATUS_REJECTED = 0x5b ,
EFL_NET_SOCKS4_REPLY_STATUS_FAILED_INDENT = 0x5c ,
EFL_NET_SOCKS4_REPLY_STATUS_FAILED_USER = 0x5d
} Efl_Net_Socks4_Reply_Status ;
typedef struct _Efl_Net_Socks4_Reply {
uint8_t null ;
uint8_t status ;
uint16_t port ;
uint8_t ipv4 [ 4 ] ;
} Efl_Net_Socks4_Reply ;
static Eina_Bool
_efl_net_ip_connect_async_run_socks4_try ( Efl_Net_Ip_Connect_Async_Data * d , const char * proxy_host , const char * proxy_port , const struct addrinfo * addrinfo , Efl_Net_Socks4_Request * request , size_t request_len )
{
char buf [ INET_ADDRSTRLEN + sizeof ( " :65536 " ) ] ;
struct sockaddr_in * a = ( struct sockaddr_in * ) addrinfo - > ai_addr ;
struct sockaddr_storage proxy_addr ;
socklen_t proxy_addrlen ;
2016-10-22 16:49:01 -07:00
SOCKET fd ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Eina_Error err ;
Eina_Bool ret = EINA_FALSE ;
ssize_t s ;
err = _efl_net_ip_resolve_and_connect ( proxy_host , proxy_port , SOCK_STREAM , IPPROTO_TCP , & fd , ( struct sockaddr * ) & proxy_addr , & proxy_addrlen ) ;
if ( err )
{
DBG ( " couldn't connect to socks4://%s:%s: %s " , proxy_host , proxy_port , eina_error_msg_get ( err ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
return EINA_TRUE ; /* no point in continuing on this error */
}
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
if ( eina_log_domain_level_check ( _ecore_con_log_dom , EINA_LOG_LEVEL_DBG ) )
{
if ( efl_net_ip_port_fmt ( buf , sizeof ( buf ) , addrinfo - > ai_addr ) )
2016-11-18 06:17:08 -08:00
DBG ( " resolved address='%s' to %s. Connect using fd= " SOCKET_FMT " socks4://%s:%s " , d - > address , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
request - > port = a - > sin_port ;
memcpy ( request - > ipv4 , & a - > sin_addr , 4 ) ;
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) request , request_len , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) request_len )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't request connection to host=%s fd= " SOCKET_FMT " socks4://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , request_len , s ) ;
}
else
{
Efl_Net_Socks4_Reply reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv reply of connection to host=%s fd= " SOCKET_FMT " socks4://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( reply ) , s ) ;
}
else
{
if ( reply . status ! = EFL_NET_SOCKS4_REPLY_STATUS_GRANTED )
2016-11-18 06:17:08 -08:00
DBG ( " rejected connection to host=%s fd= " SOCKET_FMT " socks4://%s:%s: reason=%#x " , buf , fd , proxy_host , proxy_port , reply . status ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
memcpy ( & d - > addr , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
d - > addrlen = addrinfo - > ai_addrlen ;
d - > sockfd = fd ;
d - > error = 0 ;
ret = EINA_TRUE ;
2016-11-18 06:17:08 -08:00
DBG ( " connected to host=%s fd= " SOCKET_FMT " socks4://%s:%s " , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
EINA_THREAD_CLEANUP_POP ( ! ret ) ; /* we need fd on success, on failure just close it */
return ret ;
}
static void
_efl_net_ip_connect_async_run_socks4 ( Efl_Net_Ip_Connect_Async_Data * d , const char * host , const char * port , const char * proxy )
{
char * str ;
const char * proxy_user , * proxy_pass , * proxy_host , * proxy_port ;
struct addrinfo * results = NULL ;
struct addrinfo hints = {
. ai_socktype = d - > type ,
. ai_protocol = d - > protocol ,
. ai_family = AF_INET ,
2016-10-22 04:41:26 -07:00
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
} ;
2016-09-09 16:09:51 -07:00
int r ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( strchr ( host , ' : ' ) )
{
DBG ( " SOCKSv4 only handles IPv4. Wanted host=%s " , host ) ;
d - > error = EAFNOSUPPORT ;
return ;
}
eina/ecore: allow threads to be canceled, use in ecore_con.
As discussed in the mailing list, many people will use worker threads
to execute blocking syscalls and mandating ecore_thread_check() for
voluntary preemption reduces the ecore_thread usefulness a lot.
A clear example is ecore_con usage of connect() and getaddrinfo() in
threads. If the connect timeout expires, the thread will be cancelled,
but it was blocked on syscalls and they will hang around for long
time. If the application exits, ecore will print an error saying it
can SEGV.
Then enable access to pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)
via eina_thread_cancellable_set(EINA_TRUE), to pthread_cancel() via
eina_thread_cancel(), to pthread_cleanup_push()/pthread_cleanup_pop()
via EINA_THREAD_CLEANUP_PUSH()/EINA_THREAD_CLEANUP_POP() and so on.
Ecore threads will enforce non-cancellable threads on its own code,
but the user may decide to enable that and allow cancellation, that's
not an issue since ecore_thread now plays well and use cleanup
functions.
Ecore con connect/resolve make use of that and enable cancellable
state, efl_net_dialer_tcp benefits a lot from that.
A good comparison of the benefit is to run:
./src/examples/ecore/efl_io_copier_example tcp://google.com:1234 :stdout:
before and after. It will timeout after 30s and with this patch the
thread is gone, no ecore error is printed about possible SEGV.
2016-09-13 21:38:58 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( ( d - > type ! = SOCK_STREAM ) | | ( d - > protocol ! = IPPROTO_TCP ) )
{
DBG ( " SOCKSv4 only accepts TCP requests. Wanted type=%#x, protocol=%#x " , d - > type , d - > protocol ) ;
d - > error = EPROTONOSUPPORT ;
return ;
}
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
DBG ( " proxy connection to %s:%s using socks4://%s " , host , port , proxy ) ;
str = strdup ( proxy ) ;
EINA_THREAD_CLEANUP_PUSH ( free , str ) ;
if ( ! _efl_net_ip_port_user_pass_split ( str , & proxy_host , & proxy_port , & proxy_user , & proxy_pass ) )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
ERR ( " Invalid proxy string: socks4://%s " , proxy ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
if ( ! proxy_user ) proxy_user = " " ;
if ( ! proxy_port ) proxy_port = " 1080 " ;
do
r = getaddrinfo ( host , port , & hints , & results ) ;
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( r ! = 0 )
{
DBG ( " couldn't resolve host='%s', port='%s': %s " ,
host , port , gai_strerror ( r ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST ;
}
else
{
const struct addrinfo * addrinfo ;
Efl_Net_Socks4_Request * request ;
size_t request_len ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) freeaddrinfo , results ) ;
request_len = sizeof ( Efl_Net_Socks4_Request ) + strlen ( proxy_user ) + 1 ;
request = malloc ( request_len ) ;
if ( request )
{
request - > version = 0x04 ;
request - > command = EFL_NET_SOCKS4_REQUEST_COMMAND_CONNECT ;
memcpy ( request - > indent , proxy_user , strlen ( proxy_user ) + 1 ) ;
EINA_THREAD_CLEANUP_PUSH ( free , request ) ;
for ( addrinfo = results ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
if ( addrinfo - > ai_socktype ! = d - > type ) continue ;
if ( addrinfo - > ai_protocol ! = d - > protocol ) continue ;
if ( addrinfo - > ai_family ! = AF_INET ) continue ;
if ( _efl_net_ip_connect_async_run_socks4_try ( d , proxy_host , proxy_port , addrinfo , request , request_len ) )
break ;
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(request) */
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* freeaddrinfo(results) */
}
end :
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(str) */
}
static void
_efl_net_ip_connect_async_run_socks4a ( Efl_Net_Ip_Connect_Async_Data * d , const char * host , const char * port , const char * proxy )
{
2016-10-22 16:49:01 -07:00
SOCKET fd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
char * str ;
const char * proxy_user , * proxy_pass , * proxy_host , * proxy_port ;
struct sockaddr_storage proxy_addr ;
socklen_t proxy_addrlen ;
Eina_Error err ;
struct addrinfo * results = NULL ;
struct addrinfo hints = {
. ai_socktype = d - > type ,
. ai_protocol = d - > protocol ,
. ai_family = AF_INET ,
2016-10-22 04:41:26 -07:00
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
} ;
int r ;
if ( strchr ( host , ' : ' ) )
{
DBG ( " SOCKSv4 only handles IPv4. Wanted host=%s " , host ) ;
d - > error = EAFNOSUPPORT ;
2016-09-09 16:09:51 -07:00
return ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( ( d - > type ! = SOCK_STREAM ) | | ( d - > protocol ! = IPPROTO_TCP ) )
{
DBG ( " SOCKSv4 only accepts TCP requests. Wanted type=%#x, protocol=%#x " , d - > type , d - > protocol ) ;
d - > error = EPROTONOSUPPORT ;
return ;
}
DBG ( " proxy connection to %s:%s using socks4a://%s " , host , port , proxy ) ;
str = strdup ( proxy ) ;
EINA_THREAD_CLEANUP_PUSH ( free , str ) ;
if ( ! _efl_net_ip_port_user_pass_split ( str , & proxy_host , & proxy_port , & proxy_user , & proxy_pass ) )
{
ERR ( " Invalid proxy string: socks4a://%s " , proxy ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
if ( ! proxy_user ) proxy_user = " " ;
if ( ! proxy_port ) proxy_port = " 1080 " ;
err = _efl_net_ip_resolve_and_connect ( proxy_host , proxy_port , SOCK_STREAM , IPPROTO_TCP , & fd , ( struct sockaddr * ) & proxy_addr , & proxy_addrlen ) ;
if ( err )
{
DBG ( " couldn't connect to socks4a://%s: %s " , proxy , eina_error_msg_get ( err ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
2016-11-18 06:17:08 -08:00
DBG ( " connected fd= " SOCKET_FMT " to socks4a://%s " , fd , proxy ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
/* we just resolve the port number here */
do
r = getaddrinfo ( NULL , port , & hints , & results ) ;
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( r ! = 0 )
{
DBG ( " couldn't resolve port='%s': %s " , port , gai_strerror ( r ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST ;
}
else
{
const struct addrinfo * addrinfo ;
Efl_Net_Socks4_Request * request ;
size_t request_len ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) freeaddrinfo , results ) ;
request_len = sizeof ( Efl_Net_Socks4_Request ) + strlen ( proxy_user ) + 1 + strlen ( host ) + 1 ;
request = malloc ( request_len ) ;
if ( request )
{
request - > version = 0x04 ;
request - > command = EFL_NET_SOCKS4_REQUEST_COMMAND_CONNECT ;
memcpy ( request - > indent , proxy_user , strlen ( proxy_user ) + 1 ) ;
memcpy ( request - > indent + strlen ( proxy_user ) + 1 , host , strlen ( host ) + 1 ) ;
EINA_THREAD_CLEANUP_PUSH ( free , request ) ;
for ( addrinfo = results ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
struct sockaddr_in * a = ( struct sockaddr_in * ) addrinfo - > ai_addr ;
ssize_t s ;
if ( addrinfo - > ai_socktype ! = d - > type ) continue ;
if ( addrinfo - > ai_protocol ! = d - > protocol ) continue ;
if ( addrinfo - > ai_family ! = AF_INET ) continue ;
request - > port = a - > sin_port ;
request - > ipv4 [ 0 ] = 0 ;
request - > ipv4 [ 1 ] = 0 ;
request - > ipv4 [ 2 ] = 0 ;
request - > ipv4 [ 3 ] = 255 ;
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) request , request_len , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) request_len )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
DBG ( " couldn't send proxy request: %s " , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , request_len , s ) ;
}
else
{
Efl_Net_Socks4_Reply reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
DBG ( " couldn't recv proxy reply: %s " , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( reply ) , s ) ;
}
else
{
if ( reply . status ! = EFL_NET_SOCKS4_REPLY_STATUS_GRANTED )
DBG ( " proxy rejected request status=%#x " , reply . status ) ;
else
{
d - > addr4 . sin_family = AF_INET ;
d - > addr4 . sin_port = a - > sin_port ;
memcpy ( & d - > addr4 . sin_addr , reply . ipv4 , 4 ) ;
d - > addrlen = sizeof ( struct sockaddr_in ) ;
d - > sockfd = fd ;
d - > error = 0 ;
}
}
}
break ;
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(request) */
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* freeaddrinfo(results) */
}
2016-11-18 06:17:08 -08:00
EINA_THREAD_CLEANUP_POP ( d - > sockfd = = INVALID_SOCKET ) ; /* we need fd only on success */
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
end :
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(str) */
}
typedef enum _Efl_Net_Socks5_Auth {
EFL_NET_SOCKS5_AUTH_NONE = 0x00 ,
EFL_NET_SOCKS5_AUTH_GSSAPI = 0x01 ,
EFL_NET_SOCKS5_AUTH_USER_PASS = 0x02 ,
EFL_NET_SOCKS5_AUTH_FAILED = 0xff
} Efl_Net_Socks5_Auth ;
typedef struct _Efl_Net_Socks5_Greeting {
uint8_t version ; /* = 0x5 */
uint8_t auths_count ;
uint8_t auths [ 1 ] ; /* series of Efl_Net_Socks5_Auth */
} Efl_Net_Socks5_Greeting ;
typedef struct _Efl_Net_Socks5_Greeting_Reply {
uint8_t version ; /* = 0x5 */
uint8_t auth ; /* Efl_Net_Socks5_Auth */
} Efl_Net_Socks5_Greeting_Reply ;
typedef enum _Efl_Net_Socks5_Request_Command {
EFL_NET_SOCKS5_REQUEST_COMMAND_TCP_CONNECT = 0x01 ,
EFL_NET_SOCKS5_REQUEST_COMMAND_TCP_BIND = 0x02 ,
EFL_NET_SOCKS5_REQUEST_COMMAND_UDP_ASSOCIATE = 0x03
} Efl_Net_Socks5_Request_Command ;
typedef enum _Efl_Net_Socks5_Address_Type {
EFL_NET_SOCKS5_ADDRESS_TYPE_IPV4 = 0x01 ,
EFL_NET_SOCKS5_ADDRESS_TYPE_NAME = 0x03 ,
EFL_NET_SOCKS5_ADDRESS_TYPE_IPV6 = 0x04
} Efl_Net_Socks5_Address_Type ;
typedef struct _Efl_Net_Socks5_Request {
uint8_t version ; /* = 0x5 */
uint8_t command ; /* Efl_Net_Socks5_Command */
uint8_t reserved ;
uint8_t address_type ; /* Efl_Net_Socks5_Address_Type */
/* follows:
* - one of :
* - 4 bytes for IPv4
* - 16 bytes for IPv6
* - 1 byte ( size ) + N bytes of name
* - uint16_t port
*/
} Efl_Net_Socks5_Request ;
typedef struct _Efl_Net_Socks5_Address_Ipv4 {
uint8_t address [ 4 ] ;
uint16_t port ;
} Efl_Net_Socks5_Address_Ipv4 ;
typedef struct _Efl_Net_Socks5_Address_Ipv6 {
uint8_t address [ 16 ] ;
uint16_t port ;
} Efl_Net_Socks5_Address_Ipv6 ;
typedef struct _Efl_Net_Socks5_Request_Ipv4 {
Efl_Net_Socks5_Request base ;
Efl_Net_Socks5_Address_Ipv4 ipv4 ;
} Efl_Net_Socks5_Request_Ipv4 ;
typedef struct _Efl_Net_Socks5_Request_Ipv6 {
Efl_Net_Socks5_Request base ;
Efl_Net_Socks5_Address_Ipv6 ipv6 ;
} Efl_Net_Socks5_Request_Ipv6 ;
static Efl_Net_Socks5_Request *
efl_net_socks5_request_addr_new ( Efl_Net_Socks5_Request_Command command , const struct sockaddr * addr , size_t * p_request_len )
{
if ( addr - > sa_family = = AF_INET )
{
const struct sockaddr_in * a = ( const struct sockaddr_in * ) addr ;
Efl_Net_Socks5_Request_Ipv4 * request ;
* p_request_len = sizeof ( Efl_Net_Socks5_Request_Ipv4 ) ;
request = malloc ( * p_request_len ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( request , NULL ) ;
request - > base . version = 0x05 ;
request - > base . command = command ;
request - > base . reserved = 0 ;
request - > base . address_type = EFL_NET_SOCKS5_ADDRESS_TYPE_IPV4 ;
memcpy ( request - > ipv4 . address , & a - > sin_addr , 4 ) ;
request - > ipv4 . port = a - > sin_port ;
return & request - > base ;
}
else
{
const struct sockaddr_in6 * a = ( const struct sockaddr_in6 * ) addr ;
Efl_Net_Socks5_Request_Ipv6 * request ;
* p_request_len = sizeof ( Efl_Net_Socks5_Request_Ipv6 ) ;
request = malloc ( * p_request_len ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( request , NULL ) ;
request - > base . version = 0x05 ;
request - > base . command = command ;
request - > base . reserved = 0 ;
request - > base . address_type = EFL_NET_SOCKS5_ADDRESS_TYPE_IPV6 ;
memcpy ( request - > ipv6 . address , & a - > sin6_addr , 16 ) ;
request - > ipv6 . port = a - > sin6_port ;
return & request - > base ;
}
}
/* port must be network endianess */
static Efl_Net_Socks5_Request *
efl_net_socks5_request_name_new ( Efl_Net_Socks5_Request_Command command , const char * name , uint16_t port , size_t * p_request_len )
{
Efl_Net_Socks5_Request * request ;
uint8_t namelen = strlen ( name ) ;
uint8_t * p ;
* p_request_len = sizeof ( Efl_Net_Socks5_Request ) + 1 + namelen + 2 ;
request = malloc ( * p_request_len ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( request , NULL ) ;
request - > version = 0x05 ;
request - > command = command ;
request - > reserved = 0 ;
request - > address_type = EFL_NET_SOCKS5_ADDRESS_TYPE_NAME ;
p = ( uint8_t * ) request + sizeof ( Efl_Net_Socks5_Request ) ;
* p = namelen ;
p + + ;
memcpy ( p , name , namelen ) ;
p + = namelen ;
memcpy ( p , & port , sizeof ( port ) ) ;
return request ;
}
typedef enum _Efl_Net_Socks5_Reply_Status {
EFL_NET_SOCKS5_REPLY_STATUS_GRANTED = 0x00 ,
EFL_NET_SOCKS5_REPLY_STATUS_GENERAL_FAILURE = 0x01 ,
EFL_NET_SOCKS5_REPLY_STATUS_REJECTED_BY_RULESET = 0x02 ,
EFL_NET_SOCKS5_REPLY_STATUS_NETWORK_UNREACHABLE = 0x03 ,
EFL_NET_SOCKS5_REPLY_STATUS_HOST_UNREACHABLE = 0x04 ,
EFL_NET_SOCKS5_REPLY_STATUS_CONNECTION_REFUSED = 0x05 ,
EFL_NET_SOCKS5_REPLY_STATUS_TTL_EXPIRED = 0x06 ,
EFL_NET_SOCKS5_REPLY_STATUS_PROTOCOL_ERROR = 0x07 ,
EFL_NET_SOCKS5_REPLY_STATUS_ADDRESS_TYPE_UNSUPORTED = 0x08 ,
} Efl_Net_Socks5_Reply_Status ;
typedef struct _Efl_Net_Socks5_Reply {
uint8_t version ; /* = 0x5 */
uint8_t status ;
uint8_t null ; /* = 0 */
uint8_t address_type ; /* Efl_Net_Socks5_Address_Type */
/* follows:
* - one of :
* - 4 bytes for IPv4
* - 16 bytes for IPv6
* - 1 byte ( size ) + N bytes name
* - uint16_t port
*/
} Efl_Net_Socks5_Reply ;
typedef struct _Efl_Net_Socks5_Reply_Ipv4 {
Efl_Net_Socks5_Reply base ;
Efl_Net_Socks5_Address_Ipv4 ipv4 ;
} Efl_Net_Socks5_Reply_Ipv4 ;
typedef struct _Efl_Net_Socks5_Reply_Ipv6 {
Efl_Net_Socks5_Reply base ;
Efl_Net_Socks5_Address_Ipv6 ipv6 ;
} Efl_Net_Socks5_Reply_Ipv6 ;
static Eina_Bool
2016-10-22 16:49:01 -07:00
_efl_net_ip_connect_async_run_socks5_auth_user_pass ( SOCKET fd , const char * user , const char * pass , const char * proxy_protocol , const char * proxy_host , const char * proxy_port )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
uint8_t user_len = user ? strlen ( user ) : 0 ;
uint8_t pass_len = pass ? strlen ( pass ) : 0 ;
size_t len = 1 + 1 + user_len + 1 + pass_len ;
char * msg ;
Eina_Bool ret = EINA_FALSE ;
ssize_t s ;
msg = malloc ( len ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( msg , EINA_FALSE ) ;
EINA_THREAD_CLEANUP_PUSH ( free , msg ) ;
msg [ 0 ] = 0x01 ; /* version */
msg [ 1 ] = user_len ;
if ( user ) memcpy ( msg + 1 + 1 , user , user_len ) ;
msg [ 1 + 1 + user_len ] = pass_len ;
if ( pass ) memcpy ( msg + 1 + 1 + user_len + 1 , pass , pass_len ) ;
DBG ( " authenticate user='%s' pass=%hhu (bytes) to proxy %s://%s:%s " , user , pass_len , proxy_protocol , proxy_host , proxy_port ) ;
s = send ( fd , msg , len , MSG_NOSIGNAL ) ;
if ( s ! = ( ssize_t ) len )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't send user-password authentication to fd= " SOCKET_FMT " %s://%s:%s: %s " , fd , proxy_protocol , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send user-password authentication: need %zu, did %zd " , len , s ) ;
}
else
{
uint8_t reply [ 2 ] ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv user-password authentication reply from fd= " SOCKET_FMT " %s://%s:%s: %s " , fd , proxy_protocol , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv user-password authentication reply: need %zu, did %zd " , len , s ) ;
}
else
{
if ( reply [ 1 ] ! = 0 )
DBG ( " proxy authentication failed user='%s' pass=%hhu (bytes) to proxy %s://%s:%s: reason=%#x " , user , pass_len , proxy_protocol , proxy_host , proxy_port , reply [ 1 ] ) ;
else
{
2016-11-18 06:17:08 -08:00
DBG ( " successfully authenticated user=%s with proxy fd= " SOCKET_FMT " %s://%s:%s " , user , fd , proxy_protocol , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
ret = EINA_TRUE ;
}
}
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ;
return ret ;
}
static Eina_Bool
_efl_net_ip_connect_async_run_socks5_try ( Efl_Net_Ip_Connect_Async_Data * d , const char * proxy_host , const char * proxy_port , const char * proxy_user , const char * proxy_pass , Efl_Net_Socks5_Request_Command cmd , const struct addrinfo * addrinfo )
{
char buf [ INET6_ADDRSTRLEN + sizeof ( " []:65536 " ) ] ;
Efl_Net_Socks5_Greeting greeting = {
. version = 0x05 ,
. auths_count = 1 ,
. auths = { proxy_user ? EFL_NET_SOCKS5_AUTH_USER_PASS : EFL_NET_SOCKS5_AUTH_NONE } ,
} ;
struct sockaddr_storage proxy_addr ;
socklen_t proxy_addrlen ;
2016-10-22 16:49:01 -07:00
SOCKET fd ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Eina_Error err ;
Eina_Bool ret = EINA_FALSE ;
ssize_t s ;
err = _efl_net_ip_resolve_and_connect ( proxy_host , proxy_port , SOCK_STREAM , IPPROTO_TCP , & fd , ( struct sockaddr * ) & proxy_addr , & proxy_addrlen ) ;
if ( err )
{
DBG ( " couldn't connect to socks5://%s:%s: %s " , proxy_host , proxy_port , eina_error_msg_get ( err ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
return EINA_TRUE ; /* no point in continuing on this error */
}
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
2016-09-09 16:09:51 -07:00
if ( eina_log_domain_level_check ( _ecore_con_log_dom , EINA_LOG_LEVEL_DBG ) )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
if ( efl_net_ip_port_fmt ( buf , sizeof ( buf ) , addrinfo - > ai_addr ) )
2016-11-18 06:17:08 -08:00
DBG ( " resolved address='%s' to %s. Connect using fd= " SOCKET_FMT " socks5://%s:%s " , d - > address , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
2016-09-09 16:09:51 -07:00
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) & greeting , sizeof ( greeting ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) sizeof ( greeting ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't request connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , sizeof ( greeting ) , s ) ;
}
else
{
Efl_Net_Socks5_Greeting_Reply greeting_reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & greeting_reply , sizeof ( greeting_reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( greeting_reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv greeting reply of connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( greeting_reply ) , s ) ;
}
else
{
if ( greeting_reply . auth ! = greeting . auths [ 0 ] )
2016-11-18 06:17:08 -08:00
DBG ( " proxy server rejected authentication %#x trying connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s " , greeting . auths [ 0 ] , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
if ( ( greeting_reply . auth = = EFL_NET_SOCKS5_AUTH_USER_PASS ) & &
( ! _efl_net_ip_connect_async_run_socks5_auth_user_pass ( fd , proxy_user , proxy_pass , " socks5 " , proxy_host , proxy_port ) ) )
{
d - > error = EFL_NET_DIALER_ERROR_PROXY_AUTHENTICATION_FAILED ;
}
else
{
Efl_Net_Socks5_Request * request ;
size_t request_len ;
request = efl_net_socks5_request_addr_new ( cmd , addrinfo - > ai_addr , & request_len ) ;
if ( request )
{
EINA_THREAD_CLEANUP_PUSH ( free , request ) ;
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) request , request_len , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) request_len )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't request connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , request_len , s ) ;
}
else if ( addrinfo - > ai_family = = AF_INET )
{
Efl_Net_Socks5_Reply_Ipv4 reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv reply of connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( reply ) , s ) ;
}
else
{
if ( reply . base . status ! = EFL_NET_SOCKS5_REPLY_STATUS_GRANTED )
2016-11-18 06:17:08 -08:00
DBG ( " rejected IPv4 connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: reason=%#x " , buf , fd , proxy_host , proxy_port , reply . base . status ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
memcpy ( & d - > addr , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
d - > addrlen = addrinfo - > ai_addrlen ;
d - > sockfd = fd ;
d - > error = 0 ;
ret = EINA_TRUE ;
2016-11-18 06:17:08 -08:00
DBG ( " connected IPv4 to host=%s fd= " SOCKET_FMT " socks5://%s:%s " , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
else if ( addrinfo - > ai_family = = AF_INET6 )
{
Efl_Net_Socks5_Reply_Ipv6 reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv reply of connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: %s " , buf , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( reply ) , s ) ;
}
else
{
if ( reply . base . status ! = EFL_NET_SOCKS5_REPLY_STATUS_GRANTED )
2016-11-18 06:17:08 -08:00
DBG ( " rejected IPv6 connection to host=%s fd= " SOCKET_FMT " socks5://%s:%s: reason=%#x " , buf , fd , proxy_host , proxy_port , reply . base . status ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
memcpy ( & d - > addr , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
d - > addrlen = addrinfo - > ai_addrlen ;
d - > sockfd = fd ;
d - > error = 0 ;
ret = EINA_TRUE ;
2016-11-18 06:17:08 -08:00
DBG ( " connected IPv6 to host=%s fd= " SOCKET_FMT " socks5://%s:%s " , buf , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ;
}
}
}
}
}
EINA_THREAD_CLEANUP_POP ( ! ret ) ; /* we need fd on success, on failure just close it */
return ret ;
}
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
static void
_efl_net_ip_connect_async_run_socks5 ( Efl_Net_Ip_Connect_Async_Data * d , const char * host , const char * port , const char * proxy )
{
char * str ;
const char * proxy_user , * proxy_pass , * proxy_host , * proxy_port ;
struct addrinfo * results = NULL ;
struct addrinfo hints = {
. ai_socktype = d - > type ,
. ai_protocol = d - > protocol ,
. ai_family = AF_UNSPEC ,
2016-10-22 04:41:26 -07:00
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
} ;
Efl_Net_Socks5_Request_Command cmd ;
int r ;
if ( ( d - > type = = SOCK_STREAM ) & & ( d - > protocol = = IPPROTO_TCP ) )
cmd = EFL_NET_SOCKS5_REQUEST_COMMAND_TCP_CONNECT ;
else
{
DBG ( " EFL SOCKSv5 only accepts TCP requests at this moment. Wanted type=%#x, protocol=%#x " , d - > type , d - > protocol ) ;
d - > error = EPROTONOSUPPORT ;
return ;
}
if ( strchr ( host , ' : ' ) ) hints . ai_family = AF_INET6 ;
DBG ( " proxy connection to %s:%s using socks5://%s " , host , port , proxy ) ;
str = strdup ( proxy ) ;
EINA_THREAD_CLEANUP_PUSH ( free , str ) ;
if ( ! _efl_net_ip_port_user_pass_split ( str , & proxy_host , & proxy_port , & proxy_user , & proxy_pass ) )
{
ERR ( " Invalid proxy string: socks5://%s " , proxy ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
if ( ! proxy_port ) proxy_port = " 1080 " ;
do
r = getaddrinfo ( host , port , & hints , & results ) ;
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( r ! = 0 )
{
DBG ( " couldn't resolve host='%s', port='%s': %s " ,
host , port , gai_strerror ( r ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST ;
}
else
{
const struct addrinfo * addrinfo ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) freeaddrinfo , results ) ;
for ( addrinfo = results ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
if ( addrinfo - > ai_socktype ! = d - > type ) continue ;
if ( addrinfo - > ai_protocol ! = d - > protocol ) continue ;
if ( _efl_net_ip_connect_async_run_socks5_try ( d , proxy_host , proxy_port , proxy_user , proxy_pass , cmd , addrinfo ) )
break ;
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* freeaddrinfo(results) */
}
end :
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(str) */
}
static void
_efl_net_ip_connect_async_run_socks5h ( Efl_Net_Ip_Connect_Async_Data * d , const char * host , const char * port , const char * proxy )
{
2016-10-22 16:49:01 -07:00
SOCKET fd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
char * str ;
const char * proxy_user , * proxy_pass , * proxy_host , * proxy_port ;
struct sockaddr_storage proxy_addr ;
socklen_t proxy_addrlen ;
Eina_Error err ;
Efl_Net_Socks5_Greeting greeting = {
. version = 0x05 ,
. auths_count = 1 ,
} ;
Efl_Net_Socks5_Request_Command cmd ;
ssize_t s ;
int r ;
if ( ( d - > type = = SOCK_STREAM ) & & ( d - > protocol = = IPPROTO_TCP ) )
cmd = EFL_NET_SOCKS5_REQUEST_COMMAND_TCP_CONNECT ;
else
{
DBG ( " EFL SOCKSv5 only accepts TCP requests at this moment. Wanted type=%#x, protocol=%#x " , d - > type , d - > protocol ) ;
d - > error = EPROTONOSUPPORT ;
return ;
}
DBG ( " proxy connection to %s:%s using socks5h://%s " , host , port , proxy ) ;
str = strdup ( proxy ) ;
EINA_THREAD_CLEANUP_PUSH ( free , str ) ;
if ( ! _efl_net_ip_port_user_pass_split ( str , & proxy_host , & proxy_port , & proxy_user , & proxy_pass ) )
{
ERR ( " Invalid proxy string: socks5h://%s " , proxy ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
if ( ! proxy_port ) proxy_port = " 1080 " ;
greeting . auths [ 0 ] = proxy_user ? EFL_NET_SOCKS5_AUTH_USER_PASS : EFL_NET_SOCKS5_AUTH_NONE ;
err = _efl_net_ip_resolve_and_connect ( proxy_host , proxy_port , SOCK_STREAM , IPPROTO_TCP , & fd , ( struct sockaddr * ) & proxy_addr , & proxy_addrlen ) ;
if ( err )
{
DBG ( " couldn't connect to socks5h://%s: %s " , proxy , eina_error_msg_get ( err ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_PROXY ;
goto end ;
}
2016-11-18 06:17:08 -08:00
DBG ( " connected fd= " SOCKET_FMT " to socks5h://%s " , fd , proxy ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_PUSH ( _cleanup_close , & fd ) ;
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) & greeting , sizeof ( greeting ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) sizeof ( greeting ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't request connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , sizeof ( greeting ) , s ) ;
}
else
{
Efl_Net_Socks5_Greeting_Reply greeting_reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & greeting_reply , sizeof ( greeting_reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( greeting_reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv greeting reply of connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( greeting_reply ) , s ) ;
}
else
{
if ( greeting_reply . auth ! = greeting . auths [ 0 ] )
2016-11-18 06:17:08 -08:00
DBG ( " proxy server rejected authentication %#x trying connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s " , greeting . auths [ 0 ] , host , port , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
{
if ( ( greeting_reply . auth = = EFL_NET_SOCKS5_AUTH_USER_PASS ) & &
( ! _efl_net_ip_connect_async_run_socks5_auth_user_pass ( fd , proxy_user , proxy_pass , " socks5h " , proxy_host , proxy_port ) ) )
{
d - > error = EFL_NET_DIALER_ERROR_PROXY_AUTHENTICATION_FAILED ;
}
else
{
struct addrinfo * results = NULL ;
struct addrinfo hints = {
. ai_socktype = d - > type ,
. ai_protocol = d - > protocol ,
. ai_family = AF_UNSPEC ,
2016-10-22 04:41:26 -07:00
. ai_flags = AI_ADDRCONFIG | AI_V4MAPPED ,
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
} ;
if ( strchr ( host , ' : ' ) ) hints . ai_family = AF_INET6 ;
/* we just resolve the port number here */
do
r = getaddrinfo ( NULL , port , & hints , & results ) ;
while ( ( r = = EAI_AGAIN ) | | ( ( r = = EAI_SYSTEM ) & & ( errno = = EINTR ) ) ) ;
if ( r ! = 0 )
{
DBG ( " couldn't resolve port='%s': %s " , port , gai_strerror ( r ) ) ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_RESOLVE_HOST ;
}
else
{
const struct addrinfo * addrinfo ;
d - > error = EFL_NET_DIALER_ERROR_COULDNT_CONNECT ;
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) freeaddrinfo , results ) ;
for ( addrinfo = results ; addrinfo ! = NULL ; addrinfo = addrinfo - > ai_next )
{
Efl_Net_Socks5_Request * request ;
size_t request_len ;
uint16_t port_num ;
if ( addrinfo - > ai_socktype ! = d - > type ) continue ;
if ( addrinfo - > ai_protocol ! = d - > protocol ) continue ;
if ( addrinfo - > ai_family = = AF_INET )
port_num = ( ( const struct sockaddr_in * ) addrinfo - > ai_addr ) - > sin_port ;
else
port_num = ( ( const struct sockaddr_in6 * ) addrinfo - > ai_addr ) - > sin6_port ;
request = efl_net_socks5_request_name_new ( cmd , host , port_num , & request_len ) ;
if ( request )
{
EINA_THREAD_CLEANUP_PUSH ( free , request ) ;
2016-11-18 06:39:43 -08:00
s = send ( fd , ( const char * ) request , request_len , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = ( ssize_t ) request_len )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't request connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't send proxy request: need %zu, did %zd " , request_len , s ) ;
}
else
{
Efl_Net_Socks5_Reply reply ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & reply , sizeof ( reply ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( reply ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv reply of connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy reply: need %zu, did %zd " , sizeof ( reply ) , s ) ;
}
else
{
if ( reply . status ! = EFL_NET_SOCKS5_REPLY_STATUS_GRANTED )
2016-11-18 06:17:08 -08:00
DBG ( " rejected connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: reason=%#x " , host , port , fd , proxy_host , proxy_port , reply . status ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else if ( reply . address_type = = EFL_NET_SOCKS5_ADDRESS_TYPE_IPV4 )
{
Efl_Net_Socks5_Address_Ipv4 ipv4 ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & ipv4 , sizeof ( ipv4 ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( ipv4 ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv ipv4 of connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy ipv4: need %zu, did %zd " , sizeof ( ipv4 ) , s ) ;
}
else
{
d - > addr4 . sin_family = AF_INET ;
d - > addr4 . sin_port = ipv4 . port ;
memcpy ( & d - > addr4 . sin_addr , ipv4 . address , 4 ) ;
d - > addrlen = sizeof ( struct sockaddr_in ) ;
d - > sockfd = fd ;
d - > error = 0 ;
2016-11-18 06:17:08 -08:00
DBG ( " connected IPv4 to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s " , host , port , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
else if ( reply . address_type = = EFL_NET_SOCKS5_ADDRESS_TYPE_IPV6 )
{
Efl_Net_Socks5_Address_Ipv6 ipv6 ;
2016-11-18 06:39:43 -08:00
s = recv ( fd , ( char * ) & ipv6 , sizeof ( ipv6 ) , MSG_NOSIGNAL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( s ! = sizeof ( ipv6 ) )
{
2016-10-22 08:15:16 -07:00
if ( s = = SOCKET_ERROR )
2016-11-18 06:17:08 -08:00
DBG ( " couldn't recv ipv6 of connection to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s: %s " , host , port , fd , proxy_host , proxy_port , eina_error_msg_get ( efl_net_socket_error_get ( ) ) ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else
DBG ( " couldn't recv proxy ipv6: need %zu, did %zd " , sizeof ( ipv6 ) , s ) ;
}
else
{
d - > addr6 . sin6_family = AF_INET ;
d - > addr6 . sin6_port = ipv6 . port ;
memcpy ( & d - > addr6 . sin6_addr , ipv6 . address , 16 ) ;
d - > addrlen = sizeof ( struct sockaddr_in ) ;
d - > sockfd = fd ;
d - > error = 0 ;
2016-11-18 06:17:08 -08:00
DBG ( " connected IPv6 to host=%s:%s fd= " SOCKET_FMT " socks5h://%s:%s " , host , port , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
else
{
/* most proxy servers will return a failure instead of this, but let's guard and log */
2016-11-18 06:17:08 -08:00
DBG ( " couldn't resolve host %s:%s fd= " SOCKET_FMT " socks5h://%s:%s " , host , port , fd , proxy_host , proxy_port ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(request) */
break ;
}
}
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* freeaddrinfo(results) */
}
}
}
}
}
2016-11-18 06:17:08 -08:00
EINA_THREAD_CLEANUP_POP ( d - > sockfd = = INVALID_SOCKET ) ; /* we need fd only on success */
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
end :
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ; /* free(str) */
}
static void
_efl_net_ip_connect_async_run ( void * data , Ecore_Thread * thread EINA_UNUSED )
{
Efl_Net_Ip_Connect_Async_Data * d = data ;
const char * host , * port , * proxy ;
char * addrcopy ;
2016-09-18 23:19:16 -07:00
char * * proxies = NULL ;
int proxies_idx = 0 ;
Eina_Bool is_libproxy = EINA_FALSE ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
addrcopy = strdup ( d - > address ) ;
if ( ! addrcopy )
2016-09-09 16:09:51 -07:00
{
d - > error = errno ;
return ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( ! efl_net_ip_port_split ( addrcopy , & host , & port ) )
{
d - > error = EINVAL ;
free ( addrcopy ) ;
return ;
}
if ( ! port ) port = " 0 " ;
2016-09-18 23:19:16 -07:00
EINA_THREAD_CLEANUP_PUSH ( free , addrcopy ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
proxy = d - > proxy ;
2016-09-18 23:19:16 -07:00
2016-09-20 11:00:17 -07:00
if ( ( ! proxy ) & & ( _ecore_con_libproxy . factory ) )
2016-09-18 23:19:16 -07:00
{
/* libproxy is thread-safe but not cancellable. the provided
* parameter must be a URL with schema , otherwise it won ' t
* return anything .
*/
2016-09-20 16:13:25 -07:00
Eina_Stringshare * url ;
2016-09-18 23:19:16 -07:00
2016-09-20 16:13:25 -07:00
url = eina_stringshare_printf ( " %s://%s:%s " , d - > protocol = = IPPROTO_UDP ? " udp " : " tcp " , host , port ) ;
if ( ! url )
{
ERR ( " Could not assemble URL " ) ;
}
else
{
proxies = ecore_con_libproxy_proxies_get ( url ) ;
eina_stringshare_del ( url ) ;
}
2016-09-18 23:19:16 -07:00
}
2016-09-20 11:00:17 -07:00
EINA_THREAD_CLEANUP_PUSH ( ( Eina_Free_Cb ) ecore_con_libproxy_proxies_free , proxies ) ;
2016-09-18 23:19:16 -07:00
next_proxy :
if ( ( ! proxy ) & & ( proxies ) & & ( proxies_idx > = 0 ) )
{
proxy = proxies [ proxies_idx ] ;
if ( ! proxy )
{
is_libproxy = EINA_FALSE ;
proxies_idx = - 1 ;
}
else
{
if ( strcmp ( proxy , " direct:// " ) = = 0 )
{
/* give a chance to try envvars */
proxy = NULL ;
is_libproxy = EINA_FALSE ;
}
else
{
DBG ( " libproxy said %s for host='%s' port='%s' " , proxy , host , port ) ;
is_libproxy = EINA_TRUE ;
}
proxies_idx + + ;
}
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
if ( ! proxy )
{
proxy = d - > proxy_env ;
if ( ! proxy )
proxy = " " ;
else
{
if ( _efl_net_ip_no_proxy ( host , d - > no_proxy_strv ) )
proxy = " " ;
2016-09-18 23:19:16 -07:00
else
DBG ( " using proxy %s from envvar " , proxy ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
/* allows ecore_thread_cancel() to cancel at some points, see
* man : pthreads ( 7 ) .
*/
eina_thread_cancellable_set ( EINA_TRUE , NULL ) ;
if ( ! proxy [ 0 ] )
_efl_net_ip_connect_async_run_direct ( d , host , port ) ;
else if ( eina_str_has_prefix ( proxy , " socks4:// " ) )
_efl_net_ip_connect_async_run_socks4 ( d , host , port , proxy + strlen ( " socks4:// " ) ) ;
else if ( eina_str_has_prefix ( proxy , " socks5:// " ) )
_efl_net_ip_connect_async_run_socks5 ( d , host , port , proxy + strlen ( " socks5:// " ) ) ;
else if ( eina_str_has_prefix ( proxy , " socks4a:// " ) )
_efl_net_ip_connect_async_run_socks4a ( d , host , port , proxy + strlen ( " socks4a:// " ) ) ;
else if ( eina_str_has_prefix ( proxy , " socks5h:// " ) )
_efl_net_ip_connect_async_run_socks5h ( d , host , port , proxy + strlen ( " socks5h:// " ) ) ;
2016-09-18 23:19:16 -07:00
else if ( eina_str_has_prefix ( proxy , " socks:// " ) )
{
_efl_net_ip_connect_async_run_socks5 ( d , host , port , proxy + strlen ( " socks:// " ) ) ;
if ( d - > error )
_efl_net_ip_connect_async_run_socks4 ( d , host , port , proxy + strlen ( " socks:// " ) ) ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
else if ( ! strstr ( proxy , " :// " ) )
{
_efl_net_ip_connect_async_run_socks5 ( d , host , port , proxy ) ;
if ( d - > error )
_efl_net_ip_connect_async_run_socks4 ( d , host , port , proxy ) ;
}
else
{
if ( d - > proxy )
{
d - > error = ENOTSUP ;
ERR ( " proxy protocol not supported '%s' " , proxy ) ;
}
else
{
2016-09-18 23:19:16 -07:00
if ( is_libproxy )
{
DBG ( " libproxy said %s but it's not supported, try next proxy " , proxy ) ;
proxy = NULL ;
goto next_proxy ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
/* maybe bogus envvar, ignore it */
WRN ( " proxy protocol not supported '%s', connect directly " , proxy ) ;
_efl_net_ip_connect_async_run_direct ( d , host , port ) ;
}
}
if ( ( d - > error ) & & ( ! d - > proxy ) & & ( proxy [ 0 ] ! = ' \0 ' ) )
{
2016-09-18 23:19:16 -07:00
if ( is_libproxy )
{
DBG ( " libproxy said %s but it failed, try next proxy " , proxy ) ;
proxy = NULL ;
goto next_proxy ;
}
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
WRN ( " error using proxy '%s' from environment, try direct connect " , proxy ) ;
_efl_net_ip_connect_async_run_direct ( d , host , port ) ;
}
eina_thread_cancellable_set ( EINA_FALSE , NULL ) ;
2016-09-18 23:19:16 -07:00
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_THREAD_CLEANUP_POP ( EINA_TRUE ) ;
2016-09-09 16:09:51 -07:00
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_ip_connect_async_data_free ( Efl_Net_Ip_Connect_Async_Data * d )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
free ( d - > address ) ;
free ( d - > proxy ) ;
free ( d - > proxy_env ) ;
if ( d - > no_proxy_strv )
{
free ( d - > no_proxy_strv [ 0 ] ) ;
free ( d - > no_proxy_strv ) ;
}
2016-09-09 16:09:51 -07:00
free ( d ) ;
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_ip_connect_async_end ( void * data , Ecore_Thread * thread EINA_UNUSED )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Ip_Connect_Async_Data * d = data ;
# ifdef FD_CLOEXEC
/* if it wasn't a close on exec, release the socket to be passed to child */
2016-10-22 08:15:16 -07:00
if ( ( ! d - > close_on_exec ) & & ( d - > sockfd ! = INVALID_SOCKET ) )
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
{
int flags = fcntl ( d - > sockfd , F_GETFD ) ;
if ( flags < 0 )
{
d - > error = errno ;
2016-11-18 06:17:08 -08:00
ERR ( " fcntl( " SOCKET_FMT " , F_GETFD): %s " , d - > sockfd , strerror ( errno ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( d - > sockfd ) ;
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
else
{
flags & = ( ~ FD_CLOEXEC ) ;
if ( fcntl ( d - > sockfd , F_SETFD , flags ) < 0 )
{
d - > error = errno ;
2016-11-18 06:17:08 -08:00
ERR ( " fcntl( " SOCKET_FMT " , F_SETFD, %#x): %s " , d - > sockfd , flags , strerror ( errno ) ) ;
2016-10-22 16:49:01 -07:00
closesocket ( d - > sockfd ) ;
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
}
}
}
# endif
d - > cb ( ( void * ) d - > data , & d - > addr , d - > addrlen , d - > sockfd , d - > error ) ;
_efl_net_ip_connect_async_data_free ( d ) ;
2016-09-09 16:09:51 -07:00
}
static void
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_ip_connect_async_cancel ( void * data , Ecore_Thread * thread EINA_UNUSED )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Ip_Connect_Async_Data * d = data ;
2016-10-22 16:49:01 -07:00
if ( d - > sockfd ! = INVALID_SOCKET ) closesocket ( d - > sockfd ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
_efl_net_ip_connect_async_data_free ( d ) ;
2016-09-09 16:09:51 -07:00
}
Ecore_Thread *
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
efl_net_ip_connect_async_new ( const char * address , const char * proxy , const char * proxy_env , const char * no_proxy_env , int type , int protocol , Eina_Bool close_on_exec , Efl_Net_Connect_Async_Cb cb , const void * data )
2016-09-09 16:09:51 -07:00
{
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
Efl_Net_Ip_Connect_Async_Data * d ;
2016-09-09 16:09:51 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( address , NULL ) ;
2016-09-09 16:09:51 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( cb , NULL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d = calloc ( 1 , sizeof ( Efl_Net_Ip_Connect_Async_Data ) ) ;
2016-09-09 16:09:51 -07:00
EINA_SAFETY_ON_NULL_RETURN_VAL ( d , NULL ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d - > address = strdup ( address ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > address , error_address ) ;
if ( proxy )
{
d - > proxy = strdup ( proxy ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > proxy , error_proxy ) ;
}
if ( proxy_env )
{
d - > proxy_env = strdup ( proxy_env ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > proxy_env , error_proxy_env ) ;
}
if ( no_proxy_env )
{
d - > no_proxy_strv = eina_str_split ( no_proxy_env , " , " , 0 ) ;
EINA_SAFETY_ON_NULL_GOTO ( d - > no_proxy_strv , error_no_proxy_strv ) ;
}
2016-09-09 16:09:51 -07:00
d - > cb = cb ;
d - > data = data ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
d - > addrlen = 0 ;
2016-09-09 16:09:51 -07:00
d - > close_on_exec = close_on_exec ;
d - > type = type ;
d - > protocol = protocol ;
2016-10-22 08:15:16 -07:00
d - > sockfd = INVALID_SOCKET ;
2016-09-09 16:09:51 -07:00
d - > error = 0 ;
2016-09-18 23:19:16 -07:00
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
return ecore_thread_run ( _efl_net_ip_connect_async_run ,
_efl_net_ip_connect_async_end ,
_efl_net_ip_connect_async_cancel ,
2016-09-09 16:09:51 -07:00
d ) ;
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
error_no_proxy_strv :
free ( d - > proxy_env ) ;
error_proxy_env :
free ( d - > proxy ) ;
error_proxy :
free ( d - > address ) ;
error_address :
free ( d ) ;
return NULL ;
2016-09-09 16:09:51 -07:00
}
2016-09-20 11:00:17 -07:00
2016-10-25 05:03:34 -07:00
static Eina_Error
efl_net_multicast_address4_parse ( const char * address , struct ip_mreq * mreq )
{
char * str = NULL ;
const char * iface ;
Eina_Error err = 0 ;
int r ;
iface = strchr ( address , ' @ ' ) ;
if ( ! iface ) iface = " 0.0.0.0 " ;
else
{
str = malloc ( iface - address + 1 ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( str , ENOMEM ) ;
memcpy ( str , address , iface - address ) ;
str [ iface - address ] = ' \0 ' ;
address = str ;
iface + + ;
if ( iface [ 0 ] = = ' \0 ' ) iface = " 0.0.0.0 " ;
}
if ( address [ 0 ] = = ' \0 ' )
{
err = EINVAL ;
goto end ;
}
r = inet_pton ( AF_INET , address , & mreq - > imr_multiaddr ) ;
if ( r ! = 1 )
{
if ( r < 0 ) err = efl_net_socket_error_get ( ) ;
else err = EINVAL ;
goto end ;
}
r = inet_pton ( AF_INET , iface , & mreq - > imr_interface ) ;
if ( r ! = 1 )
{
if ( r < 0 ) err = efl_net_socket_error_get ( ) ;
else err = EINVAL ;
goto end ;
}
end :
free ( str ) ;
return err ;
}
static Eina_Error
efl_net_multicast_address6_parse ( const char * address , struct ipv6_mreq * mreq )
{
char * str ;
char * endptr ;
const char * iface ;
Eina_Error err = 0 ;
unsigned long idx ;
int r ;
str = strdup ( address ) ;
EINA_SAFETY_ON_NULL_RETURN_VAL ( str , ENOMEM ) ;
address = str ;
if ( address [ 0 ] = = ' [ ' )
{
address + + ;
endptr = strchr ( address , ' ] ' ) ;
if ( ! endptr )
{
err = EINVAL ;
goto end ;
}
memmove ( endptr , endptr + 1 , strlen ( endptr + 1 ) + 1 ) ;
}
iface = strchr ( address , ' @ ' ) ;
if ( ! iface ) iface = " 0 " ;
else
{
str [ iface - address ] = ' \0 ' ;
iface + + ;
if ( iface [ 0 ] = = ' \0 ' ) iface = " 0 " ;
}
if ( address [ 0 ] = = ' \0 ' )
{
err = EINVAL ;
goto end ;
}
r = inet_pton ( AF_INET6 , address , & mreq - > ipv6mr_multiaddr ) ;
if ( r ! = 1 )
{
if ( r < 0 ) err = efl_net_socket_error_get ( ) ;
else err = EINVAL ;
goto end ;
}
errno = 0 ;
idx = strtoul ( iface , & endptr , 10 ) ;
if ( errno )
{
err = errno ;
goto end ;
}
else if ( ( iface = = endptr ) | | ( endptr [ 0 ] ! = ' \0 ' ) )
{
errno = EINVAL ;
goto end ;
}
else if ( idx > UINT32_MAX )
{
errno = ERANGE ;
goto end ;
}
mreq - > ipv6mr_interface = idx ;
end :
free ( str ) ;
return err ;
}
Eina_Error
efl_net_multicast_join ( SOCKET fd , int family , const char * address )
{
Eina_Error err ;
if ( family = = AF_INET )
{
struct ip_mreq mreq ;
err = efl_net_multicast_address4_parse ( address , & mreq ) ;
if ( err )
return err ;
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , IPPROTO_IP , IP_ADD_MEMBERSHIP , ( const char * ) & mreq , sizeof ( mreq ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
}
else if ( family = = AF_INET6 )
{
struct ipv6_mreq mreq ;
err = efl_net_multicast_address6_parse ( address , & mreq ) ;
if ( err )
return err ;
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , IPPROTO_IPV6 , IPV6_JOIN_GROUP , ( const char * ) & mreq , sizeof ( mreq ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
}
else
{
ERR ( " invalid socket family=%d " , family ) ;
return EINVAL ;
}
return efl_net_socket_error_get ( ) ;
}
Eina_Error
efl_net_multicast_leave ( SOCKET fd , int family , const char * address )
{
Eina_Error err ;
if ( family = = AF_INET )
{
struct ip_mreq mreq ;
err = efl_net_multicast_address4_parse ( address , & mreq ) ;
if ( err )
return err ;
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , IPPROTO_IP , IP_DROP_MEMBERSHIP , ( const char * ) & mreq , sizeof ( mreq ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
}
else if ( family = = AF_INET6 )
{
struct ipv6_mreq mreq ;
err = efl_net_multicast_address6_parse ( address , & mreq ) ;
if ( err )
return err ;
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , IPPROTO_IPV6 , IPV6_LEAVE_GROUP , ( const char * ) & mreq , sizeof ( mreq ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
}
else
{
ERR ( " invalid socket family=%d " , family ) ;
return EINVAL ;
}
return efl_net_socket_error_get ( ) ;
}
Eina_Error
efl_net_multicast_ttl_set ( SOCKET fd , int family , uint8_t ttl )
{
int level = ( family = = AF_INET ) ? IPPROTO_IP : IPPROTO_IPV6 ;
int opt = ( family = = AF_INET ) ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS ;
# ifdef _WIN32
DWORD value = ttl ;
# else
int value = ttl ;
# endif
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , level , opt , ( const char * ) & value , sizeof ( value ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
return efl_net_socket_error_get ( ) ;
}
Eina_Error
efl_net_multicast_ttl_get ( SOCKET fd , int family , uint8_t * ttl )
{
int level = ( family = = AF_INET ) ? IPPROTO_IP : IPPROTO_IPV6 ;
int opt = ( family = = AF_INET ) ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS ;
# ifdef _WIN32
DWORD value ;
int valuelen = sizeof ( value ) ;
# else
int value ;
socklen_t valuelen = sizeof ( value ) ;
# endif
2016-11-18 06:52:08 -08:00
if ( getsockopt ( fd , level , opt , ( char * ) & value , & valuelen ) = = 0 )
2016-10-25 05:03:34 -07:00
{
* ttl = value ;
return 0 ;
}
return efl_net_socket_error_get ( ) ;
}
Eina_Error
efl_net_multicast_loopback_set ( SOCKET fd , int family , Eina_Bool loopback )
{
int level = ( family = = AF_INET ) ? IPPROTO_IP : IPPROTO_IPV6 ;
int opt = ( family = = AF_INET ) ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP ;
# ifdef _WIN32
DWORD value = loopback ;
# else
int value = loopback ;
# endif
2016-11-18 06:52:08 -08:00
if ( setsockopt ( fd , level , opt , ( const char * ) & value , sizeof ( value ) ) = = 0 )
2016-10-25 05:03:34 -07:00
return 0 ;
return efl_net_socket_error_get ( ) ;
}
Eina_Error
efl_net_multicast_loopback_get ( SOCKET fd , int family , Eina_Bool * loopback )
{
int level = ( family = = AF_INET ) ? IPPROTO_IP : IPPROTO_IPV6 ;
int opt = ( family = = AF_INET ) ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP ;
# ifdef _WIN32
DWORD value ;
int valuelen = sizeof ( value ) ;
# else
int value ;
socklen_t valuelen = sizeof ( value ) ;
# endif
2016-11-18 06:52:08 -08:00
if ( getsockopt ( fd , level , opt , ( char * ) & value , & valuelen ) = = 0 )
2016-10-25 05:03:34 -07:00
{
* loopback = ! ! value ;
return 0 ;
}
return efl_net_socket_error_get ( ) ;
}
size_t
efl_net_udp_datagram_size_query ( SOCKET fd )
{
# ifdef _WIN32
unsigned long size ;
if ( ioctlsocket ( fd , FIONREAD , & size ) = = 0 )
return size ;
# else
int size ;
if ( ioctl ( fd , FIONREAD , & size ) = = 0 )
return size ;
# endif
return READBUFSIZ ;
}
2016-09-20 11:00:17 -07:00
Eina_Bool
ecore_con_libproxy_init ( void )
{
if ( ! _ecore_con_libproxy . mod )
{
# define LOAD(x) \
if ( ! _ecore_con_libproxy . mod ) { \
_ecore_con_libproxy . mod = eina_module_new ( x ) ; \
if ( _ecore_con_libproxy . mod ) { \
if ( ! eina_module_load ( _ecore_con_libproxy . mod ) ) { \
eina_module_free ( _ecore_con_libproxy . mod ) ; \
_ecore_con_libproxy . mod = NULL ; \
} \
} \
}
# if defined(_WIN32) || defined(__CYGWIN__)
LOAD ( " libproxy-1.dll " ) ;
LOAD ( " libproxy.dll " ) ;
# elif defined(__APPLE__) && defined(__MACH__)
LOAD ( " libproxy.1.dylib " ) ;
LOAD ( " libproxy.dylib " ) ;
# else
LOAD ( " libproxy.so.1 " ) ;
LOAD ( " libproxy.so " ) ;
# endif
# undef LOAD
if ( ! _ecore_con_libproxy . mod )
{
DBG ( " Couldn't find libproxy in your system. Continue without it " ) ;
return EINA_FALSE ;
}
# define SYM(x) \
if ( ( _ecore_con_libproxy . x = eina_module_symbol_get ( _ecore_con_libproxy . mod , # x ) ) = = NULL ) { \
ERR ( " libproxy (%s) missing symbol %s " , eina_module_file_get ( _ecore_con_libproxy . mod ) , # x ) ; \
eina_module_free ( _ecore_con_libproxy . mod ) ; \
_ecore_con_libproxy . mod = NULL ; \
return EINA_FALSE ; \
}
SYM ( px_proxy_factory_new ) ;
SYM ( px_proxy_factory_free ) ;
SYM ( px_proxy_factory_get_proxies ) ;
# undef SYM
DBG ( " using libproxy=%s " , eina_module_file_get ( _ecore_con_libproxy . mod ) ) ;
}
if ( ! _ecore_con_libproxy . factory )
_ecore_con_libproxy . factory = _ecore_con_libproxy . px_proxy_factory_new ( ) ;
return ! ! _ecore_con_libproxy . factory ;
}
char * *
ecore_con_libproxy_proxies_get ( const char * url )
{
EINA_SAFETY_ON_NULL_RETURN_VAL ( _ecore_con_libproxy . px_proxy_factory_get_proxies , NULL ) ;
return _ecore_con_libproxy . px_proxy_factory_get_proxies ( _ecore_con_libproxy . factory , url ) ;
}
void
ecore_con_libproxy_proxies_free ( char * * proxies )
{
char * * itr ;
if ( ! proxies ) return ;
for ( itr = proxies ; * itr ! = NULL ; itr + + )
free ( * itr ) ;
free ( proxies ) ;
}