Use setsockopt() to modify kernel structures in TCP?

Viewed 427

Is it possible to modify a single member of a kernel struct in TCP? I want to be able to use setsockopt() to update a member of the tcp_info struct in TCP.

I've tried the following:

struct tcp_info info;
unsigned int optlen = sizeof(struct tcp_info);

if (getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, &optlen) < 0)
  printf("Can't get data from getsockopt.\n");

info.retransmits += 10; // random member of tcp_info - as example

if (setsockopt(sock, IPPROTO_TCP, TCP_INFO, (char *) &info, optlen) < 0)
  printf("Can't set data with setsockopt.\n");

The call to setsockopt() fails (returns a negative value).

The way I'm trying to solve it (above), given that it had worked - doesn't seem optimal. Is it possible to modify a members value from a struct, without having to fetch and update the entire struct (all of its members)?

1 Answers

You may not set arbitrary values with setsockopt(). It has a finite list of options you may set.

I'll use the FreeBSD kernel in this example, but all of this is similar if not identical in Linux. I will jump to FreBSD's sosetopt() function in sys/kern/uipc_socket.c.

The only valid options you may set are:

SO_ACCEPTFILTER, SO_LINGER, SO_DEBUG, SO_KEEPALIVE, SO_DONTROUTE, SO_USELOOPBACK, SO_BROADCAST, SO_REUSEADDR, SO_REUSEPORT, SO_REUSEPORT_LB, SO_OOBINLINE, SO_TIMESTAMP, SO_BINTIME, SO_NOSIGPIPE, SO_NO_DDP, SO_NO_OFFLOAD, SO_RERROR, SO_SETFIB, SO_USER_COOKIE, SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT, SO_RCVLOWAT, SO_SNDTIMEO, SO_RCVTIMEO, SO_LABEL, SO_TS_CLOCK, and SO_MAX_PACING_RATE.

That list contain a number of status flags, enabling or disabling features. There are only a few that allow setting of numerical values.

  • SO_USER_COOKIE - set a user-specified metadata value to a socket.
  • SO_SNDBUF/SO_RCVBUF - set the allocated buffer sizes for sending and receiving.
  • SO_SNDLOWAT/SO_RCVLOWAT - set a minimum amount of data to be sent/received per call.
  • SO_SNDTIMEO/SO_RCVTIMEO - set a timeout for sending/receiving calls.
  • SO_MAX_PACING_RATE - Instructs the network adapter to limit the transfer rate.

None of these write values directly to kernel structures. To accomplish something of the sort you have request, you will need to modify the kernel. Your other question addresses that objective.

Related