From 1eea3cf5032b15347b4868b74afcc3fee46a32c3 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Sat, 8 Sep 2012 20:20:02 +0200 Subject: [PATCH] Support unbindAddress and bindAddress for SCTP. See #560 --- .../io/netty/channel/socket/SctpChannel.java | 15 ++++- .../channel/socket/nio/NioSctpChannel.java | 59 +++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/socket/SctpChannel.java b/transport/src/main/java/io/netty/channel/socket/SctpChannel.java index 0fab200cdc..89015cb443 100644 --- a/transport/src/main/java/io/netty/channel/socket/SctpChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/SctpChannel.java @@ -19,9 +19,7 @@ import com.sun.nio.sctp.Association; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; -import java.io.IOException; import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Set; @@ -72,10 +70,21 @@ public interface SctpChannel extends Channel { @Override SocketAddress remoteAddress(); - /** * Return all remote addresses of the SCTP server channel. * Please note that, it will return more than one address if the remote is using multi-homing. */ Set allRemoteAddresses(); + + /** + * Bind a address to the already bound channel to enable multi-homing. + * The Channel bust be bound and yet to be connected. + */ + ChannelFuture bindAddress(InetAddress localAddress); + + /** + * Unbind the address from channel's multi-homing address list. + * The address should be added already in multi-homing address list. + */ + ChannelFuture unbindAddress(InetAddress localAddress); } diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioSctpChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioSctpChannel.java index b4e4e72391..9a62b0c543 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioSctpChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioSctpChannel.java @@ -25,6 +25,7 @@ import io.netty.buffer.MessageBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelException; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelMetadata; import io.netty.channel.socket.DefaultSctpChannelConfig; import io.netty.channel.socket.SctpChannelConfig; @@ -34,6 +35,7 @@ import io.netty.logging.InternalLogger; import io.netty.logging.InternalLoggerFactory; import java.io.IOException; +import java.net.InetAddress; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; @@ -48,6 +50,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett private final SctpChannelConfig config; + @SuppressWarnings("rawtypes") private final NotificationHandler notificationHandler; private static SctpChannel newSctpChannel() { @@ -216,6 +219,7 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett javaChannel().close(); } + @SuppressWarnings("unchecked") @Override protected int doReadMessages(MessageBuf buf) throws Exception { SctpChannel ch = javaChannel(); @@ -277,4 +281,59 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett } return 1; } + + @Override + public ChannelFuture bindAddress(InetAddress localAddress) { + ChannelFuture future = newFuture(); + doBindAddress(localAddress, future); + return future; + } + + void doBindAddress(final InetAddress localAddress, final ChannelFuture future) { + if (eventLoop().inEventLoop()) { + try { + javaChannel().bindAddress(localAddress); + future.setSuccess(); + // TODO: Do we want to fire an event ? + } catch (Throwable t) { + future.setFailure(t); + pipeline().fireExceptionCaught(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + doBindAddress(localAddress, future); + } + }); + } + } + + @Override + public ChannelFuture unbindAddress(InetAddress localAddress) { + ChannelFuture future = newFuture(); + doUnbindAddress(localAddress, future); + return future; + } + + void doUnbindAddress(final InetAddress localAddress, final ChannelFuture future) { + if (eventLoop().inEventLoop()) { + try { + javaChannel().unbindAddress(localAddress); + future.setSuccess(); + // TODO: Do we want to fire an event ? + } catch (Throwable t) { + future.setFailure(t); + pipeline().fireExceptionCaught(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + doUnbindAddress(localAddress, future); + } + }); + } + } + }