Merge pull request #1366 from jsorg71/listen-list

Listen list
This commit is contained in:
jsorg71 2019-07-02 23:58:23 -07:00 committed by GitHub
commit f627b29633
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 913 additions and 325 deletions

View File

@ -1041,6 +1041,25 @@ g_sck_vsock_bind(int sck, const char *port)
#endif
}
/*****************************************************************************/
int
g_sck_vsock_bind_address(int sck, const char *port, const char *address)
{
#if defined(XRDP_ENABLE_VSOCK)
struct sockaddr_vm s;
g_memset(&s, 0, sizeof(struct sockaddr_vm));
s.svm_family = AF_VSOCK;
s.svm_port = atoi(port);
s.svm_cid = atoi(address);
return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_vm));
#else
return -1;
#endif
}
#if defined(XRDP_ENABLE_IPV6)
/*****************************************************************************/
/* Helper function for g_tcp_bind_address. */
@ -3823,3 +3842,153 @@ g_mirror_memcpy(void *dst, const void *src, int len)
return 0;
}
/*****************************************************************************/
int
g_tcp4_socket(void)
{
#if defined(XRDP_ENABLE_IPV6ONLY)
return -1;
#else
int rv;
int option_value;
socklen_t option_len;
rv = socket(AF_INET, SOCK_STREAM, 0);
if (rv < 0)
{
return -1;
}
option_len = sizeof(option_value);
if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
(char *) &option_value, &option_len) == 0)
{
if (option_value == 0)
{
option_value = 1;
option_len = sizeof(option_value);
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
(char *) &option_value, option_len) < 0)
{
}
}
}
return rv;
#endif
}
/*****************************************************************************/
int
g_tcp4_bind_address(int sck, const char *port, const char *address)
{
#if defined(XRDP_ENABLE_IPV6ONLY)
return -1;
#else
struct sockaddr_in s;
memset(&s, 0, sizeof(s));
s.sin_family = AF_INET;
s.sin_addr.s_addr = htonl(INADDR_ANY);
s.sin_port = htons((uint16_t) atoi(port));
if (inet_aton(address, &s.sin_addr) < 0)
{
return -1; /* bad address */
}
if (bind(sck, (struct sockaddr*) &s, sizeof(s)) < 0)
{
return -1;
}
return 0;
#endif
}
/*****************************************************************************/
int
g_tcp6_socket(void)
{
#if defined(XRDP_ENABLE_IPV6)
int rv;
int option_value;
socklen_t option_len;
rv = socket(AF_INET6, SOCK_STREAM, 0);
if (rv < 0)
{
return -1;
}
option_len = sizeof(option_value);
if (getsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY,
(char *) &option_value, &option_len) == 0)
{
#if defined(XRDP_ENABLE_IPV6ONLY)
if (option_value == 0)
{
option_value = 1;
#else
if (option_value != 0)
{
option_value = 0;
#endif
option_len = sizeof(option_value);
if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY,
(char *) &option_value, option_len) < 0)
{
}
}
}
option_len = sizeof(option_value);
if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
(char *) &option_value, &option_len) == 0)
{
if (option_value == 0)
{
option_value = 1;
option_len = sizeof(option_value);
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
(char *) &option_value, option_len) < 0)
{
}
}
}
return rv;
#else
return -1;
#endif
}
/*****************************************************************************/
int
g_tcp6_bind_address(int sck, const char *port, const char *address)
{
#if defined(XRDP_ENABLE_IPV6)
int rv;
int error;
struct addrinfo hints;
struct addrinfo *list;
struct addrinfo *i;
rv = -1;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = 0;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
error = getaddrinfo(address, port, &hints, &list);
if (error == 0)
{
i = list;
while ((i != NULL) && (rv < 0))
{
rv = bind(sck, i->ai_addr, i->ai_addrlen);
i = i->ai_next;
}
freeaddrinfo(list);
}
else
{
return -1;
}
return rv;
#else
return -1;
#endif
}

View File

@ -71,6 +71,7 @@ int g_sck_set_non_blocking(int sck);
int g_tcp_bind(int sck, const char *port);
int g_sck_local_bind(int sck, const char* port);
int g_sck_vsock_bind(int sck, const char* port);
int g_sck_vsock_bind_address(int sck, const char *port, const char *address);
int g_tcp_bind_address(int sck, const char* port, const char* address);
int g_sck_listen(int sck);
int g_tcp_accept(int sck);
@ -183,6 +184,10 @@ void * g_shmat(int shmid);
int g_shmdt(const void *shmaddr);
int g_gethostname(char *name, int len);
int g_mirror_memcpy(void *dst, const void *src, int len);
int g_tcp4_socket(void);
int g_tcp4_bind_address(int sck, const char *port, const char *address);
int g_tcp6_socket(void);
int g_tcp6_bind_address(int sck, const char *port, const char *address);
/* glib-style wrappers */
#define g_new(struct_type, n_structs) \

View File

