commit
f627b29633
@ -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
|
||||
}
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
20
xrdp/xrdp.c
20
xrdp/xrdp.c
@ -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();
|
||||
|
@ -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*
|
||||
|
@ -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
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user