* Florian Weimer: > * Alan Bateman: > >> On 04/10/2019 16:25, Florian Weimer wrote: >>> : >>> @@ -873,10 +873,15 @@ >>> synchronized (stateLock) { >>> ensureOpen(); >>> if (state == ST_CONNECTED) >>> throw new AlreadyConnectedException(); >>> + // ensure that the socket is bound >>> + if (localAddress == null) { >>> + bindInternal(null); >>> + } >>> + >>> int n = Net.connect(family, >>> fd, >>> isa.getAddress(), >>> isa.getPort()); >>> if (n <= 0) >>> >>> >>> Doesn't it introduce a race condition where the socket has a port and >>> queue packets, but the kernel will not perform source address checking >>> because it is unconnected? >>> >> The socket is unbound, this change to the connect method in Daniel's >> patch just binds it before connecting. The kernel will do this anyway >> so it's not strictly needed here (at least for the case that the >> connect succeeds_. > > The kernel will do it atomically during connect, so there is no race > condition. With the change above, the port is selected and opened, > packets can arrive (from arbitrary addresses), and only then the socket > is bound to the remote address.
Ah, sorry, there is this in connect(SocketAddress): // flush any packets already received. boolean blocking = isBlocking(); if (blocking) { IOUtil.configureBlocking(fd, false); } try { ByteBuffer buf = ByteBuffer.allocate(100); while (receive(fd, buf, false) > 0) { buf.clear(); } } finally { if (blocking) { IOUtil.configureBlocking(fd, true); } } So any pending datagrams are cleared in userspace, and the race is benign and not observable by applications. (I forgot that this was added in 2014, sorry.) Thanks, Florian