2003-09-23 01:09:32 -07:00
|
|
|
#ifndef _ECORE_CON_PRIVATE_H
|
|
|
|
#define _ECORE_CON_PRIVATE_H
|
|
|
|
|
2008-10-30 08:26:11 -07:00
|
|
|
#include "ecore_private.h"
|
2006-11-05 08:49:55 -08:00
|
|
|
#include "Ecore_Con.h"
|
2005-09-05 03:17:08 -07:00
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
#define ECORE_MAGIC_CON_SERVER 0x77665544
|
|
|
|
#define ECORE_MAGIC_CON_CLIENT 0x77556677
|
2007-09-26 09:01:04 -07:00
|
|
|
#define ECORE_MAGIC_CON_URL 0x77074255
|
2003-09-23 01:09:32 -07:00
|
|
|
|
2016-10-30 10:40:54 -07:00
|
|
|
#ifdef HAVE_SYS_UN_H
|
|
|
|
#include <sys/un.h>
|
|
|
|
#endif
|
|
|
|
|
2016-12-12 06:16:33 -08:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
# include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
|
2016-12-07 07:34:28 -08:00
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
# include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
2016-11-22 04:01:46 -08:00
|
|
|
#include <inttypes.h>
|
|
|
|
|
2004-04-03 07:03:33 -08:00
|
|
|
#define READBUFSIZ 65536
|
|
|
|
|
2010-07-26 23:30:27 -07:00
|
|
|
extern int _ecore_con_log_dom;
|
2010-01-06 16:30:05 -08:00
|
|
|
|
|
|
|
#ifdef ECORE_CON_DEFAULT_LOG_COLOR
|
|
|
|
#undef ECORE_LOG_DEFAULT_LOG_COLOR
|
|
|
|
#endif
|
|
|
|
#define ECORE_CON_DEFAULT_LOG_COLOR EINA_COLOR_BLUE
|
|
|
|
|
2009-12-21 09:32:19 -08:00
|
|
|
#ifdef ERR
|
|
|
|
# undef ERR
|
|
|
|
#endif
|
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_ecore_con_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
# undef DBG
|
|
|
|
#endif
|
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_ecore_con_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef INF
|
|
|
|
# undef INF
|
|
|
|
#endif
|
|
|
|
#define INF(...) EINA_LOG_DOM_INFO(_ecore_con_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef WRN
|
|
|
|
# undef WRN
|
|
|
|
#endif
|
|
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_ecore_con_log_dom, __VA_ARGS__)
|
|
|
|
|
2013-12-25 19:22:05 -08:00
|
|
|
#ifdef CRI
|
|
|
|
# undef CRI
|
2009-12-21 09:32:19 -08:00
|
|
|
#endif
|
2013-12-25 19:22:05 -08:00
|
|
|
#define CRI(...) EINA_LOG_DOM_CRIT(_ecore_con_log_dom, __VA_ARGS__)
|
2009-12-21 09:32:19 -08:00
|
|
|
|
2012-02-14 21:53:50 -08:00
|
|
|
typedef struct Ecore_Con_Socks Ecore_Con_Socks_v4;
|
2011-12-05 19:32:16 -08:00
|
|
|
typedef struct Ecore_Con_Socks_v5 Ecore_Con_Socks_v5;
|
2010-07-22 04:32:55 -07:00
|
|
|
|
2012-02-14 21:53:50 -08:00
|
|
|
struct Ecore_Con_Socks /* v4 */
|
2011-12-05 19:32:16 -08:00
|
|
|
{
|
|
|
|
unsigned char version;
|
|
|
|
|
|
|
|
const char *ip;
|
|
|
|
int port;
|
|
|
|
const char *username;
|
2012-02-14 21:53:50 -08:00
|
|
|
unsigned int ulen;
|
2011-12-05 19:32:16 -08:00
|
|
|
Eina_Bool lookup : 1;
|
|
|
|
Eina_Bool bind : 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Ecore_Con_Socks_v5
|
|
|
|
{
|
|
|
|
unsigned char version;
|
|
|
|
|
|
|
|
const char *ip;
|
|
|
|
int port;
|
|
|
|
const char *username;
|
2012-02-14 21:53:50 -08:00
|
|
|
unsigned int ulen;
|
2011-12-05 19:32:16 -08:00
|
|
|
Eina_Bool lookup : 1;
|
|
|
|
Eina_Bool bind : 1;
|
2012-02-14 21:53:50 -08:00
|
|
|
/* v5 only */
|
|
|
|
unsigned char method;
|
|
|
|
const char *password;
|
|
|
|
unsigned int plen;
|
2011-12-05 19:32:16 -08:00
|
|
|
};
|
|
|
|
|
2013-03-09 22:49:54 -08:00
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
extern int sd_fd_index;
|
|
|
|
extern int sd_fd_max;
|
|
|
|
#endif
|
|
|
|
|
2016-09-20 11:00:17 -07:00
|
|
|
/* init must be called from main thread */
|
|
|
|
void ecore_con_libproxy_proxies_free(char **proxies);
|
|
|
|
/* BLOCKING! should be called from a worker thread */
|
2018-06-25 12:13:22 -07:00
|
|
|
char **ecore_con_libproxy_proxies_get(const char *url, Ecore_Thread *eth);
|
2016-09-20 11:00:17 -07:00
|
|
|
|
2016-09-18 23:19:16 -07:00
|
|
|
|
2016-12-07 07:34:28 -08:00
|
|
|
Eina_Bool ecore_con_server_check(const Ecore_Con_Server *svr);
|
|
|
|
|
2011-12-05 19:32:16 -08:00
|
|
|
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);
|
2011-11-06 04:26:00 -08:00
|
|
|
|
|
|
|
void ecore_con_mempool_init(void);
|
|
|
|
void ecore_con_mempool_shutdown(void);
|
|
|
|
|
2016-12-07 07:34:28 -08:00
|
|
|
void ecore_con_legacy_init(void);
|
|
|
|
void ecore_con_legacy_shutdown(void);
|
2008-10-09 05:30:19 -07:00
|
|
|
|
2016-11-25 12:01:29 -08:00
|
|
|
void _ecore_con_local_mkpath(const char *path, mode_t mode);
|
|
|
|
|
2016-10-22 08:15:16 -07:00
|
|
|
/* allow windows and posix to use the same error comparison */
|
|
|
|
#ifndef SOCKET_ERROR
|
|
|
|
#define SOCKET_ERROR -1
|
|
|
|
#endif
|
|
|
|
#ifndef INVALID_SOCKET
|
|
|
|
#define INVALID_SOCKET -1
|
|
|
|
#endif
|
2016-11-18 06:17:08 -08:00
|
|
|
#ifndef SOCKET_TO_LOOP_FD
|
|
|
|
#define SOCKET_TO_LOOP_FD(sock) ((int)sock)
|
|
|
|
#endif
|
2016-10-22 16:49:01 -07:00
|
|
|
#ifndef _WIN32
|
|
|
|
#define closesocket(fd) close(fd)
|
|
|
|
#define SOCKET int
|
2016-11-18 06:17:08 -08:00
|
|
|
#define SOCKET_FMT "%d"
|
|
|
|
#else
|
2016-11-22 04:01:46 -08:00
|
|
|
#define SOCKET_FMT "%"PRIuPTR
|
2016-11-18 06:17:08 -08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This define will force SOCKET to be 'unsigned long', this will
|
|
|
|
* force compile to emit errors when assuming "int"/"%d", which is the
|
|
|
|
* case on UNIX but not on Windows.
|
|
|
|
*/
|
|
|
|
//#define EFL_NET_CHECK_SOCKET_TYPE 1
|
|
|
|
#if EFL_NET_CHECK_SOCKET_TYPE
|
|
|
|
#undef SOCKET
|
|
|
|
#undef SOCKET_FMT
|
|
|
|
#undef INVALID_SOCKET
|
|
|
|
#define SOCKET unsigned long
|
|
|
|
#define SOCKET_FMT "%lu"
|
|
|
|
#define INVALID_SOCKET ((SOCKET)-1)
|
2016-10-22 16:49:01 -07:00
|
|
|
#endif
|
2016-10-22 08:15:16 -07:00
|
|
|
|
2016-10-22 16:19:56 -07:00
|
|
|
/* some platforms do not have AI_V4MAPPED, then define to 0 so bitwise OR won't be changed */
|
|
|
|
#ifndef AI_V4MAPPED
|
|
|
|
#define AI_V4MAPPED 0
|
|
|
|
#endif
|
2016-11-18 06:20:57 -08:00
|
|
|
#ifndef AI_ADDRCONFIG
|
|
|
|
#define AI_ADDRCONFIG 0
|
|
|
|
#endif
|
2016-12-07 07:34:28 -08:00
|
|
|
#ifndef AI_CANONNAME
|
|
|
|
#define AI_CANONNAME 0
|
|
|
|
#endif
|
2016-10-22 16:19:56 -07:00
|
|
|
|
2016-11-18 06:27:15 -08:00
|
|
|
/* Windows do not define EAI_SYSTEM, so just define to some number
|
|
|
|
* that won't be matched, effectively disabling the subsequent
|
|
|
|
* checks/usage
|
|
|
|
*/
|
|
|
|
#ifndef EAI_SYSTEM
|
|
|
|
#define EAI_SYSTEM 254 /* number that won't match anything in EAI_* */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2016-10-24 14:47:15 -07:00
|
|
|
void _efl_net_server_udp_client_init(Eo *client, SOCKET fd, const struct sockaddr *addr, socklen_t addrlen, const char *str);
|
2016-10-22 16:49:01 -07:00
|
|
|
void _efl_net_server_udp_client_feed(Eo *client, Eina_Rw_Slice slice);
|
|
|
|
|
implement efl_net_{socket,dialer,server}_windows
This is the local socket for windows, analogous to AF_UNIX.
`Efl_Net_Socket_Windows` is the base class doing `ReadFile()` and
`WriteFile()` using overlapped I/O, as well as the close procedure
(`FlushFileBuffers()`, `DisconnectNamedPipe()` and
`CloseHandle()`). These are done on top of an existing HANDLE that is
set by `Efl_Net_Dialer_Windows` (from `CreateFile()`) or
`Efl_Net_Server_Windows` (from `CreateNamedPipe()`).
The overlapped I/O will return immediately, either with operation
completed or `ERROR_IO_PENDING`, which means the kernel will execute
that asynchronously and will later `SetEvent(overlapped.hEvent)` which
is an event we wait on our main loop. That `overlapped` handle must
exist during the call lifetime, thus cannot be bound to `pd`, as we
may call `CancelIo()` but there is no guarantee the memory won't be
touched, in that case we keep the overlapped around, but without an
associated object.
Windows provides no notification "can read without blocking" or
non-blocking calls that returns partial data. The way to go is to use
these overlapped I/O, with an initial `ReadFile()` to an internal
buffer, once that operation finishes, we callback the user to says
there is something to read (`efl_io_reader_can_read_set()`) and wait
until `efl_io_reader_read()` is called to consume the available data,
then `ReadFile()` is called again to read more data to the same
internal buffer.
Likewise, there is no "can write without blocking" or non-blocking
calls that sends only partial data. The way to go is to get user bytes
in `efl_io_writer_write()` and copy them in an internal buffer, then
call `WriteFile()` on that and inform the user nothing else can be
written until that operation completes
(`efl_io_writer_can_write_set()`).
This is cumbersome since we say we "sent" stuff when we actually
didn't, it's still in our internal buffer (`pd->send.bytes`), but
nonetheless the kernel and the other peer may be adding even more
buffers, in this case we need to do a best effort to get it
delivery. A particular case is troublesome: `write() -> close()`, this
may result in `WriteFile()` pending, in this case we wait using
`GetOverlappedResult()`, *this is nasty and may block*, but it's the
only way I see to cope with such common use case.
Other operations, like ongoing `ReadFile()` or `ConnectNamedPipe()`
will be canceled using `CancelIo()`.
Q: Why no I/O Completion Port (IOCP) was used? Why no
CreateThreadpoolIo()? These perform much better!
A: These will call back from secondary threads, but in EFL we must
report back to the user in order to process incoming data or get
more data to send. That is, we serialize everything to the main
thread, making it impossible to use the benefits of IOCP and
similar such as CreateThreadpoolIo(). Since we'd need to wakeup the
main thread anyways, using `OVERLAPPED.hEvent` with
`ecore_main_win32_handler_add()` does the job as we expect.
Thanks to Vincent Torri (vtorri) for his help getting this code done
with an example on how to do the NamedPipe handling on Windows.
2017-03-22 00:29:16 -07:00
|
|
|
#ifdef EFL_NET_SOCKET_WINDOWS_CLASS
|
|
|
|
#define PIPE_NS "\\\\.\\pipe\\"
|
|
|
|
char *_efl_net_windows_error_msg_get(DWORD win32err);
|
|
|
|
Eina_Error _efl_net_socket_windows_init(Eo *o, HANDLE h);
|
|
|
|
Eina_Error _efl_net_socket_windows_io_start(Eo *o);
|
|
|
|
HANDLE _efl_net_socket_windows_handle_get(const Eo *o);
|
|
|
|
|
|
|
|
typedef struct _Efl_Net_Socket_Windows_Operation Efl_Net_Socket_Windows_Operation;
|
|
|
|
typedef Eina_Error (*Efl_Net_Socket_Windows_Operation_Success_Cb)(void *data, Eo *sock, DWORD used_size);
|
|
|
|
typedef Eina_Error (*Efl_Net_Socket_Windows_Operation_Failure_Cb)(void *data, Eo *sock, DWORD win32err);
|
|
|
|
|
|
|
|
Efl_Net_Socket_Windows_Operation *_efl_net_socket_windows_operation_new(Eo *sock, Efl_Net_Socket_Windows_Operation_Success_Cb success_cb, Efl_Net_Socket_Windows_Operation_Failure_Cb failure_cb, const void *data);
|
|
|
|
Eina_Error _efl_net_socket_windows_operation_failed(Efl_Net_Socket_Windows_Operation *op, DWORD win32err);
|
|
|
|
Eina_Error _efl_net_socket_windows_operation_succeeded(Efl_Net_Socket_Windows_Operation *op, DWORD used_size);
|
|
|
|
|
|
|
|
static inline OVERLAPPED *
|
|
|
|
_efl_net_socket_windows_operation_overlapped_get(Efl_Net_Socket_Windows_Operation *op)
|
|
|
|
{
|
|
|
|
return (OVERLAPPED *)op;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef EFL_NET_SOCKET_UNIX_CLASS
|
2016-10-26 13:57:37 -07:00
|
|
|
Eina_Bool efl_net_unix_fmt(char *buf, size_t buflen, SOCKET fd, const struct sockaddr_un *addr, socklen_t addrlen);
|
2016-10-27 04:01:19 -07:00
|
|
|
#endif
|
2016-12-09 05:42:17 -08:00
|
|
|
Eina_Bool efl_net_ip_port_parse(const char *address, struct sockaddr_storage *storage);
|
|
|
|
Eina_Bool efl_net_ip_port_parse_split(const char *host, const char *port, struct sockaddr_storage *storage);
|
2016-10-26 13:57:37 -07:00
|
|
|
Eina_Bool efl_net_ip_port_fmt(char *buf, size_t buflen, const struct sockaddr *addr);
|
2016-10-22 16:49:01 -07:00
|
|
|
|
2016-11-01 11:01:57 -07:00
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
/**
|
|
|
|
* Checks if the next FD in the sd_fd_index:sd_fd_max is of the
|
|
|
|
* expected family, protocol and if it's listening.
|
|
|
|
*
|
|
|
|
* This is similar to sd_is_socket()/sd_is_socket_inet(), but will
|
|
|
|
* also parse address in our standard format "IP:PORT", including IPv6
|
|
|
|
* within braces, and then will validate the address with
|
|
|
|
* getsockaddr() for INET.
|
|
|
|
*
|
|
|
|
* @param address the address to validate
|
|
|
|
* @param family AF_UNIX or AF_UNSPEC for INET, in that case AF_INET
|
|
|
|
* or AF_INET6 will be inferred from @a address.
|
|
|
|
* @param type SOCK_STREAM or SOCK_DGRAM
|
|
|
|
* @param[out] listening where to return listening state, should be
|
|
|
|
* NULL for @a type SOCK_DGRAM
|
|
|
|
*
|
|
|
|
* @return 0 on success, error otherwise.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_ip_socket_activate_check(const char *address, int family, int type, Eina_Bool *listening);
|
|
|
|
#endif
|
|
|
|
|
2016-09-09 16:09:51 -07:00
|
|
|
/**
|
|
|
|
* @brief splits an address in the format "host:port" in two
|
|
|
|
* null-terminated strings.
|
|
|
|
*
|
|
|
|
* The address may be 'server.com:1234', 'server.com:http',
|
|
|
|
* 'server.com' (@c *p_port will be NULL), IPv4 127.0.0.1:456 or
|
|
|
|
* IPv6 [::1]:456
|
|
|
|
*
|
|
|
|
* @param[inout] buf contains the string to be split and will be modified.
|
|
|
|
* @param[out] p_host returns a pointer inside @a buf with
|
|
|
|
* null-terminated host part.
|
|
|
|
* @param[out] p_port returns a pointer with null-terminated port
|
|
|
|
* part. The pointer may be inside @a buf if port was
|
|
|
|
* specified or #NULL if it wasn't specified.
|
|
|
|
*
|
|
|
|
* @return #EINA_TRUE on success, #EINA_FALSE on errors.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Bool efl_net_ip_port_split(char *buf, const char **p_host, const char **p_port);
|
|
|
|
|
2016-10-22 16:49:01 -07:00
|
|
|
SOCKET efl_net_socket4(int domain, int type, int protocol, Eina_Bool close_on_exec);
|
2016-08-24 08:34:59 -07:00
|
|
|
|
2016-10-20 19:15:09 -07:00
|
|
|
/**
|
|
|
|
* @brief callback to notify of resolved address.
|
|
|
|
*
|
|
|
|
* The callback is given the ownership of the result, thus must free
|
|
|
|
* it with freeaddrinfo().
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
typedef void (*Efl_Net_Ip_Resolve_Async_Cb)(void *data, const char *host, const char *port, const struct addrinfo *hints, struct addrinfo *result, int gai_error);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief asynchronously resolve a host and port using getaddrinfo().
|
|
|
|
*
|
|
|
|
* This will call getaddrinfo() in a thread, taking care to return the
|
|
|
|
* result to the main loop and calling @a cb with given user @a data.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Ecore_Thread *efl_net_ip_resolve_async_new(const char *host, const char *port, const struct addrinfo *hints, Efl_Net_Ip_Resolve_Async_Cb cb, const void *data);
|
|
|
|
|
2016-09-09 16:09:51 -07:00
|
|
|
/**
|
|
|
|
* @brief callback to notify of connection.
|
|
|
|
*
|
|
|
|
* The callback is given the ownership of the socket (sockfd), thus
|
|
|
|
* must close().
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
2016-11-18 06:17:08 -08:00
|
|
|
typedef void (*Efl_Net_Connect_Async_Cb)(void *data, const struct sockaddr *addr, socklen_t addrlen, SOCKET sockfd, Eina_Error error);
|
2016-09-09 16:09:51 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief asynchronously create a socket and connect to the address.
|
|
|
|
*
|
|
|
|
* This will call socket() and connect() in a thread, taking care to
|
|
|
|
* return the result to the main loop and calling @a cb with given
|
|
|
|
* user @a data.
|
|
|
|
*
|
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
|
|
|
* For name resolution and proxy support use
|
|
|
|
* efl_net_ip_connect_async_new()
|
|
|
|
*
|
2016-09-09 16:09:51 -07:00
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Ecore_Thread *efl_net_connect_async_new(const struct sockaddr *addr, socklen_t addrlen, int type, int protocol, Eina_Bool close_on_exec, Efl_Net_Connect_Async_Cb cb, const void *data);
|
|
|
|
|
efl_net_dialer_tcp: add SOCKS proxy support.
SOCKS is implemented in its own thread using synchronous/blocking
primitives, which simplifies the code a lot -- as well as simulate the
usage of Ecore_Thread as our users will likely do.
Since SOCKSv4a and SOCKSv5 allow name resolution, the whole
getaddrinfo() is done in the same thread, when needed, instead of a
separate thread to do that, which should also save some resources.
Instead of the legacy ECORE_CON_SOCKS_V4 and ECORE_CON_SOCKS_V5, now
we use socks_proxy, all_proxy and no_proxy. This matches our other
dialers http/websocket (which will use http_proxy, all_proxy and
no_proxy). If desired it's easy to add back support for those
variables, but I think we should just deprecate them. (The legacy code
will keep unchanged, thus direct users of ecore_con_server will still
use those -- just the previous users of ecore_con_server will be
converted to use the new API).
2016-09-18 20:56:18 -07:00
|
|
|
/**
|
|
|
|
* @brief asynchronously create a socket and connect to the IP address.
|
|
|
|
*
|
|
|
|
* This wil resolve the address using getaddrinfo(), create a socket
|
|
|
|
* and connect in a thread.
|
|
|
|
*
|
|
|
|
* If a @a proxy is given, then it's always used. Otherwise the
|
|
|
|
* environment variable @a proxy_env is used unless it matches @a
|
|
|
|
* no_proxy_env. Some systems may do special queries for proxy from
|
|
|
|
* the thread.
|
|
|
|
*
|
|
|
|
* @param address the host:port to connect. Host may be a name or an
|
|
|
|
* IP address, IPv6 addresses should be enclosed in braces.
|
|
|
|
* @param proxy a mandatory proxy to use. If "" (empty string), it's
|
|
|
|
* disabled. If NULL, then @a proxy_env is used unless it
|
|
|
|
* matches @a no_proxy_env.
|
|
|
|
* @param proxy_env if @a proxy is NULL, then this will be used as the
|
|
|
|
* proxy unless it matches @a no_proxy_env.
|
|
|
|
* @param no_proxy_env a comma-separated list of matches that will
|
|
|
|
* avoid using @a proxy_env. "server.com" will inhibit proxy
|
|
|
|
* for "server.com", "host.server.com" but not "xserver.com".
|
|
|
|
* @param type the socket type, such as SOCK_STREAM or SOCK_DGRAM.
|
|
|
|
* @param protocol the socket protocol, such as IPPROTO_TCP.
|
|
|
|
* @param close_on_exec if EINA_TRUE, will set SOCK_CLOEXEC.
|
|
|
|
* @param cb the callback to report connection
|
|
|
|
* @param data data to give to callback
|
|
|
|
*
|
|
|
|
* @return an Ecore_Thread that will execute the connection.
|
|
|
|
*
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Ecore_Thread *efl_net_ip_connect_async_new(const char *address, const char *proxy, const char *proxy_env, const char *no_proxy_env, int type, int protocol, Eina_Bool close_on_exec, Efl_Net_Connect_Async_Cb cb, const void *data);
|
|
|
|
|
2016-09-08 12:12:18 -07:00
|
|
|
static inline Eina_Error
|
|
|
|
efl_net_socket_error_get(void)
|
|
|
|
{
|
|
|
|
#ifndef _WIN32
|
|
|
|
return errno;
|
|
|
|
#else
|
|
|
|
Eina_Error err = WSAGetLastError();
|
|
|
|
|
|
|
|
if (0) { }
|
|
|
|
|
|
|
|
/* used by send() */
|
|
|
|
#if defined(WSAEACCES) && (WSAEACCES != EACCES)
|
|
|
|
else if (err == WSAEACCES) err = EACCES;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEWOULDBLOCK) && (WSAEWOULDBLOCK != EAGAIN)
|
|
|
|
else if (err == WSAEWOULDBLOCK) err = EAGAIN;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEBADF) && (WSAEBADF != EBADF)
|
|
|
|
else if (err == WSAEBADF) err = EBADF;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAECONNRESET) && (WSAECONNRESET != ECONNRESET)
|
|
|
|
else if (err == WSAECONNRESET) err = ECONNRESET;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEDESTADDRREQ) && (WSAEDESTADDRREQ != EDESTADDRREQ)
|
|
|
|
else if (err == WSAEDESTADDRREQ) err = EDESTADDRREQ;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEFAULT) && (WSAEFAULT != EFAULT)
|
|
|
|
else if (err == WSAEFAULT) err = EFAULT;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEINTR) && (WSAEINTR != EINTR)
|
|
|
|
else if (err == WSAEINTR) err = EINTR;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEINVAL) && (WSAEINVAL != EINVAL)
|
|
|
|
else if (err == WSAEINVAL) err = EINVAL;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEISCONN) && (WSAEISCONN != EISCONN)
|
|
|
|
else if (err == WSAEISCONN) err = EISCONN;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEMSGSIZE) && (WSAEMSGSIZE != EMSGSIZE)
|
|
|
|
else if (err == WSAEMSGSIZE) err = EMSGSIZE;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAENOBUFS) && (WSAENOBUFS != ENOBUFS)
|
|
|
|
else if (err == WSAENOBUFS) err = ENOBUFS;
|
|
|
|
#endif
|
|
|
|
#if defined(WSA_NOT_ENOUGH_MEMORY) && (WSA_NOT_ENOUGH_MEMORY != ENOMEM)
|
|
|
|
else if (err == WSA_NOT_ENOUGH_MEMORY) err = ENOMEM;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAENOTCONN) && (WSAENOTCONN != ENOTCONN)
|
|
|
|
else if (err == WSAENOTCONN) err = ENOTCONN;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAENOTSOCK) && (WSAENOTSOCK != ENOTSOCK)
|
|
|
|
else if (err == WSAENOTSOCK) err = ENOTSOCK;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAEOPNOTSUPP) && (WSAEOPNOTSUPP != EOPNOTSUPP)
|
|
|
|
else if (err == WSAEOPNOTSUPP) err = EOPNOTSUPP;
|
|
|
|
#endif
|
|
|
|
#if defined(WSAESHUTDOWN) && (WSAESHUTDOWN != EPIPE)
|
|
|
|
else if (err == WSAESHUTDOWN) err = EPIPE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* extras used by recv() */
|
|
|
|
#if defined(WSAECONNREFUSED) && (WSAECONNREFUSED != ECONNREFUSED)
|
|
|
|
else if (err == WSAECONNREFUSED) err = ECONNREFUSED;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* extras used by getsockopt() */
|
|
|
|
#if defined(WSAENOPROTOOPT) && (WSAENOPROTOOPT != ENOPROTOOPT)
|
|
|
|
else if (err == WSAENOPROTOOPT) err = ENOPROTOOPT;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return err;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-10-25 05:03:34 -07:00
|
|
|
/**
|
|
|
|
* Join a multicast group specified by address.
|
|
|
|
*
|
|
|
|
* Address must be an IPv4 or IPv6 depending on @a fd and will be
|
|
|
|
* parsed using inet_pton() with corresponding @a family. The address
|
|
|
|
* may contain an '@@' delimiter to specify the local interface IP
|
|
|
|
* address to use. No interface means '0.0.0.0'.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param address the address in the format IP[@@IFACE]
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_join(SOCKET fd, int family, const char *address);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Leave a multicast group specified by address.
|
|
|
|
*
|
|
|
|
* This reverses the effect of efl_net_multicast_join().
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param address the address in the format IP[@@IFACE]
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_leave(SOCKET fd, int family, const char *address);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the Time-To-Live of multicast packets. <= 1 disables going
|
|
|
|
* outside of local network.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param ttl the time-to-live in units.
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_ttl_set(SOCKET fd, int family, uint8_t ttl);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the current time-to-live of multicast packets.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param[out] ttl returns the time-to-live in units.
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_ttl_get(SOCKET fd, int family, uint8_t *ttl);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets if the current local address should get a copy of the packets sent.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param loopback if #EINA_TRUE, enables receive of local copy. #EINA_FALSE means only remote peers will do.
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_loopback_set(SOCKET fd, int family, Eina_Bool loopback);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets if the current local address should get a copy of the packets sent.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @param family the socket family of fd, AF_INET or AF_INET6.
|
|
|
|
* @param[out] loopback returns if #EINA_TRUE, enables receive of local copy. #EINA_FALSE means only remote peers will do.
|
|
|
|
*
|
|
|
|
* @return 0 on success, errno mapping otherwise.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
Eina_Error efl_net_multicast_loopback_get(SOCKET fd, int family, Eina_Bool *loopback);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query the size of the next UDP datagram pending on queue.
|
|
|
|
*
|
|
|
|
* @param fd socket to operate on.
|
|
|
|
* @return the size in bytes.
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
size_t efl_net_udp_datagram_size_query(SOCKET fd);
|
|
|
|
|
2016-10-28 17:48:19 -07:00
|
|
|
|
|
|
|
/* SSL abstraction API */
|
|
|
|
extern void *efl_net_ssl_context_connection_new(Efl_Net_Ssl_Context *context);
|
|
|
|
|
2016-11-28 13:06:30 -08:00
|
|
|
#define EFL_NET_DIALER_HTTP_BUFFER_RECEIVE_SIZE (1U << 14) /* 16Kb to receive */
|
|
|
|
|
2003-09-23 01:09:32 -07:00
|
|
|
#endif
|