@ -875,7 +875,43 @@ trans_listen_address(struct trans *self, char *port, const char *address)
g_tcp_set_non_blocking(self->sck);
if (g_sck_vsock_bind(self->sck, port) == 0)
if (g_sck_vsock_bind_address(self->sck, port, address) == 0)
{
if (g_tcp_listen(self->sck) == 0)
{
self->status = TRANS_STATUS_UP; /* ok */
self->type1 = TRANS_TYPE_LISTENER; /* listener */
return 0;
}
}
}
else if (self->mode == TRANS_MODE_TCP4) /* tcp4 */
{
self->sck = g_tcp4_socket();
if (self->sck < 0)
{
return 1;
}
g_tcp_set_non_blocking(self->sck);
if (g_tcp4_bind_address(self->sck, port, address) == 0)
{
if (g_tcp_listen(self->sck) == 0)
{
self->status = TRANS_STATUS_UP; /* ok */
self->type1 = TRANS_TYPE_LISTENER; /* listener */
return 0;
}
}
}
else if (self->mode == TRANS_MODE_TCP6) /* tcp6 */
{
self->sck = g_tcp6_socket();
if (self->sck < 0)
{
return 1;
}
g_tcp_set_non_blocking(self->sck);
if (g_tcp6_bind_address(self->sck, port, address) == 0)
{
if (g_tcp_listen(self->sck) == 0)
{
@ -885,7 +921,6 @@ trans_listen_address(struct trans *self, char *port, const char *address)
}
}
}
return 1;
}

View File

@ -24,9 +24,11 @@
#include "arch.h"
#include "parse.h"
#define TRANS_MODE_TCP 1
#define TRANS_MODE_TCP 1 /* tcp6 if defined, else tcp4 */
#define TRANS_MODE_UNIX 2
#define TRANS_MODE_VSOCK 3
#define TRANS_MODE_TCP4 4 /* tcp4 only */
#define TRANS_MODE_TCP6 6 /* tcp6 only */
#define TRANS_TYPE_LISTENER 1
#define TRANS_TYPE_SERVER 2

View File

@ -575,6 +575,16 @@ main(int argc, char **argv)
if (!no_daemon)
{
/* if can't listen, exit with failure status */
if (xrdp_listen_test(startup_params) != 0)
{
log_message(LOG_LEVEL_ERROR, "Failed to start xrdp daemon, "
"possibly address already in use.");
g_deinit();
/* must exit with failure status,
or systemd cannot detect xrdp daemon couldn't start properly */
g_exit(1);
}
/* start of daemonizing code */
pid = g_fork();
@ -587,16 +597,6 @@ main(int argc, char **argv)
if (0 != pid)
{
/* if can't listen, exit with failure status */
if (xrdp_listen_test() != 0)
{
log_message(LOG_LEVEL_ERROR, "Failed to start xrdp daemon, "
"possibly address already in use.");
g_deinit();
/* must exit with failure status,
or systemd cannot detect xrdp daemon couldn't start properly */
g_exit(1);
}
g_writeln("daemon process %d started ok", pid);
/* exit, this is the main process */
g_deinit();

View File

@ -170,7 +170,7 @@ xrdp_listen_delete(struct xrdp_listen* self);
int
xrdp_listen_main_loop(struct xrdp_listen* self);
int
xrdp_listen_test(void);
xrdp_listen_test(struct xrdp_startup_params *startup_params);
/* xrdp_region.c */
struct xrdp_region*

View File

@ -4,9 +4,25 @@ ini_version=1
; fork a new process for each incoming connection
fork=true
; tcp port to listen
; ports to listen on, number alone means listen on all interfaces
; 0.0.0.0 or :: if ipv6 is configured
; space between multiple occurrences
; examples
;3389
;unix://./tmp/xrdp.socket
;tcp://.:3389 127.0.0.1:3389
;tcp://:3389 *:3389
;tcp://<any ipv4 format addr>:3389 192.168.1.1:3389
;tcp6://.:3389 ::1:3389
;tcp6://:3389 *:3389
;tcp6://{<any ipv6 format addr>}:3389 {FC00:0:0:0:0:0:0:1}:3389
;vsock://<cid>:<port>
port=3389
; 'port' above should be connected to with vsock instead of tcp
; use this only with number alone in port above
; prefer use vsock://<cid>:<port> above
use_vsock=false
; regulate if the listening socket use socket option tcp_nodelay
; no buffering will be performed in the TCP stack

File diff suppressed because it is too large Load Diff

View File

@ -405,8 +405,9 @@ struct xrdp_process
struct xrdp_listen
{
int status;
struct trans* listen_trans; /* in tcp listen mode */
struct list* process_list;
struct list *trans_list; /* list of struct trans* */
struct list *process_list;
struct list *fork_list;
tbus pro_done_event;
struct xrdp_startup_params* startup_params;
};
@ -527,14 +528,17 @@ struct xrdp_mod_data
struct xrdp_startup_params
{
char port[128];
char port[1024];
int kill;
int no_daemon;
int help;
int version;
int fork;
int send_buffer_bytes;
int recv_buffer_bytes;
int tcp_send_buffer_bytes;
int tcp_recv_buffer_bytes;
int tcp_nodelay;
int tcp_keepalive;
int use_vsock;
};
/*