Commit Graph

49 Commits

Author SHA1 Message Date
Mike Blumenkrantz 0e40fad446 ecore_con: make dns resolver thread stop blocking when canceled
Summary:
if the user or system attempts to cancel this thread then it should
stop blocking and exit in order to avoid potentially exiting after
efl has expected ecore-con to stop being active

@fix
fix T7041
Depends on D6354

Reviewers: ManMower, devilhorns

Reviewed By: ManMower

Subscribers: cedric, #committers

Tags: #efl

Maniphest Tasks: T7041

Differential Revision: https://phab.enlightenment.org/D6355
2018-06-25 15:14:31 -04:00
Gustavo Sverzut Barbieri fa0e2865a1 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-29 12:44:19 -03:00
Carsten Haitzler bd2f189d4c ecore_con - move libproxy to a slave binary with stdin/out msging
so here's the ugly problem. libproxy. yes. we've discussed memory
usage (e.g. it may have to execute javascript and pull in lots of deps
etc.) but we dlopene'd on the fly. ok... but this didn't solve another
issue i hit:

libproxy was causing enlightenment to abort(). some internal bit of
libproxy was raising a c++ exception. this wasn't caught. this causes
an abort(). takes down your entire desktop. FANTASTIC. this is bad. i
wouldnt' expect a library we depend on to be THIS anti-social but
libproxy seemingly is. it SHOULd catch its error sand just propagate
back to us so we can handle gracefully.

there reall is no way around this - isolate libproxy. it's even worse
that libproxy can load arbitrary modules that come from anywhere sho
who knows what issues this can cause. isolation is the best solution i
can think of.

so this makes an elf+net_proxy_helper we spawn the first time we need
a proxy lookup. we re-use that binary again and again until it exits
(it should exit after 10 seconds of being idle with no requests coming
in/pending). it'll respawn again later if needed. this involves now
the efl net threads having to marshall back to mainloop to do the
spawn and to write to the proxy process (reading is done by async exe
data events and the data is passed down a thread queue to the waitng
efl net thread). if the exe dies with pending requests unanswered then
it's respawned again and the req's are re-sent to it... just in case.
it has a limit on how often it'll respawn quickly.

this seems to work in my limited testing. this ALSO now isolates
memory usage of libproxy to another slave process AND this process
will die taking its memory with it once it's been idle for long
enough. that;s also another good solution to keeping libproxy impact
at bay.
2017-01-09 15:29:33 +09:00
Gustavo Sverzut Barbieri a995529a46 efl_net_socket_udp: expose init() as protected method.
remove one more TODO: since Efl.Net.Ip.Address was introduced we can
now expose Efl.Net.Socket.Udp.init as a protected method that will
configure the internal address we use for the remote peer. This allow
subclasses to override or call such methods.
2016-12-19 17:11:46 -02:00
Gustavo Sverzut Barbieri 4812d9eb74 add missing includes for BSD.
Thanks @netstar.
2016-12-12 12:17:11 -02:00
Gustavo Sverzut Barbieri f4306d654d 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).
2016-12-10 08:44:06 -02:00
Gustavo Sverzut Barbieri afdbe897a0 efl_net: optimize serving of IP addresses.
If we can parse the IP using inet_pton() and the port, there is no
reason to call getaddrinfo() in a thread.

This is required since ecore_con_suite (for ecore_con-over-efl_net) will
assume the server is running as soon as it's created.
2016-12-09 13:47:04 -02:00
Gustavo Sverzut Barbieri b4ed72518d efl_net_dialer_http: export read size.
In the legacy wrapper I'll need that.
2016-11-29 16:02:25 -02:00
Gustavo Sverzut Barbieri 48049a4ce2 efl_net_server_unix: add leading_directories_create property.
This allows us to crete any parent directories that are missing.
2016-11-25 18:01:29 -02:00
Gustavo Sverzut Barbieri 6062109707 efl_net: proper format for SOCKET.
SOCKET is defined as uintptr_t (uint_ptr as called on Windows) and
thus will vary its size based on 32 or 64 bits.

Then we should format with PRIuPTR from inttypes.h, which is supported
since VisualStudio 2013
https://blogs.msdn.microsoft.com/vcblog/2013/07/19/c99-library-support-in-visual-studio-2013/
2016-11-22 11:03:57 -02:00
Gustavo Sverzut Barbieri 3f2881a458 efl_net: SOCKET_FMT is "long" on windows.
at least it seems so, let's see if warnings are gone.
2016-11-18 15:16:32 -02:00
Gustavo Sverzut Barbieri b322a3ae53 efl_net: define EAI_SYSTEM when it's not defined (ie: Windows).
its value is unimportant, just do not match any other EAI error value.

