NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/56346: Listening socket instantly closes if TCP_KEEPALIVE options are set on the server side
>Number: 56346
>Category: kern
>Synopsis: Listening socket instantly closes if TCP_KEEPALIVE options are set on the server side
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Aug 02 07:55:00 +0000 2021
>Originator: Szilard Parrag
>Release: 9.2
>Organization:
>Environment:
NetBSD localhost 9.2 NetBSD 9.2 (GENERIC) #0: Wed May 12 13:15:55 UTC 2021 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
When exectuing the following code the listening socket closes after setting TCP_KEEPALIVE options. This does not happen on Linux, as the values are inherited by the clients/peers.
>How-To-Repeat:
Run the following program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <netinet/tcp.h>
void setsockopt_or_fail(int socket, int level, int options_name, const void *option_value, socklen_t option_len){
int retval = setsockopt(socket, level, options_name, option_value, option_len);
if(retval < 0){
perror("setter failed");
exit(1);
}
}
int main(){
//socket prep
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server = {0};
server.sin_addr.s_addr = INADDR_ANY;
server.sin_family = AF_INET;
server.sin_port = htons(4442);
int on = 1;
setsockopt_or_fail(sockfd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
unsigned int a = 10;
setsockopt_or_fail(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &a, sizeof(a));
a = 3;
setsockopt_or_fail(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &a, sizeof(a));
a = 1;
setsockopt_or_fail(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &a, sizeof(a));
//bind
if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0){
perror("bind error");
exit(1);
}
//listen
if(listen(sockfd, 10) < 0){
perror("listen error");
exit(1);
}
printf("we are listening\n");
// accept
for(;;){
int clientfd = accept(sockfd, NULL, NULL);
if(clientfd < 0){
perror("error during accept");
exit(1);
}
printf("accepted\n");
char buff[50];
while(1){
int retval = read(clientfd, &buff, sizeof(buff));
if(retval == 0){
printf("Connection has finished\n");
break;
}
else if(retval < 0){
perror("error reading socket");
exit(1);
}
}
close(clientfd);
}
close(sockfd);
}
>Fix:
Home |
Main Index |
Thread Index |
Old Index