diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java index 1105d4f9c1..c546aba77d 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java @@ -22,6 +22,7 @@ import io.netty.buffer.Unpooled; import io.netty.channel.AbstractChannel; import io.netty.channel.Channel; import io.netty.channel.ChannelConfig; +import io.netty.channel.ChannelException; import io.netty.channel.ChannelMetadata; import io.netty.channel.EventLoop; import io.netty.channel.RecvByteBufAllocator; @@ -68,6 +69,14 @@ abstract class AbstractKQueueChannel extends AbstractChannel implements UnixChan this.writeFilterEnabled = writeFilterEnabled; } + static boolean isSoErrorZero(BsdSocket fd) { + try { + return fd.getSoError() == 0; + } catch (IOException e) { + throw new ChannelException(e); + } + } + @Override public final FileDescriptor fd() { return socket; diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueServerChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueServerChannel.java index 1f582c63f9..397a96068b 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueServerChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueServerChannel.java @@ -32,6 +32,10 @@ import java.net.SocketAddress; public abstract class AbstractKQueueServerChannel extends AbstractKQueueChannel implements ServerChannel { private static final ChannelMetadata METADATA = new ChannelMetadata(false, 16); + AbstractKQueueServerChannel(BsdSocket fd) { + this(fd, isSoErrorZero(fd)); + } + AbstractKQueueServerChannel(BsdSocket fd, boolean active) { super(null, fd, active); } diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java index 75a02f86f5..d555997979 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueStreamChannel.java @@ -68,6 +68,10 @@ public abstract class AbstractKQueueStreamChannel extends AbstractKQueueChannel super(parent, fd, active, true); } + AbstractKQueueStreamChannel(BsdSocket fd) { + this(null, fd, isSoErrorZero(fd)); + } + @Override protected AbstractKQueueUnsafe newUnsafe() { return new KQueueStreamUnsafe(); diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java index cffa7f537f..9ae3845f74 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDatagramChannel.java @@ -68,6 +68,10 @@ public final class KQueueDatagramChannel extends AbstractKQueueChannel implement config = new KQueueDatagramChannelConfig(this); } + public KQueueDatagramChannel(int fd) { + this(new BsdSocket(fd), true); + } + KQueueDatagramChannel(BsdSocket socket, boolean active) { super(null, socket, active); config = new KQueueDatagramChannelConfig(this); diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDomainSocketChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDomainSocketChannel.java index ff99c51382..10a84f4aa0 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDomainSocketChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueDomainSocketChannel.java @@ -41,6 +41,10 @@ public final class KQueueDomainSocketChannel extends AbstractKQueueStreamChannel super(null, newSocketDomain(), false); } + public KQueueDomainSocketChannel(int fd) { + this(null, new BsdSocket(fd)); + } + KQueueDomainSocketChannel(Channel parent, BsdSocket fd) { super(parent, fd, true); } diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerDomainSocketChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerDomainSocketChannel.java index 5c8a2b34ee..980719eb51 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerDomainSocketChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerDomainSocketChannel.java @@ -40,6 +40,10 @@ public final class KQueueServerDomainSocketChannel extends AbstractKQueueServerC super(newSocketDomain(), false); } + public KQueueServerDomainSocketChannel(int fd) { + this(new BsdSocket(fd), false); + } + KQueueServerDomainSocketChannel(BsdSocket socket, boolean active) { super(socket, active); } diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerSocketChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerSocketChannel.java index 22f14435cb..ae37067f30 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerSocketChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueServerSocketChannel.java @@ -36,6 +36,21 @@ public final class KQueueServerSocketChannel extends AbstractKQueueServerChannel config = new KQueueServerSocketChannelConfig(this); } + public KQueueServerSocketChannel(int fd) { + // Must call this constructor to ensure this object's local address is configured correctly. + // The local address can only be obtained from a Socket object. + this(new BsdSocket(fd)); + } + + KQueueServerSocketChannel(BsdSocket fd) { + super(fd); + config = new KQueueServerSocketChannelConfig(this); + + // As we create an KQueueServerSocketChannel from a FileDescriptor we should try to obtain the remote and local + // address from it. This is needed as the FileDescriptor may be bound already. + local = fd.localAddress(); + } + KQueueServerSocketChannel(BsdSocket fd, boolean active) { super(fd, active); config = new KQueueServerSocketChannelConfig(this); diff --git a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueSocketChannel.java b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueSocketChannel.java index c894a7e1b0..89688e2945 100644 --- a/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueSocketChannel.java +++ b/transport-native-kqueue/src/main/java/io/netty/channel/kqueue/KQueueSocketChannel.java @@ -42,6 +42,15 @@ public final class KQueueSocketChannel extends AbstractKQueueStreamChannel imple config = new KQueueSocketChannelConfig(this); } + public KQueueSocketChannel(int fd) { + super(new BsdSocket(fd)); + // As we create an EpollSocketChannel from a FileDescriptor we should try to obtain the remote and local + // address from it. This is needed as the FileDescriptor may be bound/connected already. + remote = socket.remoteAddress(); + local = socket.localAddress(); + config = new KQueueSocketChannelConfig(this); + } + KQueueSocketChannel(Channel parent, BsdSocket fd, InetSocketAddress remote) { super(parent, fd, true); config = new KQueueSocketChannelConfig(this);