Partially fixes D4357.
2016-11-18 12:53:32 -02:00
Gustavo Sverzut Barbieri 090940c3ae efl_net: windows do not define AI_ADDRCONFIG.
do as for other missing bitwise flags and simply define to 0, reducing
need to ifdefs in the code.

This partially addresses D4357.
2016-11-18 12:53:32 -02:00
Gustavo Sverzut Barbieri 5818dc71da efl_net: use SOCKET_FMT to format SOCKET so it works on UNIX and Windows.
On Windows SOCKET is unsigned, thus will cause sign errors when
formatting with "%d" or comparing with signed values.

On UNIX it was quiet and easy to miss, thus a new #define can be used
to check for those. It will use 'unsigned long' as SOCKET, thus will
complain out loud and not even work correctly when using pointers on
64bits UNIX on mistakes -- which should improve the situation.

This helped to fix lots of missing conversions, all fixed.

This partially addresses D4357.
2016-11-18 12:53:32 -02:00
Gustavo Sverzut Barbieri c2630c829f efl_net_server support systemd socket activation.
It includes extensive verifications to avoid mistakes and usage of
incorrect sockets.
2016-11-01 16:37:04 -02:00
Gustavo Sverzut Barbieri f4198f022a efl_net_socket_ssl: initial SSL wrapper.
This is the first step towards SSL connections on top of sockets, with
an example on how to upgrade a dialer and a server client using TCP.
2016-10-31 19:39:33 -02:00
Jean Guyomarc'h d27b1df4e8 ecore_con: fix structure declaration
Clang raised a massive amount of warnings due to the struct sockaddr_un
not being declared before using it. So, include the header that declares
this structure first.
2016-10-30 18:40:54 +01:00
Gustavo Sverzut Barbieri 48fb9e72df UNIX socket doesn't exist on Windows.
thanks to vtorri & Kuri to spot that one.
2016-10-27 09:01:56 -02:00
Gustavo Sverzut Barbieri 651ff13616 addded efl_net_{socket,dialer,server}_unix
This introduces AF_UNIX server and dialer, these are not available on
Windows as in that platform we'll create a custom class for native
'local' communication.

In the future we can add a wrapper class Efl.Net.Local that will use
the class for each platform, but won't expose its details.

For instance, if we ever expose 'credentials' (which I didn't because
they are not portable), then it doesn't make sense to try to match
that on Windows. The 'Efl.Net.Local' would just stick to the basics:
Reader, Writer and Closer APIs.
2016-10-26 19:01:03 -02:00
Gustavo Sverzut Barbieri cd53f9bad2 efl_net_*_udp: make UDP usable, including multicast.
This was a huge work, but now UDP is usable as seen in the examples.

Instead of relying on 'connect()', just do 'sendto()' and 'recvfrom()'
as they are universal. Multicast address can only be connected in
IPv4, IPv6 wasn't working and I'm not sure the IPv4 is portable to
other platforms.

Dialer will auto-join multicast groups is the dialed address is
one. Multicast properties such as time to live (hops) and loopback can
be configured. When joining multicast groups, the local
address/interface can be configured by 'IP@IFACE' format, with
'@IFACE' being optional.

Dialers will now auto-bind, so it can receive data as dialers are
expected to be bi-directional. One can manually specify the binding
address if there is such need.

Since datagrams must be read in their full size, otherwise the
remaining bits are dropped, expose next_datagram_size_query() in both
Efl.Net.Socket.Udp and Efl.Net.Server.Udp.Client.

To finalize UDP for real we need to introduce an 'Efl_Net_Ip_Address'
structure to serve as both IPv4 and IPv6 and expose 'sendto()' and
'recvfrom()'. These will come later as this commit is already too big.
2016-10-25 10:11:48 -02:00
Gustavo Sverzut Barbieri 6d1a54ed8e efl_net_server_udp_client: add missing part of name. 2016-10-25 10:11:48 -02:00
Gustavo Sverzut Barbieri cddbce8900 efl_net_*: improve WIN32.
Thanks to vtorri for poiting out about close() is not the correct
socket function, we should use closesocket() instead.

