From da8717a4bfa8884a411ae2445b9f1654b0550a64 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 20 May 2008 15:52:06 +0200 Subject: add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers --- ChangeLog | 1 + doc/sync/alarm/node1/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/alarm/node2/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/ftfw/node1/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/ftfw/node2/conntrackd.conf | 22 ++++++++++++++++++++++ include/mcast.h | 2 ++ src/mcast.c | 31 +++++++++++++++++++++++++++++++ src/read_config_lex.l | 2 ++ src/read_config_yy.y | 12 +++++++++++- src/sync-mode.c | 6 ++++++ 10 files changed, 141 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4458830..0b30f4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ o remove (misleading) counters and use information from the statistics mode o use generic nfct_copy() from libnetfilter_conntrack to update objects o use generic nfct_cmp() to compare objects o improve network message sanity checkings +o add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers version 0.9.6 (2008/03/08) ------------------------------ diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf index 3004d07..56bef0c 100644 --- a/doc/sync/alarm/node1/conntrackd.conf +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -39,6 +39,28 @@ Sync { IPv4_interface 192.168.100.100 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf index fb12130..e0cb375 100644 --- a/doc/sync/alarm/node2/conntrackd.conf +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -39,6 +39,28 @@ Sync { IPv4_interface 192.168.100.200 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf index fadeb9d..f3211db 100644 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ b/doc/sync/ftfw/node1/conntrackd.conf @@ -34,6 +34,28 @@ Sync { IPv4_interface 192.168.100.100 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + # + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf index 59ffc4f..9c26ff5 100644 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ b/doc/sync/ftfw/node2/conntrackd.conf @@ -33,6 +33,28 @@ Sync { IPv4_interface 192.168.100.200 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + # + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/include/mcast.h b/include/mcast.h index c2fd3ec..7c4b1d6 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -19,6 +19,8 @@ struct mcast_conf { unsigned int interface_index6; } ifa; int mtu; + int sndbuf; + int rcvbuf; char iface[IFNAMSIZ]; }; diff --git a/src/mcast.c b/src/mcast.c index f945511..16d8856 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -28,6 +28,7 @@ #include #include #include +#include struct mcast_sock *mcast_server_create(struct mcast_conf *conf) { @@ -37,6 +38,7 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) struct ipv6_mreq ipv6; } mreq; struct mcast_sock *m; + socklen_t socklen = sizeof(int); m = (struct mcast_sock *) malloc(sizeof(struct mcast_sock)); if (!m) @@ -96,6 +98,20 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return NULL; } + if (conf->rcvbuf && + setsockopt(m->fd, SOL_SOCKET, SO_RCVBUFFORCE, &conf->rcvbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + debug("mcast_sock_server_create:setsockopt2"); + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_RCVBUF, &conf->rcvbuf, &socklen); + if (bind(m->fd, (struct sockaddr *) &m->addr, m->sockaddr_len) == -1) { debug("mcast_sock_server_create:bind"); close(m->fd); @@ -195,6 +211,7 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) { int ret; struct mcast_sock *m; + socklen_t socklen = sizeof(int); m = (struct mcast_sock *) malloc(sizeof(struct mcast_sock)); if (!m) @@ -215,6 +232,20 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) return NULL; } + if (conf->sndbuf && + setsockopt(m->fd, SOL_SOCKET, SO_SNDBUFFORCE, &conf->sndbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + debug("mcast_sock_server_create:setsockopt2"); + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_SNDBUF, &conf->sndbuf, &socklen); + switch(conf->ipproto) { case AF_INET: ret = __mcast_client_create_ipv4(m, conf); diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 1350afc..eb3368a 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -104,6 +104,8 @@ ftfw [F|f][T|t][F|f][W|w] "LISTEN" { return T_LISTEN; } "LogFileBufferSize" { return T_STAT_BUFFER_SIZE; } "DestroyTimeout" { return T_DESTROY_TIMEOUT; } +"McastSndSocketBuffer" { return T_MCAST_SNDBUFF; } +"McastRcvSocketBuffer" { return T_MCAST_RCVBUFF; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 0bc5e3c..7fb3d5b 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -53,7 +53,7 @@ struct ct_conf conf; %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT - +%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF %token T_IP T_PATH_VAL %token T_NUMBER @@ -344,6 +344,16 @@ multicast_option : T_GROUP T_NUMBER conf.mcast.port = $2; }; +multicast_option: T_MCAST_SNDBUFF T_NUMBER +{ + conf.mcast.sndbuf = $2; +}; + +multicast_option: T_MCAST_RCVBUFF T_NUMBER +{ + conf.mcast.rcvbuf = $2; +}; + hashsize : T_HASHSIZE T_NUMBER { conf.hashsize = $2; diff --git a/src/sync-mode.c b/src/sync-mode.c index 7d73e2f..ad55adc 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -211,6 +211,9 @@ static int init_sync(void) return -1; } + dlog(LOG_NOTICE, "multicast server socket receiver queue " + "has been set to %d bytes", CONFIG(mcast).rcvbuf); + /* multicast client to send events on the wire */ STATE_SYNC(mcast_client) = mcast_client_create(&CONFIG(mcast)); if (STATE_SYNC(mcast_client) == NULL) { @@ -219,6 +222,9 @@ static int init_sync(void) return -1; } + dlog(LOG_NOTICE, "multicast client socket sender queue " + "has been set to %d bytes", CONFIG(mcast).sndbuf); + if (mcast_buffered_init(&CONFIG(mcast)) == -1) { dlog(LOG_ERR, "can't init tx buffer!"); mcast_server_destroy(STATE_SYNC(mcast_server)); -- cgit v1.2.3