[netflow-tools] Patch to allow explicit specification of SO_SNDBUF and SO_RCVBUF
Jesse Kempf
kempfj2 at cs.rpi.edu
Wed Oct 24 05:37:04 EST 2007
I've inlined the diff at the bottom of the email.
In short, this patch makes it possible to specify the receive buffer size for each ``listen on'' directive, and the send buffer size for ``logsock''.
There's some receive buffer guessing for listening sockets already, but I figured it would be more helpful (and more precise) to let the administrator explicitly tune the values. Well, that and I just had need to take a crack at tuning these values.
Cheers,
-Jesse Kempf
Index: flowd-bufsiz/parse.y
===================================================================
--- flowd-bufsiz/parse.y (revision 173)
+++ flowd-bufsiz/parse.y (revision 177)
@@ -102,7 +102,7 @@
%}
-%token LISTEN ON JOIN GROUP LOGFILE LOGSOCK STORE PIDFILE FLOW SOURCE
+%token LISTEN ON JOIN GROUP LOGFILE LOGSOCK BUFSIZE STORE PIDFILE FLOW SOURCE
%token ALL TAG ACCEPT DISCARD QUICK AGENT SRC DST PORT PROTO TOS ANY
%token TCP_FLAGS EQUALS MASK INET INET6 DAYS AFTER BEFORE DATE
%token IN_IFNDX OUT_IFNDX
@@ -385,8 +385,22 @@
la->fd = -1;
la->addr = $3.addr;
la->port = $3.port;
+ la->bufsiz = 0;
TAILQ_INSERT_TAIL(&conf->listen_addrs, la, entry);
}
+ | LISTEN ON address_port BUFSIZE number {
+ struct listen_addr *la;
+
+ if ((la = calloc(1, sizeof(*la))) == NULL)
+ logerrx("listen_on: calloc");
+
+ la->fd = -1;
+ la->addr = $3.addr;
+ la->port = $3.port;
+ la->bufsiz = $5;
+ TAILQ_INSERT_TAIL(&conf->listen_addrs, la, entry);
+
+ }
| FLOW SOURCE prefix_or_any {
struct allowed_device *ad;
@@ -414,6 +428,10 @@
| LOGSOCK string {
conf->log_socket = $2;
}
+ | LOGSOCK string BUFSIZE number {
+ conf->log_socket = $2;
+ conf->log_socket_bufsiz = $4;
+ }
| PIDFILE string {
conf->pid_file = $2;
}
@@ -902,6 +920,7 @@
{ "all", ALL},
{ "any", ANY},
{ "before", BEFORE},
+ { "bufsize", BUFSIZE},
{ "date", DATE},
{ "days", DAYS},
{ "discard", DISCARD},
Index: flowd-bufsiz/flowd.c
===================================================================
--- flowd-bufsiz/flowd.c (revision 173)
+++ flowd-bufsiz/flowd.c (revision 177)
@@ -1365,7 +1365,7 @@
struct listen_addr *la;
TAILQ_FOREACH(la, &conf->listen_addrs, entry) {
- if ((la->fd = open_listener(&la->addr, la->port,
+ if ((la->fd = open_listener(&la->addr, la->port, la->bufsiz,
&conf->join_groups)) == -1) {
logerrx("Listener setup of [%s]:%d failed",
addr_ntop_buf(&la->addr), la->port);
Index: flowd-bufsiz/flowd.h
===================================================================
--- flowd-bufsiz/flowd.h (revision 173)
+++ flowd-bufsiz/flowd.h (revision 177)
@@ -55,6 +55,7 @@
struct xaddr addr;
u_int16_t port;
int fd;
+ size_t bufsiz;
TAILQ_ENTRY(listen_addr) entry;
};
TAILQ_HEAD(listen_addrs, listen_addr);
@@ -72,6 +73,7 @@
struct flowd_config {
char *log_file;
char *log_socket;
+ size_t log_socket_bufsiz;
char *pid_file;
u_int32_t store_mask;
u_int32_t opts;
Index: flowd-bufsiz/flowd.conf.5.in
===================================================================
--- flowd-bufsiz/flowd.conf.5.in (revision 173)
+++ flowd-bufsiz/flowd.conf.5.in (revision 177)
@@ -135,7 +135,20 @@
listen on [::]:12345
.Ed
.Pp
-This option is mandatory, there is no default value.
+
+This option accepts the modifier
+.Pa bufsize
+to allow the specification (in bytes) of the receive buffer for this socket.
+.Pp
+For example,
+.Bd -literal -offset indent
+listen on 0.0.0.0:12345 bufsize 9876
+.Ed
+.Pp
+The
+.Cm listen on
+directive is mandatory. There is no default value.
+
.It Ar logfile
Specifies the file in which the received flow records are stored.
The full path to the file must be specified in quotes.
@@ -161,7 +174,18 @@
logsock "/var/log/flowd.sock"
.Ed
.Pp
-There is no default value for this option and it it mandatory
+This option accepts the modifier
+.Pa bufsize
+to allow the specification (in bytes) of the send buffer for this socket.
+.Pp
+For example,
+.Bd -literal -offset indent
+logsock "/var/log/flowd.sock" bufsize 1234
+.Ed
+.Pp
+There is no default value for
+.Cm logfile
+and it is mandatory
to specify at least one of the
.Cm logfile
and
Index: flowd-bufsiz/privsep.c
===================================================================
--- flowd-bufsiz/privsep.c (revision 173)
+++ flowd-bufsiz/privsep.c (revision 177)
@@ -119,7 +119,7 @@
}
int
-open_listener(struct xaddr *addr, u_int16_t port, struct join_groups *groups)
+open_listener(struct xaddr *addr, u_int16_t port, size_t bufsiz, struct join_groups *groups)
{
int fd, fl, i, orig;
struct sockaddr_storage ss;
@@ -167,10 +167,23 @@
logit(LOG_DEBUG, "Listener for [%s]:%d fd = %d", addr_ntop_buf(addr),
port, fd);
- /* Crank up socket receive buffer size to cope with bursts of flows */
+ /* Crank up socket receive buffer size to cope with bursts of flows
+ * If the config doesn't contain an explicit buffer size, we
+ * fall back to guessing.
+ */
+
slen = sizeof(fl);
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &orig, &slen) == 0) {
- for (i = 3; i >= 1; i--) {
+ if (bufsiz > 0) {
+ fl = bufsiz;
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
+ &bufsiz, sizeof(bufsiz)) == 0) {
+ logit(LOG_DEBUG, "Increased socket receive "
+ "buffer from %d to %d", orig, fl);
+ } else if (i == 1)
+ logerr("%s: setsockopt(SO_RCVBUF)", __func__);
+ } else{
+ for (i = 3; i >= 1; i--) {
fl = (1024 * 64) << i;
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &fl,
sizeof(fl)) == 0) {
@@ -179,6 +192,7 @@
break;
} else if (i == 1)
logitm(LOG_DEBUG, "setsockopt(SO_RCVBUF)");
+ }
}
}
@@ -300,6 +314,13 @@
newconf.log_file = privsep_read_string(fd, 1);
newconf.log_socket = privsep_read_string(fd, 1);
+ if (atomicio(read, fd, &newconf.log_socket_bufsiz,
+ sizeof(newconf.log_socket_bufsiz)) !=
+ sizeof(newconf.log_socket_bufsiz)) {
+ logitm(LOG_ERR, "%s: read(conf.log_socket_bufsiz)", __func__);
+ return (-1);
+ }
+
if ((newconf.pid_file = privsep_read_string(fd, 0)) == NULL) {
logit(LOG_ERR, "%s: Couldn't read conf.pid_file", __func__);
return (-1);
@@ -431,6 +452,13 @@
logit(LOG_ERR, "%s: Couldn't write conf.log_socket", __func__);
return (-1);
}
+ if (atomicio(vwrite, fd, &conf->log_socket_bufsiz,
+ sizeof(conf->log_socket_bufsiz)) !=
+ sizeof(conf->log_socket_bufsiz)) {
+ logitm(LOG_ERR, "%s: write(conf.log_socket_bufsiz)", __func__);
+ return (-1);
+ }
+
if (privsep_write_string(fd, conf->pid_file, 0) == -1) {
logit(LOG_ERR, "%s: Couldn't write conf.pid_file", __func__);
return (-1);
@@ -581,7 +609,7 @@
FILE *cfg;
struct passwd *pw = NULL;
struct flowd_config newconf = {
- NULL, NULL, NULL, 0, 0,
+ NULL, NULL, 0, NULL, 0, 0,
TAILQ_HEAD_INITIALIZER(newconf.listen_addrs),
TAILQ_HEAD_INITIALIZER(newconf.filter_list),
TAILQ_HEAD_INITIALIZER(newconf.allowed_devices),
@@ -786,7 +814,7 @@
static int
answer_open_socket(struct flowd_config *conf, int client_fd)
{
- int fd;
+ int fd, slen, orig;
struct sockaddr_un to;
socklen_t tolen;
@@ -816,6 +844,20 @@
return (-1);
}
+ slen = sizeof(orig);
+ if (conf->log_socket_bufsiz > 0 &&
+ getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &orig, &slen) == 0) {
+
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+ &conf->log_socket_bufsiz,
+ sizeof(conf->log_socket_bufsiz)) == 0) {
+ logit(LOG_DEBUG, "Increased log_socket send "
+ "buffer from %d to %d", orig,
+ conf->log_socket_bufsiz);
+ } else
+ logerr("%s: setsockopt(SO_SNDBUF)", __func__);
+ }
+
if (send_fd(client_fd, fd) == -1)
return (-1);
@@ -850,7 +892,7 @@
}
TAILQ_FOREACH(la, &newconf.listen_addrs, entry) {
- if ((la->fd = open_listener(&la->addr, la->port,
+ if ((la->fd = open_listener(&la->addr, la->port, la->bufsiz,
&conf->join_groups)) == -1) {
logit(LOG_ERR, "Listener setup of [%s]:%d failed",
addr_ntop_buf(&la->addr), la->port);
Index: flowd-bufsiz/privsep.h
===================================================================
--- flowd-bufsiz/privsep.h (revision 173)
+++ flowd-bufsiz/privsep.h (revision 177)
@@ -27,7 +27,7 @@
void privsep_init(struct flowd_config *, int *, const char *);
int client_open_log(int);
int client_open_socket(int);
-int open_listener(struct xaddr *, u_int16_t, struct join_groups *);
+int open_listener(struct xaddr *, u_int16_t, size_t, struct join_groups *);
int read_config(const char *, struct flowd_config *);
int client_reconfigure(int, struct flowd_config *);
More information about the netflow-tools
mailing list