From: Tomas Hozza <thozza@redhat.com>
To: netdev@vger.kernel.org
Subject: SOCK_STREAM TCP: send() returns success even when other side responded with RST packet
Date: Tue, 19 Feb 2013 02:02:12 -0500 (EST) [thread overview]
Message-ID: <20690238.1777611.1361257332454.JavaMail.root@redhat.com> (raw)
In-Reply-To: <79866921.1777178.1361257053436.JavaMail.root@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2133 bytes --]
Hi.
I was advised to forward my networking Kernel related Bug here
so it can get fixed much faster. Here is the Bug description
copied from Red Hat Bugzilla (https://bugzilla.redhat.com/show_bug.cgi?id=912382):
Description of problem:
I'm using SOCK_STREAM TCP sockets. Imagine server-client application.
- Server will accept connection from client.
- Client sends some data to server -> server receives data.
- Client then half-closes the TCP connection using shutdown(fd, SHUT_WR).
- Client waits for some data from the server.
- Server sends some data to client -> client receives data.
- Client exits and closes the socket.
- After some time server tries to send some data to the client.
- The first send() call returns success even the Client's response is RST.
Version-Release number of selected component (if applicable):
3.7.7-201.fc18.x86_64
3.7.8-202.fc18.x86_64
How reproducible:
always
Steps to Reproduce:
1. download attached client/server sources.
2. compile server: # gcc tcp_server.c -o server
3. compile client: # gcc tcp_client.c -o client
4. run the server: # ./server
5. run the client: # ./client
Actual results:
Server started...
Created SOCK_STREAM socket
Bound to localhost:6666
waiting for connection...
Client connected!
Waiting for some data from client
Received: "MSG from client"
Received EOF
Sending msg to client: "MSG from server"
sleep(5)
Sending 1 msg to client: "MSG from server"
try #1 send() result: (0) Success
Sending 2 msg to client: "MSG from server"
try #2 send() result: (32) Broken pipe
Server exiting...
Expected results:
Server should fail to send() data right after sleep().
Server started...
Created SOCK_STREAM socket
Bound to localhost:6666
waiting for connection...
Client connected!
Waiting for some data from client
Received: "MSG from client"
Received EOF
Sending msg to client: "MSG from server"
sleep(5)
Sending 1 msg to client: "MSG from server"
try #1 send() result: (32) Broken pipe
Server exiting...
Additional info:
RST answer means that data were NOT delivered. Therefore the very
first send() call after server sleep() should fail!
Regards,
Tomas Hozza
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tcp_server.c --]
[-- Type: text/x-csrc; name=tcp_server.c, Size: 2474 bytes --]
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
int main(int argc, char **argv)
{
int ssock, csock, i;
static char buff[256];
ssize_t nbytes;
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6666);
signal(SIGPIPE, SIG_IGN);
printf("Server started...\n");
if ((ssock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket() error. (%d) %s\n", errno, strerror(errno));
exit(1);
}
printf("Created SOCK_STREAM socket\n");
if (bind(ssock, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
printf("bind() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Bound to localhost:6666\n");
if (listen(ssock, 1) == -1) {
printf("listen() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("waiting for connection...\n");
csock = accept(ssock, NULL, NULL);
if (csock == -1) {
printf("accept() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Client connected!\n");
printf("Waiting for some data from client\n");
while ((nbytes = recv(csock, buff, sizeof(buff), 0)) > 0) {
printf("Received: \"%s\"\n", buff);
}
if (nbytes < 0) {
printf("recv() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
close(csock);
exit(1);
} else if (nbytes == 0) {
printf("Received EOF\n");
printf("Sending msg to client: \"MSG from server\"\n");
if ((nbytes = send(csock, "MSG from server", sizeof("MSG from server"), 0)) <= 0) {
printf("send() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
close(csock);
exit(1);
}
}
printf("sleep(5)\n");
sleep(5);
i = 1;
while (1) {
printf("Sending %d msg to client: \"MSG from server\"\n", i);
nbytes = send(csock, "MSG from server", sizeof("MSG from server"), 0);
printf("try #%d send() result: (%d) %s\n",i ,errno, strerror(errno));
if (nbytes <= 0)
break;
++i;
}
printf("Server exiting...\n");
close(ssock);
close(csock);
return 0;
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: tcp_client.c --]
[-- Type: text/x-csrc; name=tcp_client.c, Size: 1694 bytes --]
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
int ssock, i;
static char buff[256];
ssize_t nbytes;
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6666);
printf("Client started...\n");
if ((ssock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket() error. (%d) %s\n", errno, strerror(errno));
exit(1);
}
printf("Created SOCK_STREAM socket\n");
if (connect(ssock, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) {
printf("connect() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Connected to the server!\n");
printf("Sending some data to server\n");
if ((nbytes = send(ssock, "MSG from client", sizeof("MSG from client"), 0)) <= 0) {
printf("send() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Half-closing connection with shutdown(ssock, SHUT_WR)\n");
if (shutdown(ssock, SHUT_WR) == -1) {
printf("shutdown() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Receiving data from server\n");
if ((nbytes = recv(ssock, buff, sizeof(buff), 0)) > 0) {
printf("Received: \"%s\"\n", buff);
} else {
printf("recv() error. (%d) %s\n", errno, strerror(errno));
close(ssock);
exit(1);
}
printf("Client exiting...\n");
close(ssock);
return 0;
}
next parent reply other threads:[~2013-02-19 7:02 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <79866921.1777178.1361257053436.JavaMail.root@redhat.com>
2013-02-19 7:02 ` Tomas Hozza [this message]
2013-02-19 14:51 ` SOCK_STREAM TCP: send() returns success even when other side responded with RST packet Eric Dumazet
2013-02-19 15:09 ` Tomas Hozza
2013-02-19 15:26 ` Stephen Hemminger
2013-02-19 15:27 ` Eric Dumazet
2013-02-19 15:46 ` Tomas Hozza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20690238.1777611.1361257332454.JavaMail.root@redhat.com \
--to=thozza@redhat.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.