c - Configuring TCP keepalive after accept -


after accept() on socket, i'm trying configure tcp keepalive.

sockconnected = accept(socklisten, &remoteaddr,                    &remotelen); /* bit of checking goes here */ if (setsockopt (sockconnected , sol_socket, so_keepalive,                             (st_char *) &sockopt_on, sizeof (int) ) ) {    /* error logging */ }  if (setsockopt(sockconnected , ipproto_tcp, tcp_keepidle, (char*)&(sockopt_tcp_keep_idle), sizeof(sockopt_tcp_keep_idle))) {     /* error logging */ } if (setsockopt(sockconnected, ipproto_tcp, tcp_keepintvl, (char*)&(sockopt_tcp_keep_intvl), sizeof(sockopt_tcp_keep_intvl))) {     /* error logging */ } if (setsockopt(sockconnected, ipproto_tcp, tcp_keepcnt, (char*)&(sockopt_tcp_keep_cnt), sizeof(sockopt_tcp_keep_cnt))) {     /* error logging */ } 

after calling getsockopt() 4 properties, seems alright. i've checked in wireshark , there no keep alive packets being sent. had change sol_tcp ipproto_tcp, because when calling setsockopt() tcp_keepidle returning errno 92 (protocol not found).

i'm doing same thing after calling socket() outgoing connection, , it's working perfectly.

i'm using c , linux.

is there reason why setsockopt may not working after accept?

here minimal working example. if works you, can use reference.

#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/signal.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/tcp.h>  #define check(expr) if (!(expr)) { perror(#expr); kill(0, sigterm); }  void enable_keepalive(int sock) {     int yes = 1;     check(setsockopt(sock, sol_socket, so_keepalive, &yes, sizeof(int)) != -1);      int idle = 1;     check(setsockopt(sock, ipproto_tcp, tcp_keepidle, &idle, sizeof(int)) != -1);      int interval = 1;     check(setsockopt(sock, ipproto_tcp, tcp_keepintvl, &interval, sizeof(int)) != -1);      int maxpkt = 10;     check(setsockopt(sock, ipproto_tcp, tcp_keepcnt, &maxpkt, sizeof(int)) != -1); }  int main(int argc, char** argv) {     check(argc == 2);      struct sockaddr_in addr;     addr.sin_family = af_inet;     addr.sin_port = htons(12345);     check(inet_pton(af_inet, argv[1], &addr.sin_addr) != -1);      int server = socket(af_inet, sock_stream, ipproto_tcp);     check(server != -1);      int yes = 1;     check(setsockopt(server, sol_socket, so_reuseaddr, &yes, sizeof(int)) != -1);      check(bind(server, (struct sockaddr*)&addr, sizeof(addr)) != -1);     check(listen(server, 1) != -1);      if (fork() == 0) {         int client = socket(af_inet, sock_stream, ipproto_tcp);         check(client != -1);         check(connect(client, (struct sockaddr*)&addr, sizeof(addr)) != -1);         printf("connected\n");         pause();     }     else {         int client = accept(server, null, null);         check(client != -1);         enable_keepalive(client);         printf("accepted\n");         wait(null);     }      return 0; } 

example output (tcpdump reports keepalive packets every second):

$ ./a.out 127.0.0.1 & [1] 14010 connected accepted  $ tcpdump -n -c4 -ilo port 12345 dropped privs tcpdump tcpdump: verbose output suppressed, use -v or -vv full protocol decode listening on lo, link-type en10mb (ethernet), capture size 262144 bytes 18:00:35.173892 ip 127.0.0.1.12345 > 127.0.0.1.60998: flags [.], ack 510307430, win 342, options [nop,nop,ts val 389745775 ecr 389745675], length 0 18:00:35.173903 ip 127.0.0.1.60998 > 127.0.0.1.12345: flags [.], ack 1, win 342, options [nop,nop,ts val 389745775 ecr 389745075], length 0 18:00:36.173886 ip 127.0.0.1.12345 > 127.0.0.1.60998: flags [.], ack 1, win 342, options [nop,nop,ts val 389745875 ecr 389745775], length 0 18:00:36.173898 ip 127.0.0.1.60998 > 127.0.0.1.12345: flags [.], ack 1, win 342, options [nop,nop,ts val 389745875 ecr 389745075], length 0 4 packets captured 8 packets received filter 0 packets dropped kernel 

Comments