Also defined SOCKET to int on Linux so we can use the same 'type' and
avoid lots of ifdef in our code. On Windows it's unsigned, thus would
cause some warnings about incorrect signed comparison.
2016-10-22 21:49:01 -02:00
Gustavo Sverzut Barbieri a06c9f96aa AI_V4MAPPED may not be defined in some platforms.
define to 0 in such cases, so the flag won't be affected.

Fixes T4754
2016-10-22 21:20:56 -02:00
Gustavo Sverzut Barbieri e6a78bd02a efl_net: play better with WIN32.
Defined INVALID_SOCKET=-1 and SOCKET_ERROR=-1 on non-Windows platforms
so we can keep the same construct 'function() == error' and it should
work on POSIX and windows.

I cannot test these on Windows, but the situation should be improved
with this commit.
2016-10-22 13:15:16 -02:00
Gustavo Sverzut Barbieri 7493368e54 efl_net_server_udp: initial UDP server.
This is the initial UDP server that works similarly to the TCP one,
however under the hood it's widely different since the socket is
reused for all "clients", thus needs a new Efl.Net.Server.Udp.Client
(Efl.Net.Socket) as Efl.Net.Socket.Udp exposes the fd and options such
as 'cork', which would interfere in other clients.

The main socket will read the packets and find an existing client to
feed it. If no client exists, then it will create one if not overr
limit. Since there is no kernel-queuing as done by listen()/accept(),
the 'no reject' case will just accept the client anyway.

Next commits will improve UDP server handling with some advanced
features:

 - join multicast groups
 - bind to a specific interface (SO_BINDTODEVICE)
 - block packets going out of local network (SO_DONTROUTE)
 - specify priorities (SO_PRIORITY)
2016-10-21 13:33:27 -02:00
Gustavo Sverzut Barbieri 094c9091b4 efl_net_server_tcp: use async getaddrinfo() to resolve server name.
this allows nicer usage such as 'localhost:http' as the address, which
will resolve to [::1]:80 (if IPv6 is enabled) or 127.0.0.1:80 if only
IPv4 exists.
2016-10-21 00:16:37 -02:00
Gustavo Sverzut Barbieri f0f9c5d24a libproxy: dlopen() and make it runtime optional. 2016-09-20 15:00:48 -03:00
Gustavo Sverzut Barbieri 0d478c301f efl_net_dialer_tcp: use libproxy settings.
libproxy allows various means to configure a proxy, will load from
gnome and kde configuration settings, envvars, macos and even windows
registry.

curl still doesn't use it, but we can make that later.
2016-09-19 10:01:51 -03:00
Gustavo Sverzut Barbieri a975bfe1e6 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-19 01:18:14 -03:00
Gustavo Sverzut Barbieri cb8695e9d6 efl_net_dialer_tcp: make asynchronous resolve and connect.
both resolve (getaddrinfo()) and connect() are now done in
Ecore_Thread, avoid to block the main loop.

My plan is to always use the threaded connect() using a blocking
socket, only set it to non-blocking after the socket is returned to
the main thread and before it's accessible to the user. It will make
the connect behavior more uniform.

Some errors were moved from HTTP to Dialer as they are more generic.
2016-09-09 20:14:01 -03:00
Gustavo Sverzut Barbieri 4814f937e2 efl_net_socket_fd: make it more win32 friendly.
it seems that on windows read() and write() won't work with sockets,
so use recv() and send().

Note that this code is still untested on windows, at least the errors
must be fetched using WSAGetLastError() instead of errno directly, but
I don't have a Windows machine I can test.
2016-09-08 17:01:13 -03:00
Gustavo Sverzut Barbieri e3ee477140 efl_net: better handling for SOCK_CLOEXEC.
On systems where SOCK_CLOEXEC is supported, give it to socket() and if
accept4() is supported, then use it as well.

Otherwise revert to fcntl().
2016-08-24 12:34:59 -03:00
Gustavo Sverzut Barbieri e7df1a7483 efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.

Efl.Net.Dialer defines to to reach a server.

Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.

The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.

The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.

TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.

The examples are documented and should cover the basic principles:

 - efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
   "netcat", can send data from socket, file or stdin to a socket,
   file, stdout or stderr.

 - efl_net_server_example listens for connections and can either reply
   "Hello World!" and take some data or work as an echo-server,
   looping back all received data to the user.

