add TCP V4 and V6 only socket functions

This commit is contained in:
Jay Sorg 2019-06-29 23:59:18 -07:00
parent d7bd6f726b
commit 0bc7803eaa
5 changed files with 178 additions and 8 deletions

View File

@ -3823,3 +3823,132 @@ 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(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 (bind(sck, (struct sockaddr*) &s, sizeof(s)) == 0)
{
return 0;
}
return -1;
#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(int sck, const char *port, const char *address)
{
#if defined(XRDP_ENABLE_IPV6)
struct sockaddr_in6 sa;
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)
{
return 0;
}
return -1;
#else
return -1;
#endif
}

View File

@ -183,6 +183,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(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);
/* glib-style wrappers */
#define g_new(struct_type, n_structs) \

View File

@ -885,7 +885,42 @@ trans_listen_address(struct trans *self, char *port, const char *address)
}
}
}
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(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(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;
}
}
}
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

@ -470,7 +470,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP4;
*index = lindex;
return 0;
}
@ -482,7 +482,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP4;
*index = lindex;
return 0;
}
@ -496,7 +496,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP4;
*index = lindex;
return 0;
}
@ -508,7 +508,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP6;
*index = lindex;
return 0;
}
@ -520,7 +520,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP6;
*index = lindex;
return 0;
}
@ -534,7 +534,7 @@ xrdp_listen_pp(struct xrdp_listen *self, int *index,
bytes = xrdp_listen_parse_integer(port, 128, str, str_end - str);
str += bytes;
lindex += bytes;
*mode = TRANS_MODE_TCP;
*mode = TRANS_MODE_TCP6;
*index = lindex;
return 0;
}