From 7176f1464710fd809af92ae3c2fcf9412eda9ace Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Wed, 2 Oct 2013 12:52:35 -0700 Subject: [PATCH] added options to set tcp send and recv buffer sizes --- common/os_calls.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++ common/os_calls.h | 4 +++ xrdp/xrdp.ini | 2 ++ xrdp/xrdp_listen.c | 61 +++++++++++++++++++++++++++++++ xrdp/xrdp_types.h | 2 ++ 5 files changed, 159 insertions(+) diff --git a/common/os_calls.c b/common/os_calls.c index a26a180f..3ed08a97 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -492,6 +492,96 @@ g_tcp_socket(void) return rv; } +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_set_send_buffer_bytes(int sck, int bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = bytes; + option_len = sizeof(option_value); + if (setsockopt(sck, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + option_len) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_get_send_buffer_bytes(int sck, int *bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = 0; + option_len = sizeof(option_value); + if (getsockopt(sck, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + &option_len) != 0) + { + return 1; + } + *bytes = option_value; + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_set_recv_buffer_bytes(int sck, int bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = bytes; + option_len = sizeof(option_value); + if (setsockopt(sck, SOL_SOCKET, SO_RCVBUF, (char *)&option_value, + option_len) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_get_recv_buffer_bytes(int sck, int *bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = 0; + option_len = sizeof(option_value); + if (getsockopt(sck, SOL_SOCKET, SO_RCVBUF, (char *)&option_value, + &option_len) != 0) + { + return 1; + } + *bytes = option_value; + return 0; +} + /*****************************************************************************/ int APP_CC g_tcp_local_socket(void) diff --git a/common/os_calls.h b/common/os_calls.h index b68dd4bf..8085911d 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -45,6 +45,10 @@ int APP_CC 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_sck_set_send_buffer_bytes(int sck, int bytes); +int APP_CC g_sck_get_send_buffer_bytes(int sck, int *bytes); +int APP_CC g_sck_set_recv_buffer_bytes(int sck, int bytes); +int APP_CC g_sck_get_recv_buffer_bytes(int sck, int *bytes); int APP_CC g_tcp_local_socket(void); int APP_CC g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid); void APP_CC g_tcp_close(int sck); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index c191619b..604ac515 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -13,6 +13,8 @@ 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 +#tcp_send_buffer_bytes=32768 +#tcp_recv_buffer_bytes=32768 #black=000000 #grey=d6d3ce #dark_grey=808080 diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 2e1617a6..5d7edf83 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -217,6 +217,18 @@ xrdp_listen_get_port_address(char *port, int port_bytes, val = (char *)list_get_item(values, index); *tcp_keepalive = g_text2bool(val); } + + if (g_strcasecmp(val, "tcp_send_buffer_bytes") == 0) + { + val = (char *)list_get_item(values, index); + startup_param->send_buffer_bytes = g_atoi(val); + } + + if (g_strcasecmp(val, "tcp_recv_buffer_bytes") == 0) + { + val = (char *)list_get_item(values, index); + startup_param->recv_buffer_bytes = g_atoi(val); + } } } } @@ -322,6 +334,7 @@ xrdp_listen_main_loop(struct xrdp_listen *self) tbus done_obj; int tcp_nodelay; int tcp_keepalive; + int bytes; self->status = 1; @@ -356,6 +369,54 @@ xrdp_listen_main_loop(struct xrdp_listen *self) } } + if (self->startup_params->send_buffer_bytes > 0) + { + bytes = self->startup_params->send_buffer_bytes; + log_message(LOG_LEVEL_INFO, "setting send buffer to %d bytes", + bytes); + if (g_sck_set_send_buffer_bytes(self->listen_trans->sck, + bytes) != 0) + { + log_message(LOG_LEVEL_ERROR, "error setting send buffer"); + } + else + { + if (g_sck_get_send_buffer_bytes(self->listen_trans->sck, + &bytes) != 0) + { + log_message(LOG_LEVEL_ERROR, "error getting send buffer"); + } + else + { + log_message(LOG_LEVEL_INFO, "send buffer set to %d bytes", bytes); + } + } + } + + if (self->startup_params->recv_buffer_bytes > 0) + { + bytes = self->startup_params->recv_buffer_bytes; + log_message(LOG_LEVEL_INFO, "setting recv buffer to %d bytes", + bytes); + if (g_sck_set_recv_buffer_bytes(self->listen_trans->sck, + bytes) != 0) + { + log_message(LOG_LEVEL_ERROR, "error setting recv buffer"); + } + else + { + if (g_sck_get_recv_buffer_bytes(self->listen_trans->sck, + &bytes) != 0) + { + log_message(LOG_LEVEL_ERROR, "error getting recv buffer"); + } + else + { + log_message(LOG_LEVEL_INFO, "recv buffer set to %d bytes", bytes); + } + } + } + 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 */ diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index cd71c342..3811b16b 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -489,4 +489,6 @@ struct xrdp_startup_params int help; int version; int fork; + int send_buffer_bytes; + int recv_buffer_bytes; };