Page MenuHomeFreeBSD

Improve ioctl() for listening TCP sockets
ClosedPublic

Authored by tuexen on Oct 21 2020, 10:08 PM.

Details

Summary

The ioctl() calls using FIONREAD, FIONWRITE, FIONSPACE, and SIOCATMARK access the socket send or receive buffer. This is not possible for listening sockets since r319722. Since send()/recv() calls fail on listening sockets, fail also ioctl() indicating EINVAL.

This fixes Bug 250366.

Test Plan

Use the following packetdrill script:

 0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0.000 bind(3, ..., ...) = 0
+0.000 listen(3, 1) = 0
+0.000 < S  0:0(0)       win 65535 <mss 1460>
+0.000 > S. 0:0(0) ack 1 win 65535 <mss 1460>
+0.000 < .  1:1(0) ack 1 win 65535
+0.000 recv(3, ..., 1000, 0) = -1 ENOTCONN (Socket is not connected)
+0.000 ioctl(3, FIONREAD, [0]) = -1 EINVAL (Invalid argument)
+0.000 ioctl(3, FIONWRITE, [0]) = -1 EINVAL (Invalid argument)
+0.000 ioctl(3, FIONSPACE, [0]) = -1 EINVAL (Invalid argument)
+0.000 ioctl(3, SIOCATMARK, [0]) = -1 EINVAL (Invalid argument)
+0.000 accept(3, ..., ...) = 4
// send buffer size is net.inet.tcp.sendspace (default to 32768)
// rounded up to a multiple of the MSS sent by the peer.
+0.00  getsockopt(4, SOL_SOCKET, SO_SNDBUF, [33580], [4]) = 0
+0.000 ioctl(4, FIONREAD, [0]) = 0
+0.000 ioctl(4, FIONWRITE, [0]) = 0
+0.000 ioctl(4, FIONSPACE, [33580]) = 0
+0.000 ioctl(4, SIOCATMARK, [0]) = 0
+0.000 < .  1:9(8) ack 1 win 65535
+0.000 send(4, ..., 7, 0) = 7
+0.000 > P. 1:8(7) ack 9 win 65535
+0.000 ioctl(4, FIONREAD, [8]) = 0
+0.000 ioctl(4, FIONWRITE, [7]) = 0
+0.000 ioctl(4, FIONSPACE, [33573]) = 0
+0.000 ioctl(4, SIOCATMARK, [0]) = 0
+0.000 recv(4, ..., 1000, 0) = 8
+0.000 < .  9:9(0) ack 8 win 65535
+0.000 ioctl(4, FIONREAD, [0]) = 0
+0.000 ioctl(4, FIONWRITE, [0]) = 0
+0.000 ioctl(4, FIONSPACE, [33580]) = 0
+0.000 ioctl(4, SIOCATMARK, [0]) = 0

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.