More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-22 18:25:14 -03:00
Srivardhan Hebbar b1e1186b8e ecore_con: change Ecore.Con.Client to Efl.Network.Client.
Summary: Signed-off-by: Srivardhan Hebbar <sri.hebbar@samsung.com>

Reviewers: cedric

Subscribers: jpeg

Differential Revision: https://phab.enlightenment.org/D3663

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
2016-02-12 21:25:55 +01:00
Srivardhan Hebbar fca9ff1322 ecore_con: changing Ecore.Con.Server to Efl.Network.Server.
Summary: Signed-off-by: Srivardhan Hebbar <sri.hebbar@samsung.com>

Reviewers: cedric

Subscribers: jpeg

Differential Revision: https://phab.enlightenment.org/D3549

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
2016-02-05 08:10:52 +01:00
Cedric BAIL ae5e2c8284 emile/ecore_con: drop SSLv3 support due to security issue.
SSLv3 has been compromised a year ago by what is known as POODLE
(https://en.wikipedia.org/wiki/POODLE). Every major browser have now
dropped support for SSLv3 and distribution are starting to do so also.
It is a good timing for us to do so, especially as it breaks build on
some distribution.
2015-11-02 14:22:42 -08:00
Vincent Torri ebaa04c318 ecore_con: add missing declarations on Windows.
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
2015-05-14 18:41:48 +02:00
Guillaume Friloux f26977a175 ecore_con: use SOCKET and not int for socket descriptors on win32 2015-02-11 17:03:37 +01:00
Tom Hacohen a58c1b6c97 Ecore con url: Migrate to eo. 2014-09-01 11:12:17 +01:00
Mike Blumenkrantz 7b0db79c2d revert all recent ecore-con related eo changes. completely broken.
please test things before committing.

reverts all changes since and including f6156c9a62
2014-08-30 08:12:54 -04:00
Tom Hacohen f6156c9a62 Ecore con url: Migrate to eo. 2014-08-28 11:52:38 +01:00
Tom Hacohen d72f809fb8 Ecore con server: Migrate to eo. 2014-08-22 17:37:56 +01:00
Tom Hacohen d9b5f192d4 Ecore con client: Migrate to eo. 2014-08-22 17:11:54 +01:00
Carsten Haitzler 16d7b981eb ecore-con - deal with internal buffer growing over 2g in size
@fix this fixes a corner case where you may buffer 2g or more of data
in ecore-con buffers. this leads to a stall. @fix
2014-04-04 19:36:50 +09:00
Daniel Juyung Seo 76d8532b54 efl: Unified eina critical manro to CRI.
Being annoyed by different types of eina critical macros - CRI, CRIT,
 CRITICAL -, I concluded to unify them to one. Discussed on IRC and
 finally, CRI was chosen to meet the consistency with other macros -
 ERR, WRN, INF, DBG - in terms of the number of characters.
If there is any missing bits, please let me know.
2013-12-26 12:27:13 +09:00
Carsten Haitzler 2c1c6b9335 ecore-con: make curl support entirely runtime loaded via eina_module
this makes curl support a pure runtime-only thing. libcurl is loaded by
eina_module (dlopen/dlsym) when curl is actually first needed (when a
url connection/object is created). this means that ecore-con has no
link or compile dependencies on curl, only runtime, AND this saves
memory (due to curl inits using apparently a chunk of private pages).
so this saves memory and moves the dependency to runtime (though still
consider libcurl a dependency of efl - but like a binary executed,
it's at runtime).
2013-10-10 22:31:18 +09:00
Cedric Bail 9176271492 ecore_con: add systemd socket activation.
Be careful, systemd socket activation require you to always order
server socket creation in the same order as defined in the unit file.
This means ecore_con_server_add should always been in the same order
for those of them using systemd socket activation.
2013-03-10 16:00:32 +09:00
Gustavo Sverzut Barbieri 48120ec0c8 efl: both eet and ecore_con now share --with-crypto and defines.
* rename USE_GNUTLS and USE_OPENSSL to HAVE_GNUTLS and HAVE_OPENSSL
   in ecore_con, to match other modules such as Eet.

 * define requirements_pc_crypto, requirements_pc_deps_crypto and
   requirements_libs_crypto so modules can use that.

 * move to a common check section.



SVN revision: 80288
2012-12-06 00:11:14 +00:00
Vincent Torri 7d6010b12c merge: add escape ecore, fix several bugs
SVN revision: 79995
2012-12-02 22:35:45 +00:00