commit
f627b29633
@ -1041,6 +1041,25 @@ g_sck_vsock_bind(int sck, const char *port)
|
|||||||
#endif
|
#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)
|
#if defined(XRDP_ENABLE_IPV6)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Helper function for g_tcp_bind_address. */
|
/* Helper function for g_tcp_bind_address. */
|
||||||
@ -3823,3 +3842,153 @@ g_mirror_memcpy(void *dst, const void *src, int len)
|
|||||||
return 0;
|
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_tcp_bind(int sck, const char *port);
|
||||||
int g_sck_local_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(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_tcp_bind_address(int sck, const char* port, const char* address);
|
||||||
int g_sck_listen(int sck);
|
int g_sck_listen(int sck);
|
||||||
int g_tcp_accept(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_shmdt(const void *shmaddr);
|
||||||
int g_gethostname(char *name, int len);
|
int g_gethostname(char *name, int len);
|
||||||
int g_mirror_memcpy(void *dst, const void *src, 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 */
|
/* glib-style wrappers */
|
||||||
#define g_new(struct_type, n_structs) \
|
#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);
|
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)
|
if (g_tcp_listen(self->sck) == 0)
|
||||||
{
|
{
|
||||||
@ -885,7 +921,6 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,11 @@
|
|||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
#include "parse.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_UNIX 2
|
||||||
#define TRANS_MODE_VSOCK 3
|
#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_LISTENER 1
|
||||||
#define TRANS_TYPE_SERVER 2
|
#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 (!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 */
|
/* start of daemonizing code */
|
||||||
pid = g_fork();
|
pid = g_fork();
|
||||||
|
|
||||||
@ -587,16 +597,6 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
if (0 != pid)
|
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);
|
g_writeln("daemon process %d started ok", pid);
|
||||||
/* exit, this is the main process */
|
/* exit, this is the main process */
|
||||||
g_deinit();
|
g_deinit();
|
||||||
|
@ -170,7 +170,7 @@ xrdp_listen_delete(struct xrdp_listen* self);
|
|||||||
int
|
int
|
||||||
xrdp_listen_main_loop(struct xrdp_listen* self);
|
xrdp_listen_main_loop(struct xrdp_listen* self);
|
||||||
int
|
int
|
||||||
xrdp_listen_test(void);
|
xrdp_listen_test(struct xrdp_startup_params *startup_params);
|
||||||
|
|
||||||
/* xrdp_region.c */
|
/* xrdp_region.c */
|
||||||
struct xrdp_region*
|
struct xrdp_region*
|
||||||
|
@ -4,9 +4,25 @@ ini_version=1
|
|||||||
|
|
||||||
; fork a new process for each incoming connection
|
; fork a new process for each incoming connection
|
||||||
fork=true
|
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=3389
|
||||||
|
|
||||||
; 'port' above should be connected to with vsock instead of tcp
|
; '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
|
use_vsock=false
|
||||||
; regulate if the listening socket use socket option tcp_nodelay
|
; regulate if the listening socket use socket option tcp_nodelay
|
||||||
; no buffering will be performed in the TCP stack
|
; 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
|
struct xrdp_listen
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
struct trans* listen_trans; /* in tcp listen mode */
|
struct list *trans_list; /* list of struct trans* */
|
||||||
struct list* process_list;
|
struct list *process_list;
|
||||||
|
struct list *fork_list;
|
||||||
tbus pro_done_event;
|
tbus pro_done_event;
|
||||||
struct xrdp_startup_params* startup_params;
|
struct xrdp_startup_params* startup_params;
|
||||||
};
|
};
|
||||||
@ -527,14 +528,17 @@ struct xrdp_mod_data
|
|||||||
|
|
||||||
struct xrdp_startup_params
|
struct xrdp_startup_params
|
||||||
{
|
{
|
||||||
char port[128];
|
char port[1024];
|
||||||
int kill;
|
int kill;
|
||||||
int no_daemon;
|
int no_daemon;
|
||||||
int help;
|
int help;
|
||||||
int version;
|
int version;
|
||||||
int fork;
|
int fork;
|
||||||
int send_buffer_bytes;
|
int tcp_send_buffer_bytes;
|
||||||
int recv_buffer_bytes;
|
int tcp_recv_buffer_bytes;
|
||||||
|
int tcp_nodelay;
|
||||||
|
int tcp_keepalive;
|
||||||
|
int use_vsock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user