Connection abort before accept returns :
Similar to interrupted system call, a non fatal error occurs when the client is reset after three handshake without transfer of any packet.
the three way handshake, the connection is established and then the client TCP
sends an RST (reset). ON the server side the connection is queued by its TCP
waiting for the server process to call accept when the RST arrives. Some time
later the server process calls accept.
happens to aborted connection depends on the type of implementation . The
Berkley derived implementation handles the aborted connection completely within
the kernal and the server process never sees it. Most of the SVR4 (System V
release 4) implementation returns an error to the process as the return from accept and the type of error depends on
the implementation. Most implementation returns an errono EPROTO ( protocol error) but posix .1g specifies that the
return must be ECONNABORTED (―software
caused connection abort‖). The reason for this is that
EPROTO is also returned when some fatal protocol related event occurs on the
bytestream. Receiving the same error EPROTO by the server makes it difficult to
decide whether to call accept again
or not. IN case of ECONNABORTED error, the4 server ignores the error and just
call accept again.
Termination of Server Process:
starting client – server, the child process is killed at the server ( kill the
child process based on the its ID ). This simulates the crashing of the server
process, then what happens to client: The following steps take place.
1. We start the server and client on different
hosts and type one line to the client to verify that all is OK. That line is
echoed normally by the server child.
2. Identify the process ID of the server child and
kill it. As part of the process termination, all open descriptors in the child
are closed. This causes the FIN to by sent to the client and the client TCP
responds with an ACK. This is the first half of the TCP connection termination.
3. The SIGCHLD signal is sent to the server parent
and handled correctly.
4. Nothing happens at the client. The client
receives the FIN from the sever TCP and responds with an ACK. But the problem
is that the client process is blocked in the call to the fgets waiting for a line form the terminal.
5. When we type another line, str_cli calls
written and the client TCP sends the data to the sever. This is allowed by TCP
because the receipt of the FIN by the client TCP only indicates that the server
process has closed its end of the connection and will not send any more data.
The receipt of FIN does not tell the client that the server process has
terminated (which in this case it has).
6. When the server TCP receives the data from the
client, it responds with an RST since the process that had that socket open has
terminated. We can verify that the RST is sent by watching the packets with tcpdump
7. But the client process will not see the RST
because it calls readline immediately a after the call to writen and readline
returns 0 (end of line) immediately because of the FIN that was received inIT2351-NPM/
U-2/ 12 step 2. Our client is not expecting to receive an end of line at this
point so it quits with an error message server terminated prematurely.―
8. So when
the client terminates ( by calling err_quit), all its open descriptors are
The problem in this example is that the client blocked in the call
to fgets when the FIN arrives on the socket. The client is really working with
the two descriptors - the socket and the user input - and instead of blocking
on input from any one of the two sources, it should block on input from either
source. This is the function of select and poll function .
client has more than one to write, what happens to it? That is when the FIN is
received, the readline returns RST, but the second one is also written. The
rule applied here is, when a process writes to a socket that has received an
RST, the SIGPIPE signal is sent to the process. The default action of this
signal is to terminate the process so the process must catch the signal to
avoid involuntarily terminated.
process catches the signal and returns from the signal handler, or ignores the
signal, the write operation returns EPIPE (error pipe)
void str_cli (FILE *fp, int sockfd)
sendline[MAXLINE], recvline[MAXLINE]; while (fgets(sendline, MAXLINE,
writen(sockfd, sendline, 1); sleep(1);
(sockfd, sendline +1, strlen (sendline)-1); if (readline()sockfd, recvline,
(―str_cli: server terminated prematurely‖); fputs
above str_cli(), the writen is called two times: the first time the first byte
of data is writen to the socket, followed by a pause of 1 sec, followed by the
remainder of the line. The intention is for the first writen to elicit the RST
and then for the second writen to generate SIGPIPE.
with the client, type in one line, see that line is echoed correctly, and then
terminates the server child on the server host, we then type another line, but
nothing is echoed and we just get a shell Prompt. Since the default action of
the SIGPIPE is to terminate the process without generating a core file, nothing
is printed by the Kornshell.
recommended way to handle SIGPIPE depends on what the application what to do when
this occurs. IF there is nothing special to do, then setting the signal
disposition to SIG_IGN is easy, assuming that subsequent output operations will
catch the error of EPIPE and terminate.
special actions are needed when the signal occurs, then the signal should be
caught and any desired actions can be performed in the signal handler.
multiple sockets are in use, the delivery of the signal does not tell us which
socket encountered the error. IF we need to know which write caused the error,
then we must either ignore the signal or return from the signal handler and
handle EPIPE from write