4

I'm trying to change the default socket send buffer size to a small size, in order to see how the UDP throughput gets affected for small UDP datagrams. To do this, I use the setsockopt function with the option SO_SNDBUF and I am trying to set the buffer size to 64 bytes. I also use getsockopt to see the result of the setsockopt function.

Here is the code I use:

int sock_fd;
struct sockaddr_in server_addr;
static int target_port = PORT;
int curr_snd_buff = 0;
int sk_snd_buff = 64;
socklen_t optlen;

if( (sock_fd=socket(AF_INET,SOCK_DGRAM,0)) == -1)
 fatal("in socket (client_udp)");

memset(&server_addr, 0, sizeof(struct sockaddr_in));

server_addr.sin_family = AF_INET;                                                                                          
server_addr.sin_addr.s_addr=inet_addr(args->a_ip);
server_addr.sin_port=htons(target_port); 

if ( sk_snd_buff > 0 )                                                                                                     >{                                                                                                     
  optlen = sizeof(sk_snd_buff);
  // get the default socketh send buffer size
 if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
    fatal("getting the socket send buffer");
  }
  printf("* default socket send buffer: %d\n", curr_snd_buff);
  printf("* attempting to change it to: %d\n", sk_snd_buff);
  if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sk_snd_buff, optlen) == -1) {
    fatal("changing the socket send buffer");
  }
  if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) {
    fatal("getting the socket send buffer");
  }
  printf("* new socket send buffer: %d\n", curr_snd_buff);
}

But, what I see is that there is a lower limit of the buffer size set to 4608 bytes each time I try to set a small value. Here is the output of the above code:

  • default socket send buffer: 212992
  • attempting to change it to: 2304
  • new socket send buffer: 4608

By trying various sizes, I found that this happens for sizes <= 2304. For larger sizes, e.g. 2305, I get a greater size:

  • default socket send buffer: 212992
  • attempting to change it to: 2305
  • new socket send buffer: 4610

and for some greater sizes, e.g. 3000, the doubled of the size that I have requested:

  • default socket send buffer: 212992
  • attempting to change it to: 3000
  • new socket send buffer: 6000

By searching throught the net I found that Linux doubles the value within the kernel when you set it, and returns the doubled value when you query it: Understanding set/getsockopt SO_SNDBUF

Is there a way to reduce the minimum lower limit of the socket send buffer size? E.g., to set it to 64 bytes?

Community
  • 1
  • 1
Thanasis Petsas
  • 4,378
  • 5
  • 31
  • 57
  • 1
    `printf("* attempting to change it to: %d\n", sk_snd_buff);` <- Whoa! Why does this print 2304 if sk_snd_buff was initialized to 64 and not changed after that? Do you have memory corruption somewhere? You should debug that first. – user253751 Mar 30 '15 at 21:30
  • The minimum is fixed to 2048(doubled). The maximum can be set in `/proc/sys/net/core/wmem_max`. I guess the only way to change it is to hack the kernel. – Eugene Sh. Mar 30 '15 at 21:32
  • To supplement the comment written by @immibis what does valgrind say? – autistic Mar 30 '15 at 21:36
  • 1
    I don't see how reducing the socket send buffer size will actually achieve the objective of testing UDP throughput for small datagrams. Just *send* small datagrams. – user207421 Mar 31 '15 at 00:42

1 Answers1

4

The minimum buffer size is a function of the kernel. The Linux docs for option SO_SNDBUF have this to say:

Sets or gets the maximum socket send buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/wmem_default file and the maximum allowed value is set by the /proc/sys/net/core/wmem_max file. The minimum (doubled) value for this option is 2048.

(socket(7) manpage)

Details will likely vary on different systems, but

  1. That explains the doubling you see -- the buffer's capacity for outgoing bytes is the size you set, but the kernel reserves and reports back twice as much space altogether.
  2. On Linux, at least, you are not going to be able to set as small a buffer as you say you want. I would guess that other systems would have constraints of the same order of magnitude.
John Bollinger
  • 160,171
  • 8
  • 81
  • 157