Merge pull request #28 from ArvidNorr/tcp_nodelay

Support for TCP keepalive and TCP no_delay added
This commit is contained in:
ArvidNorr 2012-06-18 00:00:05 -07:00
commit d2903cd1fc
4 changed files with 100 additions and 3 deletions

View File

@ -325,9 +325,11 @@ g_getchar(void)
}
/*****************************************************************************/
/*Returns 0 on success*/
int APP_CC
g_tcp_set_no_delay(int sck)
{
int ret = 1 ; /*error*/
#if defined(_WIN32)
int option_value;
int option_len;
@ -345,11 +347,55 @@ g_tcp_set_no_delay(int sck)
{
option_value = 1;
option_len = sizeof(option_value);
setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
option_len);
if(setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value,
option_len)==0)
{
ret = 0 ; /* success */
}
}
return 0;
}
else
{
g_writeln("Error getting tcp_nodelay");
}
return ret;
}
/*****************************************************************************/
/*Returns 0 on success*/
int APP_CC
g_tcp_set_keepalive(int sck)
{
int ret = 1 ; /*error*/
#if defined(_WIN32)
int option_value;
int option_len;
#else
int option_value;
unsigned int option_len;
#endif
option_len = sizeof(option_value);
/* SOL_TCP IPPROTO_TCP */
if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value,
&option_len) == 0)
{
if (option_value == 0)
{
option_value = 1;
option_len = sizeof(option_value);
if(setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value,
option_len)==0)
{
ret = 0 ; /* success */
}
}
}
else
{
g_writeln("Error getting tcp_keepalive");
}
return ret;
}
/*****************************************************************************/

View File

@ -64,6 +64,8 @@ g_getchar(void);
int APP_CC
g_tcp_set_no_delay(int sck);
int APP_CC
g_tcp_set_keepalive(int sck);
int APP_CC
g_tcp_socket(void);
int APP_CC
g_tcp_local_socket(void);

View File

@ -7,6 +7,12 @@ crypt_level=low
channel_code=1
max_bpp=24
fork=yes
# regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack
tcp_nodelay=yes
# regulate if the listening socket use socket option keepalive
# if the network connection disappear without close messages the connection will be closed
tcp_keepalive=yes
#black=000000
#grey=d6d3ce
#dark_grey=808080

View File

@ -134,6 +134,7 @@ xrdp_process_run(void* in_val)
static int
xrdp_listen_get_port_address(char* port, int port_bytes,
char* address, int address_bytes,
int *tcp_nodelay, int *tcp_keepalive,
struct xrdp_startup_params* startup_param)
{
int fd;
@ -151,6 +152,8 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
/* see if port or address is in xrdp.ini file */
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file);
*tcp_nodelay = 0 ;
*tcp_keepalive = 0 ;
if (fd > 0)
{
names = list_create();
@ -189,6 +192,28 @@ xrdp_listen_get_port_address(char* port, int port_bytes,
startup_param->fork = 1;
}
}
if (g_strcasecmp(val, "tcp_nodelay") == 0)
{
val = (char*)list_get_item(values, index);
if ((g_strcasecmp(val, "yes") == 0) ||
(g_strcasecmp(val, "on") == 0) ||
(g_strcasecmp(val, "true") == 0) ||
(g_atoi(val) != 0))
{
*tcp_nodelay = 1 ;
}
}
if (g_strcasecmp(val, "tcp_keepalive") == 0)
{
val = (char*)list_get_item(values, index);
if ((g_strcasecmp(val, "yes") == 0) ||
(g_strcasecmp(val, "on") == 0) ||
(g_strcasecmp(val, "true") == 0) ||
(g_atoi(val) != 0))
{
*tcp_keepalive = 1 ;
}
}
}
}
}
@ -283,19 +308,37 @@ xrdp_listen_main_loop(struct xrdp_listen* self)
tbus term_obj;
tbus sync_obj;
tbus done_obj;
int tcp_nodelay;
int tcp_keepalive;
self->status = 1;
if (xrdp_listen_get_port_address(port, sizeof(port),
address, sizeof(address),
&tcp_nodelay, &tcp_keepalive,
self->startup_params) != 0)
{
g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed");
self->status = -1;
return 1;
}
/*Create socket*/
error = trans_listen_address(self->listen_trans, port, address);
if (error == 0)
{
if(tcp_nodelay)
{
if(g_tcp_set_no_delay(self->listen_trans->sck))
{
g_writeln("Error setting tcp_nodelay");
}
}
if(tcp_keepalive)
{
if(g_tcp_set_keepalive(self->listen_trans->sck))
{
g_writeln("Error setting tcp_keepalive");
}
}
self->listen_trans->trans_conn_in = xrdp_listen_conn_in;
self->listen_trans->callback_data = self;
term_obj = g_get_term_event(); /*Global termination event */