• Aucun résultat trouvé

Figure 5.13. Receiving an RST for an ESTABLISHED connection before accept is called

Here, the three-way handshake completes, 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. Sometime later, the server process calls accept.

An easy way to simulate this scenario is to start the server, have it call socket, bind, and listen, and then go to sleep for a short period of time before calling accept. While the server process is asleep, start the client and have it call socket and connect. As soon as connect returns, set the SO_LINGER socket option to generate the RST (which we will describe in Section 7.5 and show an example of in Figure 16.21) and terminate.

Unfortunately, what happens to the aborted connection is implementation-dependent.

Berkeley-derived implementations handle the aborted connection completely within the kernel, and the server process never sees it. Most SVR4 implementations, however, return an error to the process as the return from accept, and the error depends on the implementation. These SVR4 implementations return an errno of EPROTO ("protocol error"), but POSIX specifies that the return must be ECONNABORTED ("software caused connection abort") instead. The reason for the POSIX change is that EPROTO is also returned when some fatal protocol-related events occur on the streams subsystem. Returning the same error for the nonfatal abort of an

established connection by the client makes it impossible for the server to know whether to call accept again or not. In the case of the ECONNABORTED error, the server can ignore the error and just call accept again.

The steps involved in Berkeley-derived kernels that never pass this error to the process can be followed in TCPv2. The RST is processed on p. 964, causing tcp_close to be called. This function calls in_pcbdetach on p. 897, which in turn calls sofree on p. 719.

sofree (p. 473) finds that the socket being aborted is still on the listening socket's completed connection queue and removes the socket from the queue and frees the socket. When the server gets around to calling accept, it will never know that a

[ Team LiB ]

Table of Contents

UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API

By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff

Publisher: Addison Wesley Pub Date: November 21, 2003

ISBN: 0-13-141155-1 Pages: 1024

"Everyone will want this book because it provides a great mix of practical experience, historical perspective, and a depth of understanding that only comes from being intimately involved in the field. I've already enjoyed and learned from reading this book, and surely you will too."

-Sam Leffler

The classic guide to UNIX networking APIs... now completely updated!

To build today's highly distributed, networked applications and services, you need deep

mastery of sockets and other key networking APIs. One book delivers comprehensive, start-to-finish guidance for building robust, high-performance networked systems in any environment:

UNIX Network Programming, Volume 1, Third Edition.

Building on the legendary work of W. Richard Stevens, this edition has been fully updated by two leading network programming experts to address today's most crucial standards, implementations, and techniques. New topics include:

POSIX Single UNIX Specification Version 3

IPv6 APIs (including updated guidance on IPv6/IPv4 interoperability) The new SCTP transport protocol

IPsec-based Key Management Sockets

FreeBSD 4.8/5.1, Red Hat Linux 9.x, Solaris 9, AIX 5.x, HP-UX, and Mac OS X implementations

New network program debugging techniques

Source Specific Multicast API, the key enabler for widespread IP multicast deployment connection that was completed has since been removed from the queue.

We will return to these aborted connections in Section 16.6 and see how they can present a problem when combined with select and a listening socket in the normal blocking mode.

[ Team LiB ]

[ Team LiB ]

Table of Contents

UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API

By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff

Publisher: Addison Wesley Pub Date: November 21, 2003

ISBN: 0-13-141155-1 Pages: 1024

"Everyone will want this book because it provides a great mix of practical experience, historical perspective, and a depth of understanding that only comes from being intimately involved in the field. I've already enjoyed and learned from reading this book, and surely you will too."

-Sam Leffler

The classic guide to UNIX networking APIs... now completely updated!

To build today's highly distributed, networked applications and services, you need deep

mastery of sockets and other key networking APIs. One book delivers comprehensive, start-to-finish guidance for building robust, high-performance networked systems in any environment:

UNIX Network Programming, Volume 1, Third Edition.

Building on the legendary work of W. Richard Stevens, this edition has been fully updated by two leading network programming experts to address today's most crucial standards, implementations, and techniques. New topics include:

POSIX Single UNIX Specification Version 3

IPv6 APIs (including updated guidance on IPv6/IPv4 interoperability) The new SCTP transport protocol

IPsec-based Key Management Sockets

FreeBSD 4.8/5.1, Red Hat Linux 9.x, Solaris 9, AIX 5.x, HP-UX, and Mac OS X implementations

New network program debugging techniques

Source Specific Multicast API, the key enabler for widespread IP multicast deployment [ Team LiB ]

5.12 Termination of Server Process

We will now start our client/server and then kill the server child process. This simulates the crashing of the server process, so we can see what happens to the client. (We must be careful to distinguish between the crashing of the server process, which we are about to describe, and the crashing of the server host, which we will describe in Section 5.14.) The following steps take place:

We start the server and client and type one line to the client to verify that all is okay. That line is echoed normally by the server child.

1.

We find the process ID of the server child and kill it. As part of process termination, all open descriptors in the child are closed. This causes a FIN to be sent to the client, and the client TCP responds with an ACK. This is the first half of the TCP connection termination.

2.

The SIGCHLD signal is sent to the server parent and handled correctly (Figure 5.12).

3.

Nothing happens at the client. The client TCP receives the FIN from the server TCP and responds with an ACK, but the problem is that the client process is blocked in the call to fgets waiting for a line from the terminal.

4.

Running netstat at this point shows the state of the sockets.

5.

