Commit af30db04 authored by Robert Ricci's avatar Robert Ricci

If the environment variable LIBNETMON_SOCKBUFSIZE is set, force

the socket buffer to be that size (in bytes) by setting it ourselves,
and not letting the caller change it.
parent 62efd41a
......@@ -17,6 +17,7 @@ void croak(char *format, ...) {
fprintf(stderr,"*** ERROR\n libnetmon: ");
vfprintf(stderr,format, ap);
va_end(ap);
fflush(stderr);
exit(1);
}
......@@ -54,6 +55,7 @@ void lnm_init() {
FIND_REAL_FUN(connect);
FIND_REAL_FUN(write);
FIND_REAL_FUN(send);
FIND_REAL_FUN(setsockopt);
sockpath = getenv("LIBNETMON_SOCKPATH");
if (sockpath) {
......@@ -87,6 +89,18 @@ void lnm_init() {
outstream = stdout;
}
char *bufsize_s;
if ((bufsize_s = getenv("LIBNETMON_SOCKBUFSIZE"))) {
if (sscanf(bufsize_s,"%i",&forced_bufsize) == 1) {
printf("libnetmon: Forcing socket buffer size %i\n",
forced_bufsize);
} else {
croak("Bad sockbufsize: %s\n",bufsize_s);
}
} else {
forced_bufsize = 0;
}
intialized = true;
} else {
/* DEBUG(printf("Skipping intialization\n")); */
......@@ -202,7 +216,7 @@ void log_packet(int fd, size_t len) {
* gettimeofday()
*/
if (gettimeofday(&time,NULL)) {
croak("Error in gettimeofday()");
croak("Error in gettimeofday()\n");
}
/*
fprintf(stderr,"%lu.%08lu [%i, %i]\n",time.tv_sec, time.tv_usec, fd,len);
......@@ -277,6 +291,23 @@ int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) {
* Note: The kernel already verified for us that the pointer is okay
*/
startFD(sockfd,serv_addr);
/*
* We may have been asked to force the socket buffer size
*/
if (forced_bufsize) {
int sso_rv;
sso_rv = real_setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,
&forced_bufsize, sizeof(forced_bufsize));
if (sso_rv == -1) {
croak("Unable to force out buffer size: %s\n",strerror(errno));
}
sso_rv = real_setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,
&forced_bufsize, sizeof(forced_bufsize));
if (sso_rv == -1) {
croak("Unable to force in buffer size: %s\n",strerror(errno));
}
}
} else {
/*
* Do this in case they called connect() to reconnect a previously
......@@ -359,3 +390,28 @@ ssize_t write(int fd, const void *buf, size_t count) {
return rv;
}
int setsockopt (int s, int level, int optname, const void *optval,
socklen_t optlen) {
lnm_init();
DEBUG(printf("setsockopt called (%i,%i)\n",level,optname));
/*
* Note, we do this on all sockets, not just those we are currently
* monitoring, since it's likely they'll call setsockopt() before
* connect()
*/
if (forced_bufsize && (level == SOL_SOCKET) && ((optname == SO_SNDBUF) ||
(optname == SO_RCVBUF))) {
/*
* I believe this is the right thing to do - return success but don't
* do anything - I think that this is what you normally get when you,
* say, pick a socket buffer size that is too big.
*/
printf("Warning: Ignored attempt to change SO_SNDBUF or SO_RCVBUF\n");
return 0;
} else {
return real_setsockopt(s,level,optname,optval,optlen);
}
}
......@@ -91,6 +91,11 @@ static unsigned int fdSize;
*/
FILE *outstream;
/*
* Force the socket buffer size
*/
int forced_bufsize;
/*
* Manipulate the monitorFDs structure
*/
......@@ -108,6 +113,7 @@ typedef int close_proto_t(int);
typedef int connect_proto_t(int, const struct sockaddr*, socklen_t);
typedef ssize_t write_proto_t(int, const void *, size_t);
typedef ssize_t send_proto_t(int, const void *, ssize_t, int);
typedef int setsockopt_proto_t(int, int, int, const void*, socklen_t);
/*
* Locations of the real library functions
......@@ -117,6 +123,7 @@ static close_proto_t *real_close;
static connect_proto_t *real_connect;
static write_proto_t *real_write;
static send_proto_t *real_send;
static setsockopt_proto_t *real_setsockopt;
/*
* Note: Functions that we're wrapping are in the .c file
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment