diff --git a/common/os_calls.c b/common/os_calls.c index 6289c276..2b4e0e9b 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -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. */ @@ -3859,7 +3878,7 @@ g_tcp4_socket(void) /*****************************************************************************/ int -g_tcp4_bind(int sck, const char *port, const char *address) +g_tcp4_bind_address(int sck, const char *port, const char *address) { #if defined(XRDP_ENABLE_IPV6ONLY) return -1; @@ -3870,11 +3889,15 @@ g_tcp4_bind(int sck, const char *port, const char *address) s.sin_family = AF_INET; s.sin_addr.s_addr = htonl(INADDR_ANY); s.sin_port = htons((uint16_t) atoi(port)); - if (bind(sck, (struct sockaddr*) &s, sizeof(s)) == 0) + if (inet_aton(address, &s.sin_addr) < 0) { - return 0; + return -1; /* bad address */ } - return -1; + if (bind(sck, (struct sockaddr*) &s, sizeof(s)) < 0) + { + return -1; + } + return 0; #endif } @@ -3934,20 +3957,37 @@ g_tcp6_socket(void) /*****************************************************************************/ int -g_tcp6_bind(int sck, const char *port, const char *address) +g_tcp6_bind_address(int sck, const char *port, const char *address) { #if defined(XRDP_ENABLE_IPV6) - struct sockaddr_in6 sa; + int rv; + int error; + struct addrinfo hints; + struct addrinfo *list; + struct addrinfo *i; - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET6; - sa.sin6_addr = in6addr_any; - sa.sin6_port = htons((uint16_t) atoi(port)); - if (bind(sck, (struct sockaddr *) &sa, sizeof(sa)) == 0) + 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) { - return 0; + i = list; + while ((i != NULL) && (rv < 0)) + { + rv = bind(sck, i->ai_addr, i->ai_addrlen); + i = i->ai_next; + } + freeaddrinfo(list); } - return -1; + else + { + return -1; + } + return rv; #else return -1; #endif diff --git a/common/os_calls.h b/common/os_calls.h index 6cbe499a..b52a84df 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -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); @@ -184,9 +185,9 @@ 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(int sck, const char *port, const char *address); +int g_tcp4_bind_address(int sck, const char *port, const char *address); int g_tcp6_socket(void); -int g_tcp6_bind(int sck, const char *port, const char *address); +int g_tcp6_bind_address(int sck, const char *port, const char *address); /* glib-style wrappers */ #define g_new(struct_type, n_structs) \ diff --git a/common/trans.c b/common/trans.c index 608b8819..883d7cbd 100644 --- a/common/trans.c +++ b/common/trans.c @@ -875,7 +875,7 @@ 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) { @@ -893,7 +893,7 @@ trans_listen_address(struct trans *self, char *port, const char *address) return 1; } g_tcp_set_non_blocking(self->sck); - if (g_tcp4_bind(self->sck, port, address) == 0) + if (g_tcp4_bind_address(self->sck, port, address) == 0) { if (g_tcp_listen(self->sck) == 0) { @@ -911,7 +911,7 @@ trans_listen_address(struct trans *self, char *port, const char *address) return 1; } g_tcp_set_non_blocking(self->sck); - if (g_tcp6_bind(self->sck, port, address) == 0) + if (g_tcp6_bind_address(self->sck, port, address) == 0) { if (g_tcp_listen(self->sck) == 0) { diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index fb71d7d3..c8d8924f 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -5,18 +5,24 @@ ini_version=1 ; fork a new process for each incoming connection fork=true -; ports to listen on, examples +; 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://:3389 (<- 192.168.1.1:3389) -;tcp6://.:3389 -;tcp6://:3389 -;tcp6://{}:3389 +;tcp://.:3389 127.0.0.1:3389 +;tcp://:3389 *:3389 +;tcp://:3389 192.168.1.1:3389 +;tcp6://.:3389 ::1:3389 +;tcp6://:3389 *:3389 +;tcp6://{}:3389 {FC00:0:0:0:0:0:0:1}:3389 ;vsock://: -port=tcp://:3389 +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://: above use_vsock=false ; regulate if the listening socket use socket option tcp_nodelay ; no buffering will be performed in the TCP stack