linux % netstat -a | grep 9877

tcp 0 0 *:9877 *:* LISTEN tcp 0 0 localhost:9877 localhost:43604 FIN_WAIT2 tcp 1 0 localhost:43604 localhost:9877 CLOSE_WAIT

From Figure 2.4, we see that half of the TCP connection termination sequence has taken place.

We can still type a line of input to the client. Here is what happens at the client starting from Step 1:

linux % tcpcli01 127.0.0.1 start client

hello the first line that we type

hello is echoed correctly here we kill the server child on the server host

another line we then type a second line to the client str_cli : server terminated

prematurely 6.

[ Team LiB ]

Table of Contents

UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API

By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff

Publisher: Addison Wesley Pub Date: November 21, 2003

ISBN: 0-13-141155-1 Pages: 1024

"Everyone will want this book because it provides a great mix of practical experience, historical perspective, and a depth of understanding that only comes from being intimately involved in the field. I've already enjoyed and learned from reading this book, and surely you will too."

-Sam Leffler

The classic guide to UNIX networking APIs... now completely updated!

To build today's highly distributed, networked applications and services, you need deep

mastery of sockets and other key networking APIs. One book delivers comprehensive, start-to-finish guidance for building robust, high-performance networked systems in any environment:

UNIX Network Programming, Volume 1, Third Edition.

Building on the legendary work of W. Richard Stevens, this edition has been fully updated by two leading network programming experts to address today's most crucial standards, implementations, and techniques. New topics include:

POSIX Single UNIX Specification Version 3

IPv6 APIs (including updated guidance on IPv6/IPv4 interoperability) The new SCTP transport protocol

IPsec-based Key Management Sockets

FreeBSD 4.8/5.1, Red Hat Linux 9.x, Solaris 9, AIX 5.x, HP-UX, and Mac OS X implementations

New network program debugging techniques

Source Specific Multicast API, the key enabler for widespread IP multicast deployment When we type "another line," str_cli calls writen and the client TCP sends the data to the server. 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 be sending any more data. The receipt of the FIN does not tell the client TCP that the server process has terminated (which in this case, it has). We will cover this again in Section 6.6 when we talk about TCP's half-close.

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 was sent by watching the packets with tcpdump.

The client process will not see the RST because it calls readline immediately after the call to writen and readline returns 0 (EOF) immediately because of the FIN that was

received in Step 2. Our client is not expecting to receive an EOF at this point (Figure 5.5) so it quits with the error message "server terminated prematurely."

7.

When the client terminates (by calling err_quit in Figure 5.5), all its open descriptors are closed.

8.

What we have described also depends on the timing of the example. The client's call to readline may happen before the server's RST is received by the client, or it may happen after. If the readline happens before the RST is received, as we've shown in our

example, the result is an unexpected EOF in the client. But if the RST arrives first, the result is an ECONNRESET ("Connection reset by peer") error return from readline.

The problem in this example is that the client is blocked in the call to fgets when the FIN arrives on the socket. The client is really working with two descriptors—the socket and the user input—and instead of blocking on input from only one of the two sources (as str_cli is

currently coded), it should block on input from either source. Indeed, this is one purpose of the select and poll functions, which we will describe in Chapter 6. When we recode the str_cli function in Section 6.4, as soon as we kill the server child, the client is notified of the received FIN.

[ Team LiB ]

[ Team LiB ]

Table of Contents

UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking API

By W. Richard Stevens, Bill Fenner, Andrew M. Rudoff

Publisher: Addison Wesley Pub Date: November 21, 2003

ISBN: 0-13-141155-1 Pages: 1024

"Everyone will want this book because it provides a great mix of practical experience, historical perspective, and a depth of understanding that only comes from being intimately involved in the field. I've already enjoyed and learned from reading this book, and surely you will too."

-Sam Leffler

The classic guide to UNIX networking APIs... now completely updated!

To build today's highly distributed, networked applications and services, you need deep

mastery of sockets and other key networking APIs. One book delivers comprehensive, start-to-finish guidance for building robust, high-performance networked systems in any environment:

UNIX Network Programming, Volume 1, Third Edition.

Building on the legendary work of W. Richard Stevens, this edition has been fully updated by two leading network programming experts to address today's most crucial standards, implementations, and techniques. New topics include:

POSIX Single UNIX Specification Version 3

IPv6 APIs (including updated guidance on IPv6/IPv4 interoperability) The new SCTP transport protocol

IPsec-based Key Management Sockets

FreeBSD 4.8/5.1, Red Hat Linux 9.x, Solaris 9, AIX 5.x, HP-UX, and Mac OS X implementations

New network program debugging techniques

Source Specific Multicast API, the key enabler for widespread IP multicast deployment [ Team LiB ]

5.13

SIGPIPE

Signal

What happens if the client ignores the error return from readline and writes more data to the server? This can happen, for example, if the client needs to perform two writes to the server before reading anything back, with the first write eliciting the RST.

The rule that applies 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 being involuntarily terminated.

If the process either catches the signal and returns from the signal handler, or ignores the signal, the write operation returns EPIPE.

A frequently asked question (FAQ) on Usenet is how to obtain this signal on the first write, and not the second. This is not possible. Following our discussion above, the first write elicits the RST and the second write elicits the signal. It is okay to write to a socket that has received a FIN, but it is an error to write to a socket that has received an RST.

To see what happens with SIGPIPE, we modify our client as shown in Figure 5.14.