When will a connected UDP socket be closed by the OS?

15,515

Solution 1

connect() on an UDP socket just records the port number and IP address you pass in, so it'll only accept packets from that IP/port, and you can use the socket fd to send/write data without specifying the remote address for each send/write call.

Regarding this, async errors means if you send() something, and that send call results in an error occuring later (e.g. when the TCP/IP stack actually sends the packet, or an ICMP packet is later returned), a subsequent send will return that error. Such async errors are only returned on a "connected" UDP socket. (The linux udp(7) manpage suggest errors are returned whether the socket is connected or not, but testing shows this is not the cases at least when a sent UDP packet generates an ICMP error. It might be that send() errors are returned if you recv() on that socket, instead of subsequent send() calls produce an error )

The socket is not closed though, you'll have to close it yourself either by calling close() or exiting the program. e.g. if you connect() your UDP socket, and send to a port noone is listening to, an ICMP packet is normally returned and a subsequent send() call will fail with errno set to ECONNREFUSED. You can continue sending on that socket though, it doesn't get closed by the OS, and if someone starts listening on the port in the mean time the packets will get through.

Solution 2

UDP sockets are connectionless, so there is no real sense of "openness" state attached to them - this is unlike TCP sockets where a socket may be in any number of connection states as determined by the exchange of packets up to a given point.

The only sense in which UDP sockets can be opened and closed is in the sense that they are system level objects with some internal state and a file descriptor. Sockets are never automatically closed in the event of an error and will remain open indefinitely, unless their owning process terminates or calls close on them.

To address your other concern, if the destination port on the destination host is not opened, the sender of a UDP packet will never know.** UDP provides no means of receiver acknowledgement. The packet is routed and, if it arrives at the host, checked for correctness and either successfully received or discarded. There are a number of reasons why send might return an error code when writing to a UDP socket, but none of them have to do with the state of the receiving host.** I recommend consulting the sendto manpage for possible failure modes.

On the other hand, in the case of a TCP socket attempting to connect to an unopened port, the sender will never receive an acknowledgement of its initial connection request, and ultimately connect will fail. At this point it would be up to the sender to stop sending data over the socket (as this will only generate more errors), but even in this case however, the socket file descriptor is never automatically closed.

** See response by @Zuljin in the comments.

Solution 3

The OS won't close your socket just because an error has happened. If the other end disappears, you can continue to send messages to it (but may receive further errors).

Share:
15,515
Ian Barkley-Yeung
Author by

Ian Barkley-Yeung

Updated on June 05, 2022

Comments

  • Ian Barkley-Yeung
    Ian Barkley-Yeung almost 2 years

    I have a UDP file descriptor in a C++ program running under Linux. I call connect() on it to connect it to a remote address and then read and write from that socket.

    According to UNIX Network Programming, "Asynchronous errors are returned to the process for connected UDP sockets." I'm guessing that these asynchronous errors will cause the UDP socket to be closed by the OS, but the book isn't that clear. It also isn't clear what types of asynchronous errors are possible, though it's suggested that if the port on the remote machine is not open, the socket will be closed.

    So my question is: Under what conditions will Linux close the UDP file descriptor?

    • Bad port number?
    • Bad IP address?
    • Any others?
    • bobah
      bobah about 13 years
      UDP socket cannot be connected to, check en.wikipedia.org/wiki/Berkeley_sockets#Client_2
    • Ian Barkley-Yeung
      Ian Barkley-Yeung about 13 years
      No, they can -- read the man page for connect(): "If s is of type SOCK_DGRAM, it permanently specifies the peer to which messages are sent." As I mentioned in the question, UNIX Network Programming states that asynchronous errors will be returned for connected UDP sockets.
    • user207421
      user207421 almost 3 years
      "I'm guessing that these asynchronous errors will cause the UDP socket to be closed by the OS": no. Don't guess. It is up to you to close the socket.
  • Zuljin
    Zuljin about 13 years
    "if the destination port on the destination host is not opened, the sender of a UDP packet will never know" - I can't agree with that. Some OS (I'm not sure if all of them) return ICMP Destination Unreachable message when destination port is not open. Such situation could be detected by sender. I think on Windows sender recvfrom function will fail with error WSAECONNRESET. I'm not sure how this might be detected on other OS.
  • kqnr
    kqnr about 13 years
    @Zuljin, thanks for the info. I was unaware of that! I think ultimately the more relevant parts of the answer still stand though. i.e., UDP "connections" do not exist and UDP sockets are never automatically closed by failed I/O procedures.
  • Zuljin
    Zuljin about 13 years
    I also wasn't aware of this until my application start crashing when server closed UDP port :). This is something hard to find in socket programing tutorials and in most cases handling such situation is not necessary. As I mentioned I'm not even sure if all popular OS send this ICMP package by default (I think some of the firewall could block this behavior to prevent port scanning etc.). So your whole answer is correct with a little exception when server support sending ICMPs.
  • Ian Barkley-Yeung
    Ian Barkley-Yeung about 13 years
    So it's always in a "recoverable" state? As long as the other ends recovers, the socket will start working again? OK, that's what I wanted to know. Thanks.
  • user207421
    user207421 almost 3 years
    UDP sockets are open until you close them, which you have to do. The statement 'there is no real sense of "openness" state attached to them' is completely false.