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:
Gustavo Sverzut Barbieri 2016-12-07 13:34:28 -02:00
parent 72ad2c5eb7
commit f4306d654d
18 changed files with 2671 additions and 6579 deletions

View File

@ -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

View File

@ -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);
/**
* @}

View File

@ -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"

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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.
*/

View File

@ -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 .*/

View File

@ -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;
}
}

View File

@ -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;
}
}