efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
#define EFL_NET_SERVER_FD_PROTECTED 1
|
|
|
|
#define EFL_NET_SERVER_PROTECTED 1
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "Ecore.h"
|
|
|
|
#include "Ecore_Con.h"
|
|
|
|
#include "ecore_con_private.h"
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
|
|
# include <sys/socket.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define MY_CLASS EFL_NET_SERVER_FD_CLASS
|
|
|
|
|
|
|
|
typedef struct _Efl_Net_Server_Fd_Data
|
|
|
|
{
|
|
|
|
Eina_Stringshare *address;
|
|
|
|
int family;
|
|
|
|
unsigned int clients_count;
|
|
|
|
unsigned int clients_limit;
|
|
|
|
Eina_Bool clients_reject_excess;
|
|
|
|
Eina_Bool serving;
|
|
|
|
Eina_Bool close_on_exec;
|
|
|
|
Eina_Bool reuse_address;
|
|
|
|
Eina_Bool reuse_port;
|
|
|
|
} Efl_Net_Server_Fd_Data;
|
|
|
|
|
2016-10-22 16:49:01 -07:00
|
|
|
static SOCKET
|
|
|
|
efl_net_accept4(SOCKET fd, struct sockaddr *addr, socklen_t *addrlen, Eina_Bool close_on_exec)
|
2016-08-24 08:34:59 -07:00
|
|
|
{
|
|
|
|
#ifdef HAVE_ACCEPT4
|
|
|
|
int flags = 0;
|
|
|
|
if (close_on_exec) flags |= SOCK_CLOEXEC;
|
|
|
|
return accept4(fd, addr, addrlen, flags);
|
|
|
|
#else
|
2016-10-22 16:49:01 -07:00
|
|
|
SOCKET client = accept(fd, addr, addrlen);
|
2016-10-22 17:41:01 -07:00
|
|
|
if (client == INVALID_SOCKET) return client;
|
2016-08-24 08:34:59 -07:00
|
|
|
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef FD_CLOEXEC
|
2016-08-24 08:34:59 -07:00
|
|
|
if (close_on_exec)
|
|
|
|
{
|
|
|
|
if (fcntl(client, F_SETFD, FD_CLOEXEC) < 0)
|
|
|
|
{
|
|
|
|
int errno_bkp = errno;
|
|
|
|
ERR("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", client, strerror(errno));
|
2016-10-22 16:49:01 -07:00
|
|
|
closesocket(client);
|
2016-08-24 08:34:59 -07:00
|
|
|
errno = errno_bkp;
|
2016-10-22 17:14:45 -07:00
|
|
|
return INVALID_SOCKET;
|
2016-08-24 08:34:59 -07:00
|
|
|
}
|
|
|
|
}
|
2016-10-22 08:15:16 -07:00
|
|
|
#endif
|
|
|
|
|
2016-08-24 08:34:59 -07:00
|
|
|
return client;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
static void
|
2016-08-30 05:34:10 -07:00
|
|
|
_efl_net_server_fd_event_read(void *data EINA_UNUSED, const Efl_Event *event)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
2016-10-21 04:24:50 -07:00
|
|
|
efl_net_server_fd_process_incoming_data(event->object);
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-08-30 05:34:10 -07:00
|
|
|
_efl_net_server_fd_event_error(void *data EINA_UNUSED, const Efl_Event *event)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
Eo *o = event->object;
|
|
|
|
Eina_Error err = EBADF;
|
|
|
|
|
|
|
|
efl_net_server_serving_set(o, EINA_FALSE);
|
2016-08-29 16:13:22 -07:00
|
|
|
efl_event_callback_call(o, EFL_NET_SERVER_EVENT_ERROR, &err);
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Efl_Object *
|
|
|
|
_efl_net_server_fd_efl_object_finalize(Eo *o, Efl_Net_Server_Fd_Data *pd EINA_UNUSED)
|
|
|
|
{
|
|
|
|
o = efl_finalize(efl_super(o, MY_CLASS));
|
|
|
|
if (!o) return NULL;
|
|
|
|
|
|
|
|
// TODO: only register "read" if "can_read" is being monitored?
|
|
|
|
efl_event_callback_add(o, EFL_LOOP_FD_EVENT_READ, _efl_net_server_fd_event_read, NULL);
|
|
|
|
efl_event_callback_add(o, EFL_LOOP_FD_EVENT_ERROR, _efl_net_server_fd_event_error, NULL);
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Efl_Object *
|
|
|
|
_efl_net_server_fd_efl_object_constructor(Eo *o, Efl_Net_Server_Fd_Data *pd EINA_UNUSED)
|
|
|
|
{
|
|
|
|
pd->family = AF_UNSPEC;
|
|
|
|
return efl_constructor(efl_super(o, MY_CLASS));
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_object_destructor(Eo *o, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
2016-10-22 17:26:02 -07:00
|
|
|
SOCKET fd = efl_loop_fd_get(o);
|
|
|
|
|
|
|
|
if (fd != INVALID_SOCKET)
|
|
|
|
{
|
|
|
|
efl_loop_fd_set(o, INVALID_SOCKET);
|
|
|
|
closesocket(fd);
|
|
|
|
}
|
|
|
|
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
efl_destructor(efl_super(o, MY_CLASS));
|
|
|
|
|
|
|
|
eina_stringshare_replace(&pd->address, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_loop_fd_fd_set(Eo *o, Efl_Net_Server_Fd_Data *pd, int fd)
|
|
|
|
{
|
|
|
|
efl_loop_fd_set(efl_super(o, MY_CLASS), fd);
|
|
|
|
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd != INVALID_SOCKET)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
/* apply postponed values */
|
|
|
|
efl_net_server_fd_close_on_exec_set(o, pd->close_on_exec);
|
|
|
|
efl_net_server_fd_reuse_address_set(o, pd->reuse_address);
|
|
|
|
efl_net_server_fd_reuse_port_set(o, pd->reuse_port);
|
|
|
|
|
|
|
|
if (pd->family == AF_UNSPEC)
|
|
|
|
{
|
|
|
|
ERR("efl_loop_fd_set() must be called after efl_net_server_fd_family_set()");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
efl_net_server_address_set(o, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_net_server_address_set(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, const char *address)
|
|
|
|
{
|
|
|
|
eina_stringshare_replace(&pd->address, address);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static const char *
|
|
|
|
_efl_net_server_fd_efl_net_server_address_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
return pd->address;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static unsigned int
|
|
|
|
_efl_net_server_fd_efl_net_server_clients_count_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
return pd->clients_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_net_server_clients_count_set(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, unsigned int count)
|
|
|
|
{
|
|
|
|
pd->clients_count = count;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_net_server_clients_limit_set(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, unsigned int limit, Eina_Bool reject_excess)
|
|
|
|
{
|
|
|
|
pd->clients_limit = limit;
|
|
|
|
pd->clients_reject_excess = reject_excess;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_net_server_clients_limit_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, unsigned int *limit, Eina_Bool *reject_excess)
|
|
|
|
{
|
|
|
|
if (limit) *limit = pd->clients_limit;
|
|
|
|
if (reject_excess) *reject_excess = pd->clients_reject_excess;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_efl_net_server_serving_set(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, Eina_Bool serving)
|
|
|
|
{
|
|
|
|
if (pd->serving == serving) return;
|
|
|
|
pd->serving = serving;
|
|
|
|
if (serving)
|
2016-08-29 16:13:22 -07:00
|
|
|
efl_event_callback_call(o, EFL_NET_SERVER_EVENT_SERVING, NULL);
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Error
|
|
|
|
_efl_net_server_fd_efl_net_server_serve(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd EINA_UNUSED, const char *address)
|
|
|
|
{
|
|
|
|
DBG("address=%s", address);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_efl_net_server_serving_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
return pd->serving;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_close_on_exec_set(Eo *o, Efl_Net_Server_Fd_Data *pd, Eina_Bool close_on_exec)
|
|
|
|
{
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef FD_CLOEXEC
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
int flags, fd;
|
|
|
|
Eina_Bool old = pd->close_on_exec;
|
2016-10-22 08:15:16 -07:00
|
|
|
#endif
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
pd->close_on_exec = close_on_exec;
|
|
|
|
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef FD_CLOEXEC
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return EINA_TRUE; /* postpone until fd_set() */
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
flags = fcntl(fd, F_GETFD);
|
|
|
|
if (flags < 0)
|
|
|
|
{
|
|
|
|
ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
|
2016-09-03 15:57:43 -07:00
|
|
|
pd->close_on_exec = old;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
if (close_on_exec)
|
|
|
|
flags |= FD_CLOEXEC;
|
|
|
|
else
|
|
|
|
flags &= (~FD_CLOEXEC);
|
|
|
|
if (fcntl(fd, F_SETFD, flags) < 0)
|
|
|
|
{
|
|
|
|
ERR("fcntl(%d, F_SETFD, %#x): %s", fd, flags, strerror(errno));
|
|
|
|
pd->close_on_exec = old;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2016-10-22 08:15:16 -07:00
|
|
|
#endif
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_close_on_exec_get(Eo *o, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef FD_CLOEXEC
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
int flags, fd;
|
|
|
|
|
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return pd->close_on_exec;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
/* if there is a fd, always query it directly as it may be modified
|
|
|
|
* elsewhere by nasty users.
|
|
|
|
*/
|
|
|
|
flags = fcntl(fd, F_GETFD);
|
|
|
|
if (flags < 0)
|
|
|
|
{
|
|
|
|
ERR("fcntl(%d, F_GETFD): %s", fd, strerror(errno));
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pd->close_on_exec = !!(flags & FD_CLOEXEC); /* sync */
|
2016-10-22 08:15:16 -07:00
|
|
|
#endif
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
return pd->close_on_exec;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_reuse_address_set(Eo *o, Efl_Net_Server_Fd_Data *pd, Eina_Bool reuse_address)
|
|
|
|
{
|
|
|
|
int value, fd;
|
|
|
|
Eina_Bool old = pd->reuse_address;
|
|
|
|
|
|
|
|
pd->reuse_address = reuse_address;
|
|
|
|
|
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return EINA_TRUE; /* postpone until fd_set() */
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
value = reuse_address;
|
2016-10-22 08:15:16 -07:00
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) != 0)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
ERR("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, %d): %s",
|
2016-10-22 08:15:16 -07:00
|
|
|
fd, value, eina_error_msg_get(efl_net_socket_error_get()));
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
pd->reuse_address = old;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_reuse_address_get(Eo *o, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
int value = 0, fd;
|
|
|
|
socklen_t valuelen;
|
|
|
|
|
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return pd->reuse_address;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
/* if there is a fd, always query it directly as it may be modified
|
|
|
|
* elsewhere by nasty users.
|
|
|
|
*/
|
|
|
|
valuelen = sizeof(value);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, &valuelen) != 0)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
ERR("getsockopt(%d, SOL_SOCKET, SO_REUSEADDR): %s",
|
2016-10-22 08:15:16 -07:00
|
|
|
fd, eina_error_msg_get(efl_net_socket_error_get()));
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pd->reuse_address = !!value; /* sync */
|
|
|
|
return pd->reuse_address;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_reuse_port_set(Eo *o, Efl_Net_Server_Fd_Data *pd, Eina_Bool reuse_port)
|
|
|
|
{
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef SO_REUSEPORT
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
int value, fd;
|
|
|
|
Eina_Bool old = pd->reuse_port;
|
2016-10-22 08:15:16 -07:00
|
|
|
#endif
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
pd->reuse_port = reuse_port;
|
|
|
|
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef SO_REUSEPORT
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return EINA_TRUE; /* postpone until fd_set() */
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
value = reuse_port;
|
2016-10-22 08:15:16 -07:00
|
|
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)) != 0)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
ERR("setsockopt(%d, SOL_SOCKET, SO_REUSEPORT, %d): %s",
|
2016-10-22 08:15:16 -07:00
|
|
|
fd, value, eina_error_msg_get(efl_net_socket_error_get()));
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
pd->reuse_port = old;
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2016-09-01 10:08:11 -07:00
|
|
|
#endif
|
2016-10-22 08:15:16 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
|
|
|
_efl_net_server_fd_reuse_port_get(Eo *o, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
2016-10-22 08:15:16 -07:00
|
|
|
#ifdef SO_REUSEPORT
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
int value = 0, fd;
|
|
|
|
socklen_t valuelen;
|
|
|
|
|
|
|
|
fd = efl_loop_fd_get(o);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (fd == INVALID_SOCKET) return pd->reuse_port;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
|
|
|
|
/* if there is a fd, always query it directly as it may be modified
|
|
|
|
* elsewhere by nasty users.
|
|
|
|
*/
|
|
|
|
valuelen = sizeof(value);
|
2016-10-22 08:15:16 -07:00
|
|
|
if (getsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &value, &valuelen) != 0)
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
{
|
|
|
|
ERR("getsockopt(%d, SOL_SOCKET, SO_REUSEPORT): %s",
|
2016-10-22 08:15:16 -07:00
|
|
|
fd, eina_error_msg_get(efl_net_socket_error_get()));
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pd->reuse_port = !!value; /* sync */
|
2016-09-01 10:08:11 -07:00
|
|
|
#endif
|
2016-10-22 08:15:16 -07:00
|
|
|
|
|
|
|
return pd->reuse_port;
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_family_set(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd, int family)
|
|
|
|
{
|
|
|
|
pd->family = family;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static int
|
|
|
|
_efl_net_server_fd_family_get(Eo *o EINA_UNUSED, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
return pd->family;
|
|
|
|
}
|
|
|
|
|
2016-10-21 04:24:50 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_efl_net_server_fd_process_incoming_data(Eo *o, Efl_Net_Server_Fd_Data *pd)
|
|
|
|
{
|
|
|
|
Eina_Bool do_reject = EINA_FALSE;
|
|
|
|
struct sockaddr_storage addr;
|
2016-10-22 16:49:01 -07:00
|
|
|
SOCKET client, fd;
|
2016-10-21 04:24:50 -07:00
|
|
|
socklen_t addrlen;
|
|
|
|
|
|
|
|
if ((pd->clients_limit > 0) && (pd->clients_count >= pd->clients_limit))
|
|
|
|
{
|
|
|
|
if (!pd->clients_reject_excess)
|
|
|
|
{
|
|
|
|
// TODO: disconnect 'read' so stops calling?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
do_reject = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = efl_loop_fd_get(o);
|
|
|
|
|
|
|
|
addrlen = sizeof(addr);
|
|
|
|
client = efl_net_accept4(fd, (struct sockaddr *)&addr, &addrlen,
|
|
|
|
efl_net_server_fd_close_on_exec_get(o));
|
2016-10-22 17:41:01 -07:00
|
|
|
if (client == INVALID_SOCKET)
|
2016-10-21 04:24:50 -07:00
|
|
|
{
|
2016-10-22 08:15:16 -07:00
|
|
|
Eina_Error err = efl_net_socket_error_get();
|
|
|
|
ERR("accept(%d): %s", fd, eina_error_msg_get(err));
|
2016-10-21 04:24:50 -07:00
|
|
|
efl_event_callback_call(o, EFL_NET_SERVER_EVENT_ERROR, &err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (do_reject)
|
|
|
|
efl_net_server_fd_client_reject(o, client);
|
|
|
|
else
|
|
|
|
efl_net_server_fd_client_add(o, client);
|
|
|
|
}
|
|
|
|
|
efl.net: socket, server and dialer for TCP.
Efl.Net.Server defines how to accept new connections, doing the
bind(), listen() and accept() for protocols such as TCP.
Efl.Net.Dialer defines to to reach a server.
Both are based on Efl.Net.Socket as communication interface that is
based on Efl.Io.Reader, Efl.Io.Writer and Efl.Io.Closer, thus being
usable with code such as Efl.Io.Copier.
The Server will emit an event "client,add" with the established
Socket, which is a child and can be closed by both the server or the
user.
The Dialer extends the Socket and allows for creating one given an
address, that will be resolved and connected.
TCP is the initial implementation so we an validate the
interfaces. UDP, Unix-Local and SSL will come later as derivate
classes.
The examples are documented and should cover the basic principles:
- efl_io_copier_example can accept "tcp://IP:PORT" and will work as a
"netcat", can send data from socket, file or stdin to a socket,
file, stdout or stderr.
- efl_net_server_example listens for connections and can either reply
"Hello World!" and take some data or work as an echo-server,
looping back all received data to the user.
More complex interactions that require a "chat" between client and
server will be covered with new classes later, such as a queue that
empties itself once data is read.
2016-08-17 21:53:16 -07:00
|
|
|
#include "efl_net_server_fd.eo.c"
|