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
Post a Comment