forked from enlightenment/efl
ecore_con: Ecore_Con_Server now on top of Efl_Net!
This is a major work and unfortunately couldn't be split into smaller pieces as old code was highly coupled. Ecore_Con_Server is now a wrapper around Efl_Net_Dialer_Simple (ecore_con_server_connect()) and Efl_Net_Server_Simple (ecore_con_server_add()), doing all that the original version did with some fixes so ecore_con_ssl_server_upgrade() and ecore_con_ssl_client_upgrade() are more usable -- see the examples and -t/--type=tcp+ssl. I tried to be bug-compatible, with code annotations where things doesn't make sense. This was based on ecore_con_suite tests and some manual experimenting with the examples, these can be helpful if you find regressions (report/assign to me).
This commit is contained in:
parent
72ad2c5eb7
commit
f4306d654d
|
@ -2,10 +2,6 @@
|
|||
### Library
|
||||
|
||||
ecore_con_eolian_files = \
|
||||
lib/ecore_con/efl_network.eo \
|
||||
lib/ecore_con/efl_network_client.eo \
|
||||
lib/ecore_con/efl_network_server.eo \
|
||||
lib/ecore_con/efl_network_connector.eo \
|
||||
lib/ecore_con/efl_net_socket.eo \
|
||||
lib/ecore_con/efl_net_socket_simple.eo \
|
||||
lib/ecore_con/efl_net_socket_fd.eo \
|
||||
|
@ -71,7 +67,6 @@ lib_LTLIBRARIES += lib/ecore_con/libecore_con.la
|
|||
installed_ecoreconmainheadersdir = $(includedir)/ecore-con-@VMAJ@
|
||||
dist_installed_ecoreconmainheaders_DATA = \
|
||||
lib/ecore_con/Ecore_Con.h \
|
||||
lib/ecore_con/Ecore_Con_Legacy.h \
|
||||
lib/ecore_con/Ecore_Con_Eo.h \
|
||||
lib/ecore_con/Ecore_Con_Eet.h \
|
||||
lib/ecore_con/Ecore_Con_Eet_Legacy.h \
|
||||
|
@ -83,16 +78,15 @@ nodist_installed_ecoreconmainheaders_DATA = \
|
|||
lib_ecore_con_libecore_con_la_SOURCES = \
|
||||
lib/ecore_con/ecore_con_alloc.c \
|
||||
lib/ecore_con/ecore_con.c \
|
||||
lib/ecore_con/ecore_con_legacy.c \
|
||||
lib/ecore_con/ecore_con_eet.c \
|
||||
lib/ecore_con/ecore_con_socks.c \
|
||||
lib/ecore_con/ecore_con_ssl.c \
|
||||
lib/ecore_con/ecore_con_url.c \
|
||||
lib/ecore_con/ecore_con_url_curl.c \
|
||||
lib/ecore_con/ecore_con_url_curl.h \
|
||||
static_libs/http-parser/http_parser.c \
|
||||
static_libs/http-parser/http_parser.h \
|
||||
lib/ecore_con/ecore_con_private.h \
|
||||
lib/ecore_con/ecore_con_info.c \
|
||||
lib/ecore_con/efl_net_socket.c \
|
||||
lib/ecore_con/efl_net_socket_simple.c \
|
||||
lib/ecore_con/efl_net_socket_fd.c \
|
||||
|
@ -113,7 +107,8 @@ lib/ecore_con/efl_net_server_udp_client.c \
|
|||
lib/ecore_con/efl_net_socket_ssl.c \
|
||||
lib/ecore_con/efl_net_ssl_context.c \
|
||||
lib/ecore_con/efl_net_dialer_ssl.c \
|
||||
lib/ecore_con/efl_net_server_ssl.c
|
||||
lib/ecore_con/efl_net_server_ssl.c \
|
||||
lib/ecore_con/ecore_con_local.c
|
||||
|
||||
if EFL_NET_CONTROL_BACKEND_CONNMAN
|
||||
lib_ecore_con_libecore_con_la_SOURCES += \
|
||||
|
@ -146,9 +141,9 @@ lib/ecore_con/efl_net_ssl_ctx-gnutls.c \
|
|||
lib/ecore_con/efl_net_ssl_ctx-none.c
|
||||
|
||||
if HAVE_WINDOWS
|
||||
lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_local_win32.c
|
||||
#lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_local_win32.c
|
||||
else
|
||||
lib_ecore_con_libecore_con_la_SOURCES += lib/ecore_con/ecore_con_local.c \
|
||||
lib_ecore_con_libecore_con_la_SOURCES += \
|
||||
lib/ecore_con/efl_net_socket_unix.c \
|
||||
lib/ecore_con/efl_net_dialer_unix.c \
|
||||
lib/ecore_con/efl_net_server_unix.c
|
||||
|
|
|
@ -227,7 +227,41 @@ extern "C" {
|
|||
#define ECORE_CON_USE_SSL ECORE_CON_USE_SSL2
|
||||
#define ECORE_CON_REMOTE_SYSTEM ECORE_CON_REMOTE_TCP
|
||||
|
||||
typedef Eo Ecore_Con;
|
||||
/** Types for an ecore_con client/server object. A correct way to set this
|
||||
* type is with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if
|
||||
* encryption is desired, and LOAD_CERT if the previously loaded certificate
|
||||
* should be used.
|
||||
*
|
||||
* @ingroup Ecore_Con
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECORE_CON_LOCAL_USER = 0, /** Socket in "~/.ecore" */
|
||||
ECORE_CON_LOCAL_SYSTEM = 1, /** Socket in /tmp */
|
||||
ECORE_CON_LOCAL_ABSTRACT = 2, /** Abstract socket */
|
||||
ECORE_CON_REMOTE_TCP = 3, /** Remote server using TCP */
|
||||
ECORE_CON_REMOTE_MCAST = 4, /** Remote multicast UDP server (ecore_con_server_add() only) */
|
||||
ECORE_CON_REMOTE_UDP = 5, /** Remote server using UDP */
|
||||
ECORE_CON_REMOTE_BROADCAST = 6, /** Remote broadcast using UDP (ecore_con_server_connect() only) */
|
||||
ECORE_CON_REMOTE_NODELAY = 7, /** Remote TCP connection sending packets
|
||||
* immediately */
|
||||
ECORE_CON_REMOTE_CORK = 8, /** Remote TCP connection sending data in large chunks
|
||||
* Note: Only available on Linux
|
||||
*
|
||||
* @since 1.2 */
|
||||
ECORE_CON_USE_SSL2 = 16 /* 1 << 4 */, /** Use SSL2: UNSUPPORTED. */
|
||||
ECORE_CON_USE_SSL3 = 32 /* 1 << 5 */, /** Use SSL3: UNSUPPORTED. */
|
||||
ECORE_CON_USE_TLS = 64 /* 1 << 6 */, /** Use TLS */
|
||||
ECORE_CON_USE_MIXED = 96 /* Ecore.Con.Type.use_tls | Ecore.Con.Type.use_ssl3 */, /** Use both TLS and SSL3 */
|
||||
ECORE_CON_LOAD_CERT = 128 /* 1 << 7 */, /** Attempt to use the loaded
|
||||
* certificate */
|
||||
ECORE_CON_NO_PROXY = 256 /* 1 << 8 */, /** Disable all types of proxy on the
|
||||
* server Note: Only functional for
|
||||
* clients
|
||||
*
|
||||
* @since 1.2 */
|
||||
ECORE_CON_SOCKET_ACTIVATE = 512 /* 1 << 9 */
|
||||
} Ecore_Con_Type;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Socks
|
||||
|
@ -265,13 +299,38 @@ typedef void (*Ecore_Con_Dns_Cb)(const char *canonname,
|
|||
|
||||
/** @} */
|
||||
|
||||
#ifndef EFL_NOLEGACY_API_SUPPORT
|
||||
#include "Ecore_Con_Legacy.h"
|
||||
#endif
|
||||
#ifdef EFL_BETA_API_SUPPORT
|
||||
#include "Ecore_Con_Eo.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Server
|
||||
* Used to provide legacy ABI/ABI compatibility with non-Eo applications.
|
||||
* @ingroup Ecore_Con_Server_Group
|
||||
*/
|
||||
struct _Ecore_Con_Server;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Server
|
||||
* Used to provide legacy API/ABI compatibility with non-Eo applications.
|
||||
* @ingroup Ecore_Con_Server_Group
|
||||
*/
|
||||
typedef struct _Ecore_Con_Server Ecore_Con_Server;
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Client
|
||||
* Used to provide legacy ABI/ABI compatibility with non-Eo applications.
|
||||
* @ingroup Ecore_Con_Client_Group
|
||||
*/
|
||||
struct _Ecore_Con_Client;
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Con_Client
|
||||
* Used to provide legacy API/ABI compatibility with non-Eo applications.
|
||||
* @ingroup Ecore_Con_Client_Group
|
||||
*/
|
||||
typedef struct _Ecore_Con_Client Ecore_Con_Client;
|
||||
|
||||
|
||||
/**
|
||||
* @struct _Ecore_Con_Url
|
||||
|
@ -650,6 +709,26 @@ EAPI int ecore_con_init(void);
|
|||
*/
|
||||
EAPI int ecore_con_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief Do an asynchronous DNS lookup.
|
||||
*
|
||||
* This function performs a DNS lookup on the hostname specified by name, then
|
||||
* calls done_cb with the result and the data given as parameter. The result
|
||||
* will be given to the done_cb as follows:
|
||||
*
|
||||
* canonname - the canonical name of the address, ip - the resolved ip address,
|
||||
* addr - a pointer to the socket address, addrlen - the length of the socket
|
||||
* address, in bytes, data - the data pointer given as parameter.
|
||||
*
|
||||
* @param[in] name IP address or server name to translate.
|
||||
* @param[in] done_cb Callback to notify when done.
|
||||
* @param[in] data User data to be given to done_cb.
|
||||
*
|
||||
* @return @c true if the request did not fail to be set up, @c false
|
||||
* otherwise.
|
||||
*/
|
||||
EAPI Eina_Bool ecore_con_lookup(const char *name, Ecore_Con_Dns_Cb done_cb, const void *data) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -1142,6 +1221,10 @@ EAPI char *ecore_con_local_path_new(Eina_Bool is_system, const char *name, int p
|
|||
* or changed with ecore_con_server_data_set().
|
||||
*
|
||||
* @see ecore_con_local_path_new()
|
||||
*
|
||||
* @note This API is deprecated and new code should use
|
||||
* #EFL_NET_SERVER_SIMPLE_CLASS.
|
||||
* See @li @ref efl_net_server_simple_example.c
|
||||
*/
|
||||
EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
|
||||
const char *name, int port,
|
||||
|
@ -1194,6 +1277,10 @@ EAPI Ecore_Con_Server *ecore_con_server_add(Ecore_Con_Type type,
|
|||
* or changed with ecore_con_server_data_set().
|
||||
*
|
||||
* @see ecore_con_local_path_new()
|
||||
*
|
||||
* @note This API is deprecated and new code should use
|
||||
* #EFL_NET_DIALER_SIMPLE_CLASS.
|
||||
* See @li @ref efl_net_dialer_simple_example.c
|
||||
*/
|
||||
EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
|
||||
const char *name, int port,
|
||||
|
@ -1210,6 +1297,18 @@ EAPI Ecore_Con_Server *ecore_con_server_connect(Ecore_Con_Type type,
|
|||
*/
|
||||
EAPI void * ecore_con_server_del(Ecore_Con_Server *svr);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the name of server.
|
||||
*
|
||||
* The name returned is the name used to connect on this server.
|
||||
*
|
||||
* @param svr The given server.
|
||||
* @return The name of the server.
|
||||
*
|
||||
* @ingroup Efl_Network_Server
|
||||
*/
|
||||
EAPI const char *ecore_con_server_name_get(const Ecore_Con_Server *svr);
|
||||
|
||||
/**
|
||||
* @brief Retrieve the data associated with the given server.
|
||||
*
|
||||
|
@ -1304,6 +1403,21 @@ EAPI int ecore_con_server_send(Ecore_Con_Server *svr,
|
|||
EAPI void ecore_con_server_client_limit_set(Ecore_Con_Server *svr,
|
||||
int client_limit,
|
||||
char reject_excess_clients);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current list of clients.
|
||||
*
|
||||
* Each node in the returned list points to an @ref Efl_Network_Client. This
|
||||
* list cannot be modified or freed. It can also change if new clients are
|
||||
* connected or disconnected, and will become invalid when the server is
|
||||
* deleted/freed.
|
||||
*
|
||||
* @param svr The given server.
|
||||
* @return The list of clients on this server.
|
||||
*
|
||||
*/
|
||||
EAPI const Eina_List *ecore_con_server_clients_get(const Ecore_Con_Server *svr);
|
||||
|
||||
/**
|
||||
* @brief Get the IP address of a server that has been connected to.
|
||||
*
|
||||
|
@ -1532,7 +1646,13 @@ EAPI Eina_Bool ecore_con_client_connected_get(const Ecore_Con_Client *cl
|
|||
*/
|
||||
EAPI int ecore_con_client_port_get(const Ecore_Con_Client *cl);
|
||||
|
||||
|
||||
/**
|
||||
* @brief The server the client is connected to.
|
||||
*
|
||||
* @param cl The client
|
||||
* @return The server the client is connected to.
|
||||
*/
|
||||
EAPI Ecore_Con_Server *ecore_con_client_server_get(const Ecore_Con_Client *cl);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
#include "efl_network.eo.h"
|
||||
#include "efl_network_server.eo.h"
|
||||
#include "efl_network_connector.eo.h"
|
||||
#include "efl_network_client.eo.h"
|
||||
|
||||
#include "efl_net_socket.eo.h"
|
||||
#include "efl_net_dialer.eo.h"
|
||||
#include "efl_net_server.eo.h"
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef _ECORE_CON_LEGACY_H
|
||||
#define _ECORE_CON_LEGACY_H
|
||||
#include <Eina.h>
|
||||
#include <Eo.h>
|
||||
|
||||
#include "efl_network.eo.legacy.h"
|
||||
#include "efl_network_server.eo.legacy.h"
|
||||
#include "efl_network_connector.eo.legacy.h"
|
||||
#include "efl_network_client.eo.legacy.h"
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* ecore_con_base.eo.h
|
||||
*******************************************************************/
|
||||
typedef Eo Ecore_Con_Base;
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* ecore_con_client.eo.h
|
||||
*******************************************************************/
|
||||
typedef Eo Ecore_Con_Client;
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* ecore_con_server.eo.h
|
||||
*******************************************************************/
|
||||
typedef Eo Ecore_Con_Server;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,9 @@ GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Del, ecore_con_event_client_del);
|
|||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Write, ecore_con_event_client_write);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Data, ecore_con_event_client_data);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Error, ecore_con_event_server_error);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Upgrade, ecore_con_event_server_upgrade);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Error, ecore_con_event_client_error);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Client_Upgrade, ecore_con_event_client_upgrade);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
|
||||
GENERIC_ALLOC_FREE(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
|
||||
|
@ -48,7 +50,9 @@ static Ecore_Con_Mempool *mempool_array[] = {
|
|||
&ecore_con_event_client_write_mp,
|
||||
&ecore_con_event_client_data_mp,
|
||||
&ecore_con_event_server_error_mp,
|
||||
&ecore_con_event_server_upgrade_mp,
|
||||
&ecore_con_event_client_error_mp,
|
||||
&ecore_con_event_client_upgrade_mp,
|
||||
&ecore_con_event_server_add_mp,
|
||||
&ecore_con_event_server_del_mp,
|
||||
&ecore_con_event_server_write_mp,
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
#include <Eina.h>
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "Ecore_Con.h"
|
||||
#include "ecore_con_private.h"
|
||||
#include "Ecore_Con_Eet.h"
|
||||
|
||||
#define ECORE_CON_EET_RAW_MAGIC 0xDEAD007
|
||||
|
@ -699,7 +702,7 @@ _ecore_con_eet_base_efl_object_finalize(Eo *obj, Ecore_Con_Eet_Base_Data *pd)
|
|||
EOLIAN static void
|
||||
_ecore_con_eet_base_server_set(Eo *obj EINA_UNUSED, Ecore_Con_Eet_Base_Data *pd, Ecore_Con_Server *data)
|
||||
{
|
||||
if (!efl_isa(data, EFL_NETWORK_SERVER_CLASS))
|
||||
if (!ecore_con_server_check(data))
|
||||
return;
|
||||
|
||||
pd->server = data;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import efl_network_server;
|
||||
|
||||
struct @extern Ecore_Con_Server;
|
||||
type @extern Ecore_Con_Eet_Data_Cb: __undefined_type; [[Ecore connection eet data callback type]] /* FIXME: function pointers not supported. */
|
||||
type @extern Ecore_Con_Eet_Raw_Data_Cb: __undefined_type; [[Ecore connection eet raw data callback type]]/* FIXME: function pointers not supported. */
|
||||
|
||||
|
@ -19,7 +18,7 @@ class Ecore.Con.Eet.Base (Efl.Object) {
|
|||
get {
|
||||
}
|
||||
values {
|
||||
data: Efl.Network.Server; [[Server object]]
|
||||
data: ptr(Ecore_Con_Server); [[Server object]]
|
||||
}
|
||||
}
|
||||
@property data_callback {
|
||||
|
|
|
@ -1,297 +0,0 @@
|
|||
/*
|
||||
* getaddrinfo with callback
|
||||
*
|
||||
* man getaddrinfo
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef __OpenBSD__
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "Ecore.h"
|
||||
#include "ecore_private.h"
|
||||
#include "ecore_con_private.h"
|
||||
|
||||
typedef struct _CB_Data CB_Data;
|
||||
|
||||
struct _CB_Data
|
||||
{
|
||||
EINA_INLIST;
|
||||
Ecore_Con_Info_Cb cb_done;
|
||||
void *data;
|
||||
Ecore_Thread *thread;
|
||||
struct addrinfo hints;
|
||||
Ecore_Con_Info *result;
|
||||
int error;
|
||||
char service[NI_MAXSERV];
|
||||
char name[NI_MAXHOST];
|
||||
};
|
||||
|
||||
static void _ecore_con_info_slave_free (CB_Data *cbdata);
|
||||
static void _ecore_con_info_slave_result(void *data, Ecore_Thread *th);
|
||||
static void _ecore_con_info_slave_cancel(void *data, Ecore_Thread *th);
|
||||
static void _ecore_con_info_slave_lookup(void *data, Ecore_Thread *th);
|
||||
|
||||
static int info_init = 0;
|
||||
static CB_Data *info_slaves = NULL;
|
||||
|
||||
int
|
||||
ecore_con_info_init(void)
|
||||
{
|
||||
info_init++;
|
||||
return info_init;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_shutdown(void)
|
||||
{
|
||||
info_init--;
|
||||
if (info_init == 0)
|
||||
{
|
||||
while (info_slaves)
|
||||
{
|
||||
CB_Data *cbdata;
|
||||
|
||||
cbdata = info_slaves;
|
||||
info_slaves = (CB_Data *)eina_inlist_remove
|
||||
(EINA_INLIST_GET(info_slaves), EINA_INLIST_GET(info_slaves));
|
||||
ecore_thread_cancel(cbdata->thread);
|
||||
}
|
||||
}
|
||||
return info_init;
|
||||
}
|
||||
|
||||
static void
|
||||
_hints_fill(struct addrinfo *hints, int flags, int proto)
|
||||
{
|
||||
memset(hints, 0, sizeof(struct addrinfo));
|
||||
hints->ai_family = AF_UNSPEC;
|
||||
hints->ai_flags = flags;
|
||||
if (proto == IPPROTO_TCP) hints->ai_socktype = SOCK_STREAM;
|
||||
else hints->ai_socktype = SOCK_DGRAM;
|
||||
hints->ai_protocol = proto;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
_hints_fill(&hints, AI_CANONNAME, IPPROTO_TCP);
|
||||
return ecore_con_info_get(svr, done_cb, data, &hints);
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
_hints_fill(&hints, AI_PASSIVE, IPPROTO_TCP);
|
||||
return ecore_con_info_get(svr, done_cb, data, &hints);
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_udp_connect(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
_hints_fill(&hints, AI_CANONNAME, IPPROTO_UDP);
|
||||
return ecore_con_info_get(svr, done_cb, data, &hints);
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_udp_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
_hints_fill(&hints, AI_PASSIVE, IPPROTO_UDP);
|
||||
return ecore_con_info_get(svr, done_cb, data, &hints);
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
_hints_fill(&hints, 0, IPPROTO_UDP);
|
||||
return ecore_con_info_get(svr, done_cb, data, &hints);
|
||||
}
|
||||
|
||||
EAPI int
|
||||
ecore_con_info_get(Ecore_Con_Server *obj,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data,
|
||||
struct addrinfo *hints)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
CB_Data *cbdata;
|
||||
|
||||
if (!svr) return 0;
|
||||
cbdata = calloc(1, sizeof(CB_Data));
|
||||
if (!cbdata)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "Memory allocation failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cbdata->cb_done = done_cb;
|
||||
cbdata->data = data;
|
||||
cbdata->hints = *hints;
|
||||
cbdata->thread = ecore_thread_run(_ecore_con_info_slave_lookup,
|
||||
_ecore_con_info_slave_result,
|
||||
_ecore_con_info_slave_cancel,
|
||||
cbdata);
|
||||
if (!cbdata->thread)
|
||||
{
|
||||
free(cbdata);
|
||||
ecore_con_event_server_error(obj, "Memory allocation failure");
|
||||
return 0;
|
||||
}
|
||||
eina_convert_itoa(svr->ecs ? svr->ecs->port : svr->port, cbdata->service);
|
||||
strncpy(cbdata->name, svr->ecs ? svr->ecs->ip : svr->name, NI_MAXHOST - 1);
|
||||
cbdata->name[NI_MAXHOST - 1] = 0;
|
||||
info_slaves = (CB_Data *)eina_inlist_append(EINA_INLIST_GET(info_slaves),
|
||||
EINA_INLIST_GET(cbdata));
|
||||
svr->infos = eina_list_append(svr->infos, cbdata);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_con_info_data_clear(void *info)
|
||||
{
|
||||
CB_Data *cbdata = info;
|
||||
cbdata->data = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_info_slave_free(CB_Data *cbdata)
|
||||
{
|
||||
if (info_slaves)
|
||||
info_slaves = (CB_Data *)eina_inlist_remove(EINA_INLIST_GET(info_slaves),
|
||||
EINA_INLIST_GET(cbdata));
|
||||
if (cbdata->result) free(cbdata->result);
|
||||
cbdata->result = NULL;
|
||||
if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
|
||||
cbdata->data = NULL;
|
||||
free(cbdata);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_info_slave_result(void *data, Ecore_Thread *th EINA_UNUSED)
|
||||
{
|
||||
CB_Data *cbdata = data;
|
||||
|
||||
if (cbdata->result) // lookup ok
|
||||
{
|
||||
if (cbdata->data) cbdata->cb_done(cbdata->data, cbdata->result);
|
||||
}
|
||||
else // an error occured
|
||||
{
|
||||
if (cbdata->data)
|
||||
{
|
||||
char *str = strerror(cbdata->error);
|
||||
ecore_con_event_server_error(cbdata->data, str);
|
||||
cbdata->cb_done(cbdata->data, NULL);
|
||||
}
|
||||
}
|
||||
if (cbdata->data) ecore_con_server_infos_del(cbdata->data, cbdata);
|
||||
cbdata->data = NULL;
|
||||
_ecore_con_info_slave_free(cbdata);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_info_slave_cancel(void *data, Ecore_Thread *th EINA_UNUSED)
|
||||
{
|
||||
CB_Data *cbdata = data;
|
||||
_ecore_con_info_slave_free(cbdata);
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_info_slave_lookup(void *data, Ecore_Thread *th EINA_UNUSED)
|
||||
{
|
||||
CB_Data *cbdata = data;
|
||||
struct addrinfo *result = NULL;
|
||||
|
||||
// do lookup, fill cbdata
|
||||
if ((!getaddrinfo(cbdata->name, cbdata->service, &(cbdata->hints), &result))
|
||||
&& (result))
|
||||
{
|
||||
Ecore_Con_Info *info;
|
||||
unsigned int canonname_size = 0, size;
|
||||
|
||||
if (result->ai_canonname)
|
||||
canonname_size = strlen(result->ai_canonname) + 1;
|
||||
size = sizeof(Ecore_Con_Info) + result->ai_addrlen + canonname_size;
|
||||
info = calloc(1, size);
|
||||
if (info)
|
||||
{
|
||||
char hbuf[NI_MAXHOST] = { 0 }, sbuf[NI_MAXSERV] = { 0 }, *p;
|
||||
|
||||
info->size = size;
|
||||
memcpy(&(info->info), result, sizeof(struct addrinfo));
|
||||
p = ((char *)info) + sizeof(Ecore_Con_Info);
|
||||
memcpy(p, result->ai_addr, result->ai_addrlen);
|
||||
info->info.ai_addr = (struct sockaddr *)p;
|
||||
if (result->ai_canonname)
|
||||
{
|
||||
p = ((char *)info) + sizeof(Ecore_Con_Info) + result->ai_addrlen;
|
||||
memcpy(p, result->ai_canonname, canonname_size);
|
||||
info->info.ai_canonname = p;
|
||||
}
|
||||
// we don't care about multiple entries - take first one then
|
||||
info->info.ai_next = NULL;
|
||||
if (!getnameinfo(result->ai_addr, result->ai_addrlen,
|
||||
hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
|
||||
NI_NUMERICHOST | NI_NUMERICSERV))
|
||||
{
|
||||
memcpy(info->ip, hbuf, sizeof(info->ip));
|
||||
memcpy(info->service, sbuf, sizeof(info->service));
|
||||
}
|
||||
cbdata->result = info;
|
||||
}
|
||||
if (!cbdata->result) free(info);
|
||||
}
|
||||
if (!cbdata->result) cbdata->error = errno;
|
||||
if (result) freeaddrinfo(result);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -10,8 +10,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
|
@ -28,16 +26,8 @@
|
|||
#include "Ecore_Con.h"
|
||||
#include "ecore_con_private.h"
|
||||
|
||||
#define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
|
||||
(size_t)(((struct sockaddr_un *)NULL)-> \
|
||||
sun_path))
|
||||
#define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
|
||||
(size_t)(((struct sockaddr_un \
|
||||
*)NULL)->sun_path))
|
||||
|
||||
static int _ecore_con_local_init_count = 0;
|
||||
|
||||
static const char *_ecore_con_local_path_get()
|
||||
static const char *
|
||||
_ecore_con_local_path_get(void)
|
||||
{
|
||||
const char *homedir = getenv("XDG_RUNTIME_DIR");
|
||||
if (!homedir) homedir = eina_environment_home_get();
|
||||
|
@ -46,24 +36,6 @@ static const char *_ecore_con_local_path_get()
|
|||
return homedir;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_local_init(void)
|
||||
{
|
||||
if (++_ecore_con_local_init_count != 1)
|
||||
return _ecore_con_local_init_count;
|
||||
|
||||
return _ecore_con_local_init_count;
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_local_shutdown(void)
|
||||
{
|
||||
if (--_ecore_con_local_init_count != 0)
|
||||
return _ecore_con_local_init_count;
|
||||
|
||||
return _ecore_con_local_init_count;
|
||||
}
|
||||
|
||||
EAPI char *
|
||||
ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port)
|
||||
{
|
||||
|
@ -125,110 +97,6 @@ ecore_con_local_path_new(Eina_Bool is_system, const char *name, int port)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
ecore_con_local_connect(Ecore_Con_Server *obj,
|
||||
Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
|
||||
void *data EINA_UNUSED)
|
||||
{
|
||||
#ifndef HAVE_LOCAL_SOCKETS
|
||||
return 0;
|
||||
#else
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char *buf = NULL;
|
||||
struct sockaddr_un socket_unix;
|
||||
int curstate = 0;
|
||||
int socket_unix_len;
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
{
|
||||
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
buf = strdup(svr->name);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (svr->fd < 0)
|
||||
{
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
||||
goto error;
|
||||
|
||||
if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
|
||||
goto error;
|
||||
|
||||
if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
|
||||
sizeof(curstate)) < 0)
|
||||
goto error;
|
||||
|
||||
socket_unix.sun_family = AF_UNIX;
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
#ifdef HAVE_ABSTRACT_SOCKETS
|
||||
/* copy name insto sun_path, prefixed by null to indicate abstract namespace */
|
||||
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
|
||||
svr->name);
|
||||
socket_unix.sun_path[0] = '\0';
|
||||
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
|
||||
svr->name);
|
||||
#else
|
||||
WRN("Your system does not support abstract sockets!");
|
||||
goto error;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path) - 1);
|
||||
socket_unix.sun_path[sizeof(socket_unix.sun_path) - 1] = '\0';
|
||||
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
|
||||
}
|
||||
|
||||
if (connect(svr->fd, (struct sockaddr *)&socket_unix,
|
||||
socket_unix_len) < 0)
|
||||
{
|
||||
DBG("local connection failed: %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
svr->path = buf;
|
||||
buf = NULL;
|
||||
|
||||
if (svr->type & ECORE_CON_SSL)
|
||||
{
|
||||
if (!ecore_con_ssl_server_init(obj)) ERR("Can't init SSL");
|
||||
}
|
||||
|
||||
svr->fd_handler =
|
||||
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
||||
cb_done, obj, NULL, NULL);
|
||||
if (!svr->fd_handler)
|
||||
goto error;
|
||||
|
||||
if (!svr->delete_me) ecore_con_event_server_add(obj);
|
||||
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
error:
|
||||
if (svr->fd) close(svr->fd);
|
||||
svr->fd = -1;
|
||||
free(buf);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOCAL_SOCKETS
|
||||
void
|
||||
_ecore_con_local_mkpath(const char *path, mode_t mode)
|
||||
{
|
||||
|
@ -274,168 +142,3 @@ _ecore_con_local_mkpath(const char *path, mode_t mode)
|
|||
end:
|
||||
free(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ecore_con_local_listen(
|
||||
Ecore_Con_Server *obj,
|
||||
Eina_Bool (*
|
||||
cb_listen)(void *data,
|
||||
Ecore_Fd_Handler *
|
||||
fd_handler),
|
||||
void *data
|
||||
EINA_UNUSED)
|
||||
{
|
||||
#ifdef HAVE_LOCAL_SOCKETS
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
char *buf = NULL;
|
||||
struct sockaddr_un socket_unix;
|
||||
struct linger lin;
|
||||
mode_t pmode;
|
||||
mode_t mask;
|
||||
int socket_unix_len;
|
||||
Eina_Bool abstract_socket;
|
||||
|
||||
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
||||
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
|
||||
{
|
||||
buf = ecore_con_local_path_new(EINA_FALSE, svr->name, svr->port);
|
||||
|
||||
mask = S_IRUSR | S_IWUSR | S_IXUSR;
|
||||
_ecore_con_local_mkpath(buf, mask);
|
||||
|
||||
mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
|
||||
{
|
||||
mask = 0;
|
||||
buf = ecore_con_local_path_new(EINA_TRUE, svr->name, svr->port);
|
||||
}
|
||||
else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
buf = strdup(svr->name);
|
||||
}
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(buf, 0);
|
||||
|
||||
pmode = umask(mask);
|
||||
start:
|
||||
socket_unix.sun_family = AF_UNIX;
|
||||
if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
|
||||
{
|
||||
abstract_socket = EINA_TRUE;
|
||||
#ifdef HAVE_ABSTRACT_SOCKETS
|
||||
/* . is a placeholder */
|
||||
snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
|
||||
svr->name);
|
||||
/* first char null indicates abstract namespace */
|
||||
socket_unix.sun_path[0] = '\0';
|
||||
socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
|
||||
svr->name);
|
||||
#else
|
||||
ERR("Your system does not support abstract sockets!");
|
||||
goto error_umask;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
abstract_socket = EINA_FALSE;
|
||||
strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path) - 1);
|
||||
socket_unix.sun_path[sizeof(socket_unix.sun_path) - 1] = '\0';
|
||||
socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (svr->type & ECORE_CON_SOCKET_ACTIVATE && sd_fd_index < sd_fd_max)
|
||||
{
|
||||
if (sd_is_socket_unix(SD_LISTEN_FDS_START + sd_fd_index,
|
||||
SOCK_STREAM, 1,
|
||||
socket_unix.sun_path,
|
||||
abstract_socket ? socket_unix_len : 0) <= 0)
|
||||
{
|
||||
ERR("Your systemd unit seems to provide fd in the wrong order for Socket activation.");
|
||||
goto error_umask;
|
||||
}
|
||||
svr->fd = SD_LISTEN_FDS_START + sd_fd_index++;
|
||||
|
||||
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
||||
goto error_umask;
|
||||
|
||||
lin.l_onoff = 1;
|
||||
lin.l_linger = 0;
|
||||
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
|
||||
sizeof(struct linger)) < 0)
|
||||
goto error_umask;
|
||||
|
||||
goto fd_ready;
|
||||
}
|
||||
#else
|
||||
(void)abstract_socket;
|
||||
#endif
|
||||
svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (svr->fd < 0)
|
||||
goto error_umask;
|
||||
|
||||
if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
|
||||
goto error_fd;
|
||||
|
||||
if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
|
||||
goto error_fd;
|
||||
|
||||
lin.l_onoff = 1;
|
||||
lin.l_linger = 0;
|
||||
if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
|
||||
sizeof(struct linger)) < 0)
|
||||
goto error_fd;
|
||||
|
||||
if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
|
||||
{
|
||||
DBG("Local socket '%s' bind failed: %s", buf, strerror(errno));
|
||||
if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
|
||||
((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
|
||||
(connect(svr->fd, (struct sockaddr *)&socket_unix,
|
||||
socket_unix_len) < 0))
|
||||
{
|
||||
DBG("Local socket '%s' connect test failed: %s", buf, strerror(errno));
|
||||
if (unlink(buf) >= 0)
|
||||
goto start;
|
||||
else
|
||||
{
|
||||
DBG("Local socket '%s' removal failed: %s", buf, strerror(errno));
|
||||
goto error_fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(svr->fd, 4096) < 0)
|
||||
goto error_fd;
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
fd_ready:
|
||||
#endif
|
||||
svr->path = buf;
|
||||
buf = NULL;
|
||||
|
||||
svr->fd_handler =
|
||||
ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
|
||||
cb_listen, obj, NULL, NULL);
|
||||
umask(pmode);
|
||||
if (!svr->fd_handler)
|
||||
goto error;
|
||||
|
||||
free(buf);
|
||||
|
||||
return 1;
|
||||
|
||||
error_fd:
|
||||
close(svr->fd);
|
||||
svr->fd = -1;
|
||||
error_umask:
|
||||
umask(pmode);
|
||||
error:
|
||||
free(buf);
|
||||
#endif /* HAVE_LOCAL_SOCKETS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,20 +8,14 @@
|
|||
#define ECORE_MAGIC_CON_CLIENT 0x77556677
|
||||
#define ECORE_MAGIC_CON_URL 0x77074255
|
||||
|
||||
#define ECORE_CON_TYPE 0x0f
|
||||
#define ECORE_CON_SSL 0xf0
|
||||
#define ECORE_CON_SUPER_SSL 0xf00
|
||||
|
||||
#if HAVE_GNUTLS
|
||||
# include <gnutls/gnutls.h>
|
||||
#elif HAVE_OPENSSL
|
||||
# include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define READBUFSIZ 65536
|
||||
|
@ -58,174 +52,8 @@ extern int _ecore_con_log_dom;
|
|||
#endif
|
||||
#define CRI(...) EINA_LOG_DOM_CRIT(_ecore_con_log_dom, __VA_ARGS__)
|
||||
|
||||
typedef struct _Ecore_Con_Lookup Ecore_Con_Lookup;
|
||||
typedef struct _Ecore_Con_Info Ecore_Con_Info;
|
||||
typedef struct Ecore_Con_Socks Ecore_Con_Socks_v4;
|
||||
typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5;
|
||||
typedef void (*Ecore_Con_Info_Cb)(void *data, Ecore_Con_Info *infos);
|
||||
|
||||
typedef enum _Ecore_Con_State
|
||||
{
|
||||
ECORE_CON_CONNECTED,
|
||||
ECORE_CON_DISCONNECTED,
|
||||
ECORE_CON_INPROGRESS
|
||||
} Ecore_Con_State;
|
||||
|
||||
typedef enum _Ecore_Con_Ssl_Error
|
||||
{
|
||||
ECORE_CON_SSL_ERROR_NONE = 0,
|
||||
ECORE_CON_SSL_ERROR_NOT_SUPPORTED,
|
||||
ECORE_CON_SSL_ERROR_INIT_FAILED,
|
||||
ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED,
|
||||
ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED,
|
||||
ECORE_CON_SSL_ERROR_SSL3_NOT_SUPPORTED
|
||||
} Ecore_Con_Ssl_Error;
|
||||
|
||||
typedef enum _Ecore_Con_Ssl_Handshake
|
||||
{
|
||||
ECORE_CON_SSL_STATE_DONE = 0,
|
||||
ECORE_CON_SSL_STATE_HANDSHAKING,
|
||||
ECORE_CON_SSL_STATE_INIT
|
||||
} Ecore_Con_Ssl_State;
|
||||
|
||||
typedef enum Ecore_Con_Proxy_State
|
||||
{ /* named PROXY instead of SOCKS in case some handsome and enterprising
|
||||
* developer decides to add HTTP CONNECT support
|
||||
*/
|
||||
ECORE_CON_PROXY_STATE_DONE = 0,
|
||||
ECORE_CON_PROXY_STATE_RESOLVED,
|
||||
ECORE_CON_PROXY_STATE_INIT,
|
||||
ECORE_CON_PROXY_STATE_READ,
|
||||
ECORE_CON_PROXY_STATE_AUTH,
|
||||
ECORE_CON_PROXY_STATE_REQUEST,
|
||||
ECORE_CON_PROXY_STATE_CONFIRM,
|
||||
} Ecore_Con_Proxy_State;
|
||||
|
||||
struct _Efl_Network_Client_Data
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SOCKET fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
Ecore_Con_Server *host_server;
|
||||
void *data;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
size_t buf_offset;
|
||||
Eina_Binbuf *buf;
|
||||
const char *ip;
|
||||
Eina_List *event_count;
|
||||
struct sockaddr *client_addr;
|
||||
int client_addr_len;
|
||||
double start_time;
|
||||
Ecore_Timer *until_deletion;
|
||||
double disconnect_time;
|
||||
#if HAVE_GNUTLS
|
||||
gnutls_datum_t session_ticket;
|
||||
gnutls_session_t session;
|
||||
#elif HAVE_OPENSSL
|
||||
SSL *ssl;
|
||||
int ssl_err;
|
||||
#endif
|
||||
Ecore_Con_Ssl_State ssl_state;
|
||||
Eina_Bool handshaking : 1;
|
||||
Eina_Bool upgrade : 1; /* STARTTLS queued */
|
||||
Eina_Bool delete_me : 1; /* del event has been queued */
|
||||
};
|
||||
|
||||
typedef struct _Efl_Network_Client_Data Efl_Network_Client_Data;
|
||||
|
||||
struct _Efl_Network_Server_Data
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SOCKET fd;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
Ecore_Con_Type type;
|
||||
char *name;
|
||||
int port;
|
||||
char *path;
|
||||
void *data;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
Eina_List *clients;
|
||||
unsigned int client_count;
|
||||
Eina_Binbuf *buf;
|
||||
size_t write_buf_offset;
|
||||
Eina_List *infos;
|
||||
Eina_List *event_count;
|
||||
int client_limit;
|
||||
pid_t ppid;
|
||||
/* socks */
|
||||
Ecore_Con_Socks *ecs;
|
||||
Ecore_Con_Proxy_State ecs_state;
|
||||
int ecs_addrlen;
|
||||
unsigned char ecs_addr[16];
|
||||
size_t ecs_buf_offset;
|
||||
Eina_Binbuf *ecs_buf;
|
||||
Eina_Binbuf *ecs_recvbuf;
|
||||
const char *proxyip;
|
||||
int proxyport;
|
||||
/* endsocks */
|
||||
const char *verify_name;
|
||||
#if HAVE_GNUTLS
|
||||
gnutls_session_t session;
|
||||
gnutls_anon_client_credentials_t anoncred_c;
|
||||
gnutls_anon_server_credentials_t anoncred_s;
|
||||
gnutls_psk_client_credentials_t pskcred_c;
|
||||
gnutls_psk_server_credentials_t pskcred_s;
|
||||
gnutls_certificate_credentials_t cert;
|
||||
char *cert_file;
|
||||
gnutls_dh_params_t dh_params;
|
||||
#elif HAVE_OPENSSL
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl;
|
||||
int ssl_err;
|
||||
#endif
|
||||
double start_time;
|
||||
Ecore_Timer *until_deletion;
|
||||
double disconnect_time;
|
||||
double client_disconnect_time;
|
||||
const char *ip;
|
||||
Eina_Bool created : 1; /* @c EINA_TRUE if server is our listening server */
|
||||
Eina_Bool connecting : 1; /* @c EINA_FALSE if just initialized or connected */
|
||||
Eina_Bool handshaking : 1; /* @c EINA_TRUE if server is ssl handshaking */
|
||||
Eina_Bool upgrade : 1; /* STARTTLS queued */
|
||||
Eina_Bool disable_proxy : 1; /* proxy should never be used with this connection */
|
||||
Eina_Bool ssl_prepared : 1;
|
||||
Eina_Bool use_cert : 1; /* @c EINA_TRUE if using certificate auth */
|
||||
Ecore_Con_Ssl_State ssl_state; /* current state of ssl handshake on the server */
|
||||
Eina_Bool verify : 1; /* @c EINA_TRUE if certificates will be verified */
|
||||
Eina_Bool verify_basic : 1; /* @c EINA_TRUE if certificates will be verified only against the hostname */
|
||||
Eina_Bool reject_excess_clients : 1;
|
||||
Eina_Bool delete_me : 1; /* del event has been queued */
|
||||
#ifdef _WIN32
|
||||
Eina_Bool want_write : 1;
|
||||
Eina_Bool read_stop : 1;
|
||||
Eina_Bool read_stopped : 1;
|
||||
HANDLE pipe;
|
||||
HANDLE thread_read;
|
||||
HANDLE event_read;
|
||||
HANDLE event_peek;
|
||||
DWORD nbr_bytes;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _Efl_Network_Server_Data Efl_Network_Server_Data;
|
||||
|
||||
struct _Ecore_Con_Info
|
||||
{
|
||||
unsigned int size;
|
||||
struct addrinfo info;
|
||||
char ip[NI_MAXHOST];
|
||||
char service[NI_MAXSERV];
|
||||
};
|
||||
|
||||
struct _Ecore_Con_Lookup
|
||||
{
|
||||
Ecore_Con_Dns_Cb done_cb;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
struct Ecore_Con_Socks /* v4 */
|
||||
{
|
||||
|
@ -267,124 +95,18 @@ void ecore_con_libproxy_proxies_free(char **proxies);
|
|||
char **ecore_con_libproxy_proxies_get(const char *url);
|
||||
|
||||
|
||||
Eina_Bool ecore_con_server_check(const Ecore_Con_Server *svr);
|
||||
|
||||
extern Ecore_Con_Socks *_ecore_con_proxy_once;
|
||||
extern Ecore_Con_Socks *_ecore_con_proxy_global;
|
||||
void ecore_con_socks_init(void);
|
||||
void ecore_con_socks_shutdown(void);
|
||||
Eina_Bool ecore_con_socks_svr_init(Ecore_Con_Server *svr);
|
||||
void ecore_con_socks_read(Ecore_Con_Server *svr, unsigned char *buf, int num);
|
||||
void ecore_con_socks_dns_cb(const char *canonname, const char *ip, struct sockaddr *addr, int addrlen, Ecore_Con_Server *svr);
|
||||
|
||||
/* from ecore_con.c */
|
||||
void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info);
|
||||
void ecore_con_event_proxy_bind(Ecore_Con_Server *svr);
|
||||
void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate);
|
||||
void ecore_con_event_server_del(Ecore_Con_Server *svr);
|
||||
#define ecore_con_event_server_error(svr, error) _ecore_con_event_server_error((svr), (char*)(error), EINA_TRUE)
|
||||
void _ecore_con_event_server_error(Ecore_Con_Server *svr, char *error, Eina_Bool duplicate);
|
||||
void ecore_con_event_client_add(Ecore_Con_Client *cl);
|
||||
void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate);
|
||||
void ecore_con_event_client_del(Ecore_Con_Client *cl);
|
||||
void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error);
|
||||
void _ecore_con_server_kill(Ecore_Con_Server *svr);
|
||||
void _ecore_con_client_kill(Ecore_Con_Client *cl);
|
||||
|
||||
int ecore_con_local_init(void);
|
||||
int ecore_con_local_shutdown(void);
|
||||
/* from ecore_local_win32.c */
|
||||
#ifdef _WIN32
|
||||
Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr);
|
||||
Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr,
|
||||
Eina_Bool (*cb_done)(void *data,
|
||||
Ecore_Fd_Handler *fd_handler));
|
||||
Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr);
|
||||
Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl);
|
||||
void ecore_con_local_win32_server_del(Ecore_Con_Server *svr);
|
||||
void ecore_con_local_win32_client_del(Ecore_Con_Client *cl);
|
||||
#else
|
||||
/* from ecore_local.c */
|
||||
int ecore_con_local_connect(Ecore_Con_Server *svr,
|
||||
Eina_Bool (*cb_done)(
|
||||
void *data,
|
||||
Ecore_Fd_Handler *fd_handler),
|
||||
void *data);
|
||||
int ecore_con_local_listen(Ecore_Con_Server *svr,
|
||||
Eina_Bool (*cb_listen)(
|
||||
void *data,
|
||||
Ecore_Fd_Handler *fd_handler),
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
/* from ecore_con_info.c */
|
||||
int ecore_con_info_init(void);
|
||||
int ecore_con_info_shutdown(void);
|
||||
int ecore_con_info_tcp_connect(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data);
|
||||
int ecore_con_info_tcp_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data);
|
||||
int ecore_con_info_udp_connect(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data);
|
||||
int ecore_con_info_udp_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data);
|
||||
int ecore_con_info_mcast_listen(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data);
|
||||
void ecore_con_info_data_clear(void *info);
|
||||
|
||||
void ecore_con_event_server_add(Ecore_Con_Server *svr);
|
||||
|
||||
|
||||
/* from ecore_con_ssl.c */
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_init(void);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_shutdown(void);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_server_prepare(Ecore_Con_Server *svr, int ssl_type);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_server_init(Ecore_Con_Server *svr);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_server_shutdown(Ecore_Con_Server *svr);
|
||||
int ecore_con_ssl_server_read(Ecore_Con_Server *svr,
|
||||
unsigned char *buf,
|
||||
int size);
|
||||
int ecore_con_ssl_server_write(Ecore_Con_Server *svr,
|
||||
const unsigned char *buf,
|
||||
int size);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_client_init(Ecore_Con_Client *svr);
|
||||
Ecore_Con_Ssl_Error ecore_con_ssl_client_shutdown(Ecore_Con_Client *svr);
|
||||
int ecore_con_ssl_client_read(Ecore_Con_Client *svr,
|
||||
unsigned char *buf,
|
||||
int size);
|
||||
int ecore_con_ssl_client_write(Ecore_Con_Client *svr,
|
||||
const unsigned char *buf,
|
||||
int size);
|
||||
|
||||
int ecore_con_info_get(Ecore_Con_Server *svr,
|
||||
Ecore_Con_Info_Cb done_cb,
|
||||
void *data,
|
||||
struct addrinfo *hints);
|
||||
|
||||
|
||||
#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
|
||||
TYPE *Type##_alloc(void); \
|
||||
void Type##_free(TYPE *e);
|
||||
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Add, ecore_con_event_client_add);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Del, ecore_con_event_client_del);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Write, ecore_con_event_client_write);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Data, ecore_con_event_client_data);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Error, ecore_con_event_server_error);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Client_Error, ecore_con_event_client_error);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Add, ecore_con_event_server_add);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Del, ecore_con_event_server_del);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Write, ecore_con_event_server_write);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Server_Data, ecore_con_event_server_data);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Con_Event_Proxy_Bind, ecore_con_event_proxy_bind);
|
||||
|
||||
void ecore_con_mempool_init(void);
|
||||
void ecore_con_mempool_shutdown(void);
|
||||
|
||||
#undef GENERIC_ALLOC_FREE_HEADER
|
||||
void ecore_con_legacy_init(void);
|
||||
void ecore_con_legacy_shutdown(void);
|
||||
|
||||
void _ecore_con_local_mkpath(const char *path, mode_t mode);
|
||||
|
||||
|
@ -429,6 +151,9 @@ void _ecore_con_local_mkpath(const char *path, mode_t mode);
|
|||
#ifndef AI_ADDRCONFIG
|
||||
#define AI_ADDRCONFIG 0
|
||||
#endif
|
||||
#ifndef AI_CANONNAME
|
||||
#define AI_CANONNAME 0
|
||||
#endif
|
||||
|
||||
/* Windows do not define EAI_SYSTEM, so just define to some number
|
||||
* that won't be matched, effectively disabling the subsequent
|
||||
|
|
|
@ -47,36 +47,6 @@
|
|||
#include "Ecore_Con.h"
|
||||
#include "ecore_con_private.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(IF_NAMESIZE)
|
||||
#define IF_NAMESIZE 16
|
||||
#endif
|
||||
|
||||
/* http://tools.ietf.org/html/rfc1928
|
||||
o X'00' NO AUTHENTICATION REQUIRED
|
||||
o X'01' GSSAPI
|
||||
o X'02' USERNAME/PASSWORD
|
||||
o X'03' to X'7F' IANA ASSIGNED
|
||||
o X'80' to X'FE' RESERVED FOR PRIVATE METHODS
|
||||
o X'FF' NO ACCEPTABLE METHODS
|
||||
*/
|
||||
#define ECORE_CON_SOCKS_V5_METHOD_NONE 0
|
||||
#define ECORE_CON_SOCKS_V5_METHOD_GSSAPI 1
|
||||
#define ECORE_CON_SOCKS_V5_METHOD_USERPASS 2
|
||||
|
||||
static int ECORE_CON_SOCKS_V5_METHODS[] =
|
||||
{
|
||||
ECORE_CON_SOCKS_V5_METHOD_NONE,
|
||||
// ECORE_CON_SOCKS_V5_METHOD_GSSAPI, TODO
|
||||
ECORE_CON_SOCKS_V5_METHOD_USERPASS
|
||||
};
|
||||
|
||||
#define ECORE_CON_SOCKS_V5_TOTAL_METHODS (sizeof(ECORE_CON_SOCKS_V5_METHODS) / sizeof(int))
|
||||
|
||||
#define _ecore_con_server_kill(svr) do { \
|
||||
DBG("KILL %p", (svr)); \
|
||||
_ecore_con_server_kill((svr)); \
|
||||
} while (0)
|
||||
|
||||
#define ECORE_CON_SOCKS_VERSION_CHECK(X) do { \
|
||||
if (!(X) || ((X)->version < 4) || ((X)->version > 5)) \
|
||||
return; \
|
||||
|
@ -86,15 +56,7 @@ static int ECORE_CON_SOCKS_V5_METHODS[] =
|
|||
return (ret); \
|
||||
} while (0)
|
||||
|
||||
#define ECORE_CON_SOCKS_CAST(X) \
|
||||
Ecore_Con_Socks_v4 * v4 = NULL; \
|
||||
Ecore_Con_Socks_v5 *v5 = NULL; \
|
||||
if ((X) && ((X)->version == 4)) \
|
||||
v4 = (Ecore_Con_Socks_v4 *)(X); \
|
||||
else if ((X) && ((X)->version == 5)) \
|
||||
v5 = (Ecore_Con_Socks_v5 *)(X);
|
||||
|
||||
Eina_List *ecore_con_socks_proxies = NULL;
|
||||
static Eina_List *ecore_con_socks_proxies = NULL;
|
||||
|
||||
static Ecore_Con_Socks *
|
||||
_ecore_con_socks_find(unsigned char version, const char *ip, int port, const char *username, size_t ulen, const char *password, size_t plen)
|
||||
|
@ -133,405 +95,6 @@ _ecore_con_socks_free(Ecore_Con_Socks *ecs)
|
|||
free(ecs);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_socks_svr_init_v4(Ecore_Con_Server *obj, Ecore_Con_Socks_v4 *v4)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
size_t addrlen, buflen, ulen = 1;
|
||||
unsigned char *sbuf;
|
||||
|
||||
addrlen = v4->lookup ? strlen(svr->name) + 1 : 0;
|
||||
if (v4->username) ulen += v4->ulen;
|
||||
buflen = sizeof(char) * (8 + ulen + addrlen);
|
||||
sbuf = malloc(buflen);
|
||||
if (!sbuf)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "Memory allocation failure!");
|
||||
_ecore_con_server_kill(obj);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
/* http://en.wikipedia.org/wiki/SOCKS */
|
||||
sbuf[0] = 4;
|
||||
sbuf[1] = v4->bind ? 2 : 1;
|
||||
sbuf[2] = svr->port >> 8;
|
||||
sbuf[3] = svr->port & 0xff;
|
||||
if (addrlen)
|
||||
{
|
||||
sbuf[4] = sbuf[5] = sbuf[6] = 0;
|
||||
sbuf[7] = 1;
|
||||
}
|
||||
else
|
||||
/* SOCKSv4 only handles IPV4, so addrlen is always 4 */
|
||||
memcpy(sbuf + 4, svr->ecs_addr, 4);
|
||||
if (v4->username)
|
||||
memcpy(sbuf + 8, v4->username, ulen);
|
||||
else
|
||||
sbuf[8] = 0;
|
||||
if (addrlen) memcpy(sbuf + 8 + ulen, svr->name, addrlen);
|
||||
|
||||
svr->ecs_buf = eina_binbuf_manage_new(sbuf, buflen, EINA_FALSE);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_socks_svr_init_v5(Ecore_Con_Server *obj, Ecore_Con_Socks_v5 *v5)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
size_t buflen;
|
||||
unsigned int x;
|
||||
unsigned char *sbuf;
|
||||
|
||||
if (v5->username)
|
||||
buflen = sizeof(char) * (2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS);
|
||||
else
|
||||
buflen = 3;
|
||||
sbuf = malloc(buflen);
|
||||
if (!sbuf)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "Memory allocation failure!");
|
||||
_ecore_con_server_kill(obj);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
/* http://en.wikipedia.org/wiki/SOCKS
|
||||
* http://tools.ietf.org/html/rfc1928
|
||||
*/
|
||||
sbuf[0] = 5;
|
||||
if (v5->username)
|
||||
{
|
||||
sbuf[1] = ECORE_CON_SOCKS_V5_TOTAL_METHODS;
|
||||
for (x = 2; x < 2 + ECORE_CON_SOCKS_V5_TOTAL_METHODS; x++)
|
||||
sbuf[x] = ECORE_CON_SOCKS_V5_METHODS[x - 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
sbuf[1] = 1;
|
||||
sbuf[2] = ECORE_CON_SOCKS_V5_METHOD_NONE;
|
||||
}
|
||||
|
||||
svr->ecs_buf = eina_binbuf_manage_new(sbuf, buflen, EINA_FALSE);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
#define ECORE_CON_SOCKS_READ(EXACT) \
|
||||
if (num < EXACT) \
|
||||
{ \
|
||||
if (!svr->ecs_recvbuf) svr->ecs_recvbuf = eina_binbuf_new(); \
|
||||
if (!svr->ecs_recvbuf) goto error; \
|
||||
eina_binbuf_append_length(svr->ecs_recvbuf, buf, num); \
|
||||
/* the slowest connection on earth */ \
|
||||
if (eina_binbuf_length_get(svr->ecs_recvbuf) != EXACT) return; \
|
||||
data = eina_binbuf_string_get(svr->ecs_recvbuf); \
|
||||
} \
|
||||
else if (num > EXACT) \
|
||||
goto error; \
|
||||
else \
|
||||
data = buf
|
||||
|
||||
static void
|
||||
_ecore_con_socks_read_v4(Ecore_Con_Server *obj, Ecore_Con_Socks_v4 *v4 EINA_UNUSED, const unsigned char *buf, unsigned int num)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
const unsigned char *data;
|
||||
DBG("SOCKS: %d bytes", num);
|
||||
ECORE_CON_SOCKS_READ(8);
|
||||
|
||||
/* http://ufasoft.com/doc/socks4_protocol.htm */
|
||||
if (data[0]) goto error;
|
||||
switch (data[1])
|
||||
{
|
||||
case 90:
|
||||
/* success! */
|
||||
break;
|
||||
|
||||
case 91:
|
||||
ecore_con_event_server_error(obj, "proxy request rejected or failed");
|
||||
goto error;
|
||||
|
||||
case 92:
|
||||
ecore_con_event_server_error(obj, "proxying SOCKS server could not perform authentication");
|
||||
goto error;
|
||||
|
||||
case 93:
|
||||
ecore_con_event_server_error(obj, "proxy request authentication rejected");
|
||||
goto error;
|
||||
|
||||
default:
|
||||
ecore_con_event_server_error(obj, "garbage data from proxy");
|
||||
goto error;
|
||||
}
|
||||
if (svr->ecs->bind)
|
||||
{
|
||||
unsigned int nport;
|
||||
char naddr[IF_NAMESIZE];
|
||||
|
||||
memcpy(&nport, &data[2], 2);
|
||||
svr->proxyport = ntohl(nport);
|
||||
|
||||
if (!inet_ntop(AF_INET, &data[4], naddr, sizeof(naddr))) goto error;
|
||||
svr->proxyip = eina_stringshare_add(naddr);
|
||||
ecore_con_event_proxy_bind(obj);
|
||||
}
|
||||
svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
|
||||
INF("PROXY CONNECTED");
|
||||
if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
|
||||
svr->ecs_recvbuf = NULL;
|
||||
svr->ecs_buf_offset = svr->ecs_addrlen = 0;
|
||||
memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
|
||||
if (!svr->ssl_state)
|
||||
ecore_con_event_server_add(obj);
|
||||
if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
|
||||
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
|
||||
return;
|
||||
error:
|
||||
_ecore_con_server_kill(obj);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_socks_auth_v5(Ecore_Con_Server *obj, Ecore_Con_Socks_v5 *v5)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
size_t size;
|
||||
unsigned char *data;
|
||||
switch (v5->method)
|
||||
{
|
||||
case ECORE_CON_SOCKS_V5_METHOD_NONE:
|
||||
svr->ecs_state = ECORE_CON_PROXY_STATE_REQUEST;
|
||||
return EINA_TRUE;
|
||||
|
||||
case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
|
||||
return EINA_TRUE;
|
||||
|
||||
case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
|
||||
if (!v5->username) return EINA_FALSE;
|
||||
if (!v5->password) v5->plen = 1;
|
||||
/* http://tools.ietf.org/html/rfc1929 */
|
||||
size = sizeof(char) * (3 + v5->ulen + v5->plen);
|
||||
data = malloc(size);
|
||||
if (!data) break;
|
||||
data[0] = 1;
|
||||
data[1] = v5->ulen;
|
||||
memcpy(&data[2], v5->username, v5->ulen);
|
||||
data[1 + v5->ulen] = v5->plen;
|
||||
if (v5->password)
|
||||
memcpy(&data[2 + v5->ulen], v5->password, v5->plen);
|
||||
else
|
||||
data[2 + v5->ulen] = 0;
|
||||
svr->ecs_buf = eina_binbuf_manage_new(data, size, EINA_FALSE);
|
||||
return EINA_TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_socks_read_v5(Ecore_Con_Server *obj, Ecore_Con_Socks_v5 *v5, const unsigned char *buf, unsigned int num)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
const unsigned char *data;
|
||||
|
||||
DBG("SOCKS: %d bytes", num);
|
||||
switch (svr->ecs_state)
|
||||
{
|
||||
case ECORE_CON_PROXY_STATE_READ:
|
||||
ECORE_CON_SOCKS_READ(2);
|
||||
/* http://en.wikipedia.org/wiki/SOCKS */
|
||||
if (data[0] != 5) goto error;
|
||||
if (data[1] == 0xFF)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "proxy authentication methods rejected");
|
||||
goto error;
|
||||
}
|
||||
v5->method = data[1];
|
||||
if (!_ecore_con_socks_auth_v5(obj, v5)) goto error;
|
||||
if (svr->ecs_state == ECORE_CON_PROXY_STATE_REQUEST)
|
||||
{
|
||||
/* run again to skip auth reading */
|
||||
_ecore_con_socks_read_v5(obj, v5, NULL, 0);
|
||||
return;
|
||||
}
|
||||
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
|
||||
svr->ecs_state = ECORE_CON_PROXY_STATE_AUTH;
|
||||
break;
|
||||
|
||||
case ECORE_CON_PROXY_STATE_AUTH:
|
||||
ECORE_CON_SOCKS_READ(2);
|
||||
switch (v5->method)
|
||||
{
|
||||
case ECORE_CON_SOCKS_V5_METHOD_NONE:
|
||||
CRI("HOW DID THIS HAPPEN?????????");
|
||||
goto error;
|
||||
|
||||
case ECORE_CON_SOCKS_V5_METHOD_GSSAPI:
|
||||
/* TODO: this */
|
||||
break;
|
||||
|
||||
case ECORE_CON_SOCKS_V5_METHOD_USERPASS:
|
||||
if (data[0] != 1)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "protocol error");
|
||||
goto error; /* wrong version */
|
||||
}
|
||||
if (data[1])
|
||||
{
|
||||
ecore_con_event_server_error(obj, "proxy request authentication rejected");
|
||||
goto error;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ECORE_CON_PROXY_STATE_REQUEST:
|
||||
{
|
||||
size_t addrlen, buflen;
|
||||
unsigned char *sbuf;
|
||||
addrlen = v5->lookup ? strlen(svr->name) + 1 : (unsigned int)svr->ecs_addrlen;
|
||||
buflen = sizeof(char) * (6 + addrlen);
|
||||
sbuf = malloc(buflen);
|
||||
if (!sbuf)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "Memory allocation failure!");
|
||||
goto error;
|
||||
}
|
||||
sbuf[0] = 5;
|
||||
sbuf[1] = v5->bind ? 2 : 1; /* TODO: 0x03 for UDP port association */
|
||||
sbuf[2] = 0;
|
||||
if (v5->lookup) /* domain name */
|
||||
{
|
||||
sbuf[3] = 3;
|
||||
sbuf[4] = addrlen - 1;
|
||||
memcpy(sbuf + 5, svr->name, addrlen - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sbuf[3] = (svr->ecs_addrlen == 4) ? 1 : 4;
|
||||
memcpy(sbuf + 4, svr->ecs_addr, addrlen);
|
||||
}
|
||||
sbuf[addrlen + 4] = svr->port >> 8;
|
||||
sbuf[addrlen + 5] = svr->port & 0xff;
|
||||
|
||||
svr->ecs_buf = eina_binbuf_manage_new(sbuf, buflen, EINA_FALSE);
|
||||
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
|
||||
break;
|
||||
}
|
||||
|
||||
case ECORE_CON_PROXY_STATE_CONFIRM:
|
||||
{
|
||||
/* this is ugly because we have to read an exact number of bytes,
|
||||
* but we don't know what that number is until we've already read
|
||||
* at least 5 bytes to determine the length of the unknown stream.
|
||||
* yep.
|
||||
*/
|
||||
size_t to_read, len = svr->ecs_recvbuf ? eina_binbuf_length_get(svr->ecs_recvbuf) : 0;
|
||||
if (num + len < 5)
|
||||
{
|
||||
/* guarantees we get called again */
|
||||
ECORE_CON_SOCKS_READ(5);
|
||||
}
|
||||
if (len >= 5)
|
||||
{
|
||||
data = eina_binbuf_string_get(svr->ecs_recvbuf);
|
||||
data += 3;
|
||||
}
|
||||
else
|
||||
data = buf + 3 - len;
|
||||
switch (data[0])
|
||||
{
|
||||
case 1:
|
||||
to_read = 4;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
to_read = data[1] + 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
to_read = 16;
|
||||
/* lazy debugging stub comment */
|
||||
break;
|
||||
|
||||
default:
|
||||
ecore_con_event_server_error(obj, "protocol error");
|
||||
goto error;
|
||||
}
|
||||
/* at this point, we finally know exactly how much we need to read */
|
||||
ECORE_CON_SOCKS_READ(6 + to_read);
|
||||
|
||||
if (data[0] != 5)
|
||||
{
|
||||
ecore_con_event_server_error(obj, "protocol error");
|
||||
goto error; /* wrong version */
|
||||
}
|
||||
switch (data[1])
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ecore_con_event_server_error(obj, "general proxy failure");
|
||||
goto error;
|
||||
|
||||
case 2:
|
||||
ecore_con_event_server_error(obj, "connection not allowed by ruleset");
|
||||
goto error;
|
||||
|
||||
case 3:
|
||||
ecore_con_event_server_error(obj, "network unreachable");
|
||||
goto error;
|
||||
|
||||
case 4:
|
||||
ecore_con_event_server_error(obj, "host unreachable");
|
||||
goto error;
|
||||
|
||||
case 5:
|
||||
ecore_con_event_server_error(obj, "connection refused by destination host");
|
||||
goto error;
|
||||
|
||||
case 6:
|
||||
ecore_con_event_server_error(obj, "TTL expired");
|
||||
goto error;
|
||||
|
||||
case 7:
|
||||
ecore_con_event_server_error(obj, "command not supported / protocol error");
|
||||
goto error;
|
||||
|
||||
case 8:
|
||||
ecore_con_event_server_error(obj, "address type not supported");
|
||||
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
if (data[2])
|
||||
{
|
||||
ecore_con_event_server_error(obj, "protocol error");
|
||||
goto error;
|
||||
}
|
||||
memset(svr->ecs_addr, 0, sizeof(svr->ecs_addr));
|
||||
if (!svr->ssl_state)
|
||||
ecore_con_event_server_add(obj);
|
||||
if (svr->ssl_state || (svr->buf && eina_binbuf_length_get(svr->buf)))
|
||||
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ | ECORE_FD_WRITE);
|
||||
svr->ecs_buf_offset = svr->ecs_addrlen = 0;
|
||||
svr->ecs_state = ECORE_CON_PROXY_STATE_DONE;
|
||||
INF("PROXY CONNECTED");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (svr->ecs_recvbuf) eina_binbuf_free(svr->ecs_recvbuf);
|
||||
svr->ecs_recvbuf = NULL;
|
||||
|
||||
return;
|
||||
error:
|
||||
_ecore_con_server_kill(obj);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
ecore_con_socks_shutdown(void)
|
||||
{
|
||||
|
@ -542,55 +105,6 @@ ecore_con_socks_shutdown(void)
|
|||
_ecore_con_proxy_global = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_con_socks_read(Ecore_Con_Server *obj, unsigned char *buf, int num)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
ECORE_CON_SOCKS_VERSION_CHECK(svr->ecs);
|
||||
ECORE_CON_SOCKS_CAST(svr->ecs);
|
||||
|
||||
if (svr->ecs_state < ECORE_CON_PROXY_STATE_READ) return;
|
||||
|
||||
if (v4) _ecore_con_socks_read_v4(obj, v4, buf, (unsigned int)num);
|
||||
else _ecore_con_socks_read_v5(obj, v5, buf, (unsigned int)num);
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
ecore_con_socks_svr_init(Ecore_Con_Server *obj)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
ECORE_CON_SOCKS_VERSION_CHECK_RETURN(svr->ecs, EINA_FALSE);
|
||||
ECORE_CON_SOCKS_CAST(svr->ecs);
|
||||
|
||||
if (!svr->ip) return EINA_FALSE;
|
||||
if (svr->ecs_buf) return EINA_FALSE;
|
||||
if (svr->ecs_state != ECORE_CON_PROXY_STATE_INIT) return EINA_FALSE;
|
||||
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_WRITE);
|
||||
if (v4) return _ecore_con_socks_svr_init_v4(obj, v4);
|
||||
return _ecore_con_socks_svr_init_v5(obj, v5);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_con_socks_dns_cb(const char *canonname EINA_UNUSED, const char *ip, struct sockaddr *addr, int addrlen EINA_UNUSED, Ecore_Con_Server *obj)
|
||||
{
|
||||
Efl_Network_Server_Data *svr = efl_data_scope_get(obj, EFL_NETWORK_SERVER_CLASS);
|
||||
svr->ip = eina_stringshare_add(ip);
|
||||
svr->ecs_state++;
|
||||
if (addr->sa_family == AF_INET)
|
||||
{
|
||||
memcpy(svr->ecs_addr, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4);
|
||||
svr->ecs_addrlen = 4;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
memcpy(svr->ecs_addr, &((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr, 16);
|
||||
svr->ecs_addrlen = 16;
|
||||
}
|
||||
#endif
|
||||
ecore_con_socks_svr_init(obj);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_con_socks_init(void)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,201 +0,0 @@
|
|||
type Ecore_Con_Dns_Cb: __undefined_type; [[Ecore connection DNS callback type]]
|
||||
|
||||
enum Ecore.Con.Type
|
||||
{
|
||||
[[Types for an ecore_con client/server object. A correct way to set this type is
|
||||
with an ECORE_CON_$TYPE, optionally OR'ed with an ECORE_CON_$USE if encryption is desired,
|
||||
and LOAD_CERT if the previously loaded certificate should be used.]]
|
||||
legacy: ecore_con;
|
||||
|
||||
local_user = 0, [[Socket in "~/.ecore"]]
|
||||
local_system = 1, [[Socket in /tmp]]
|
||||
local_abstract = 2, [[Abstract socket]]
|
||||
remote_tcp = 3, [[Remote server using TCP]]
|
||||
remote_mcast = 4, [[Remote multicast server]]
|
||||
remote_udp = 5, [[Remote server using UDP]]
|
||||
remote_broadcasT = 6, [[Remote broadcast using UDP]]
|
||||
remote_nodelay = 7, [[Remote connection sending packets immediately]]
|
||||
remote_cork = 8, [[Remote connection sending data in large chunks
|
||||
Note: Only available on Linux
|
||||
@since 1.2]]
|
||||
use_ssl2 = (1 << 4), [[Use SSL2: UNSUPPORTED.]]
|
||||
use_ssl3 = (1 << 5), [[Use SSL3: UNSUPPORTED.]]
|
||||
use_tls = (1 << 6), [[Use TLS]]
|
||||
use_mixed = Ecore.Con.Type.use_tls | Ecore.Con.Type.use_ssl3, [[Use both TLS and SSL3]]
|
||||
load_cert = (1 << 7), [[Attempt to use the loaded certificate]]
|
||||
no_proxy = (1 << 8), [[Disable all types of proxy on the server
|
||||
Note: Only functional for clients
|
||||
@since 1.2]]
|
||||
socket_activate = (1 << 9) [[Indicate if the type is socket activated]]
|
||||
}
|
||||
|
||||
abstract Efl.Network (Efl.Object) {
|
||||
[[Abstract base class for all EFL.Network classes]]
|
||||
|
||||
legacy_prefix: ecore_con;
|
||||
eo_prefix: efl_network;
|
||||
data: null;
|
||||
methods {
|
||||
@property ip {
|
||||
[[Control the IP address of a server that has been connected to.
|
||||
|
||||
The parameter is a pointer to an internal string that contains the IP
|
||||
address of the connected server in the form "XXX.YYY.ZZZ.AAA" IP
|
||||
notation. This string should not be modified or trusted to stay
|
||||
valid after deletion for the svr object. If no IP is known
|
||||
null is returned.
|
||||
]]
|
||||
get @virtual_pure {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
ip: string; [[The IP address]]
|
||||
}
|
||||
}
|
||||
@property uptime {
|
||||
[[Check how long the object has been connected
|
||||
|
||||
This function is used to find out how long a client has been
|
||||
connected.
|
||||
]]
|
||||
get @virtual_pure {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
uptime: double; [[The total time, in seconds, that the object has been connected.]]
|
||||
}
|
||||
}
|
||||
@property port @virtual_pure {
|
||||
[[The port that the obj is connected to]]
|
||||
set {
|
||||
legacy: null;
|
||||
}
|
||||
get {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
port: int; [[The port that obj is connected to, or -1 on error.]]
|
||||
}
|
||||
}
|
||||
@property fd {
|
||||
[[Get the fd that the server is connected to
|
||||
|
||||
This function returns the fd which is used by the underlying server
|
||||
connection. It should not be tampered with unless you REALLY know
|
||||
what you are doing.
|
||||
|
||||
Note: This function is only valid for servers created with
|
||||
\@ref ecore_con_server_connect.
|
||||
|
||||
Warning: Seriously. Don't use this unless you know what you are doing.
|
||||
|
||||
@since 1.1
|
||||
]]
|
||||
get @virtual_pure {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
fd: int; [[The fd, or -1 on failure.]]
|
||||
}
|
||||
}
|
||||
@property connected {
|
||||
[[Returns whether the client is still connected]]
|
||||
get @virtual_pure {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
connected: bool; [[$true if connected, $false otherwise.]]
|
||||
}
|
||||
}
|
||||
@property timeout @virtual_pure {
|
||||
[[Control the default time after which an inactive client will be
|
||||
disconnected.
|
||||
|
||||
This function is used by the server to set the default idle timeout
|
||||
on clients. If any of the clients becomes idle for a time higher
|
||||
than this value, it will be disconnected. A value of < 1 disables
|
||||
the idle timeout.
|
||||
|
||||
This timeout is not affected by the one set by @.timeout.set. A
|
||||
client will be disconnected whenever the client or the server
|
||||
timeout is reached. That means, the lower timeout value will be
|
||||
used for that client if @.timeout.set is used on it.
|
||||
]]
|
||||
set {
|
||||
legacy: null;
|
||||
}
|
||||
get {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
timeout: double; [[The timeout, in seconds, to disconnect after.]]
|
||||
}
|
||||
}
|
||||
flush @virtual_pure {
|
||||
[[Flushes all pending data to the given server.
|
||||
|
||||
This function will block until all data is sent to the server.
|
||||
]]
|
||||
legacy: null;
|
||||
}
|
||||
send @virtual_pure {
|
||||
[[Sends the given data to the given server.
|
||||
|
||||
This function will send the given data to the server as soon as the
|
||||
program is back to the main loop. Thus, this function returns
|
||||
immediately (non-blocking). If the data needs to be sent now, call
|
||||
\@ref ecore_con_server_flush after this one.
|
||||
]]
|
||||
legacy: null;
|
||||
|
||||
params {
|
||||
data: const(void_ptr); [[The given data]]
|
||||
size: int; [[Length of the data, in bytes.]]
|
||||
}
|
||||
return: int; [[The number of bytes sent. 0 will be returned if there
|
||||
is an error.]]
|
||||
}
|
||||
lookup @class {
|
||||
[[Do an asynchronous DNS lookup.
|
||||
|
||||
This function performs a DNS lookup on the hostname specified by name,
|
||||
then calls done_cb with the result and the data given as parameter.
|
||||
The result will be given to the done_cb as follows:
|
||||
|
||||
canonname - the canonical name of the address, ip - the resolved ip
|
||||
address, addr - a pointer to the socket address, addrlen - the length
|
||||
of the socket address, in bytes, data - the data pointer given as
|
||||
parameter.
|
||||
]]
|
||||
params {
|
||||
name: string @nonull; [[IP address or server name to translate.]]
|
||||
done_cb: Ecore_Con_Dns_Cb; [[Callback to notify when done.]]
|
||||
data: const(void_ptr); [[User data to be given to done_cb.]]
|
||||
}
|
||||
return: bool; [[$true if the request did not fail to be set up, $false otherwise.]]
|
||||
}
|
||||
}
|
||||
events {
|
||||
data,received: Ecore.Con.Event_Data.Received; [[Data received on connection]]
|
||||
connection,upgraded; [[FIXME: what does upgrade mean here??]]
|
||||
connection,error: string; [[Error received on connection]]
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Should actually be a binbuf. */
|
||||
struct Ecore.Con.Event_Data.Received {
|
||||
[[Ecore connection event data received data structure]]
|
||||
data: void_ptr; [[The data that got sent.]]
|
||||
size: int; [[The length of the data sent.]]
|
||||
}
|
||||
|
||||
/* TODO
|
||||
* Add events (to all of the ecore con stuff, e.g url).
|
||||
* Make server the father of the client - make sure I don't leak references.
|
||||
*
|
||||
* Still need to add constructor client, and most likely migrate ecore_con_eet.
|
||||
*
|
||||
* Split server to two classes, listener and connector (or w/e).
|
||||
*
|
||||
* Mark the constructing properties all around.
|
||||
*/
|
|
@ -1,30 +0,0 @@
|
|||
class Efl.Network.Client (Efl.Network) {
|
||||
[[Efl network client]]
|
||||
legacy_prefix: ecore_con_client;
|
||||
eo_prefix: efl_network_client_obj;
|
||||
methods {
|
||||
@property server {
|
||||
[[The server the client is connected to.]]
|
||||
get {
|
||||
}
|
||||
values {
|
||||
svr: Efl.Network.Server; [[The server the client is connected to.]]
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.destructor;
|
||||
Efl.Network.ip.get;
|
||||
Efl.Network.uptime.get;
|
||||
Efl.Network.port.get;
|
||||
Efl.Network.fd.get;
|
||||
Efl.Network.connected.get;
|
||||
Efl.Network.timeout.set;
|
||||
Efl.Network.timeout.get;
|
||||
Efl.Network.flush;
|
||||
Efl.Network.send;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: Should SSL inherit from client? What's exactly the interaction here?
|
||||
Fix clients to be children of server when created .*/
|
|
@ -1,8 +0,0 @@
|
|||
class Efl.Network.Connector (Efl.Network.Server) {
|
||||
[[Efl network connector class]]
|
||||
eo_prefix: efl_network_connector_obj;
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Object.finalize;
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
class Efl.Network.Server (Efl.Network) {
|
||||
[[Efl network server]]
|
||||
legacy_prefix: ecore_con_server;
|
||||
eo_prefix: efl_network_server;
|
||||
methods {
|
||||
@property name {
|
||||
[[Retrieves the name of server.
|
||||
|
||||
The name returned is the name used to connect on this server.
|
||||
]]
|
||||
set {
|
||||
legacy: null;
|
||||
}
|
||||
get {
|
||||
}
|
||||
values {
|
||||
name: string; [[The name of the server.]]
|
||||
}
|
||||
}
|
||||
@property client_limit {
|
||||
[[Sets a limit on the number of clients that can be handled concurrently
|
||||
by the given server, and a policy on what to do if excess clients
|
||||
try to connect.
|
||||
|
||||
Beware that if you set this once ecore is already running, you may
|
||||
already have pending CLIENT_ADD events in your event queue. Those
|
||||
clients have already connected and will not be affected by this call.
|
||||
Only clients subsequently trying to connect will be affected.
|
||||
]]
|
||||
set {
|
||||
}
|
||||
get {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
client_limit: int; [[The maximum number of clients to handle
|
||||
concurrently. -1 means unlimited (default).
|
||||
0 effectively disables the server.]]
|
||||
reject_excess_clients: char; [[Set to 1 to automatically disconnect excess clients as
|
||||
soon as they connect if you are already handling
|
||||
client_limit clients. Set to 0 (default) to just
|
||||
hold off on the "accept()" system call until the
|
||||
number of active clients drops. This causes the
|
||||
kernel to queue up to 4096 connections (or your
|
||||
kernel's limit, whichever is lower).
|
||||
]]
|
||||
}
|
||||
}
|
||||
/* FIXME: Should this return an iterator? */
|
||||
@property clients {
|
||||
[[Retrieves the current list of clients.
|
||||
|
||||
Each node in the returned list points to an \@ref Efl_Network_Client.
|
||||
This list cannot be modified or freed. It can also change if new
|
||||
clients are connected or disconnected, and will become invalid
|
||||
when the server is deleted/freed.
|
||||
]]
|
||||
get {
|
||||
}
|
||||
values {
|
||||
// FIXME: Efl.Network.Client is needed, but that introduces a cycle
|
||||
clients: const(list<const(Efl.Network)>); [[The list of clients on this server.]]
|
||||
}
|
||||
}
|
||||
@property connection_type {
|
||||
[[Type of the server connection as defined in @Ecore.Con.Type]]
|
||||
get {
|
||||
legacy: null;
|
||||
}
|
||||
set {
|
||||
legacy: null;
|
||||
}
|
||||
values {
|
||||
conn_type: Ecore.Con.Type; [[Connection type]]
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.destructor;
|
||||
Efl.Object.finalize;
|
||||
Efl.Network.ip.get;
|
||||
Efl.Network.uptime.get;
|
||||
Efl.Network.port.set;
|
||||
Efl.Network.port.get;
|
||||
Efl.Network.fd.get;
|
||||
Efl.Network.connected.get;
|
||||
Efl.Network.timeout.set;
|
||||
Efl.Network.timeout.get;
|
||||
Efl.Network.flush;
|
||||
Efl.Network.send;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue