From 49bf02ce09cb0f672b965a2d53222e33636beda6 Mon Sep 17 00:00:00 2001 From: Jestan Nirojan Date: Sun, 13 Jan 2013 23:56:24 +0530 Subject: [PATCH] [#929] Implemented multi-homing opertions in SctpServerChannels and SCTP Javadocs cleanup --- .../channel/socket/sctp/SctpChannel.java | 14 +++-- .../socket/sctp/SctpNotificationEvent.java | 13 ++++- .../socket/sctp/SctpServerChannel.java | 38 +++++++++++-- .../socket/sctp/nio/NioSctpServerChannel.java | 53 +++++++++++++++++++ .../socket/sctp/oio/OioSctpServerChannel.java | 53 +++++++++++++++++++ .../sctp/SctpMessageCompletionHandler.java | 2 +- 6 files changed, 162 insertions(+), 11 deletions(-) diff --git a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpChannel.java b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpChannel.java index fb7d713427..09b1d2939c 100644 --- a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpChannel.java @@ -25,7 +25,11 @@ import java.net.InetSocketAddress; import java.util.Set; /** - * A SCTP/IP {@link Channel} + * A SCTP/IP {@link Channel} interface for single SCTP association. + * + *

+ * The SctpChannel is a message-oriented, connected transport which supports multi-streaming and multi-homing. + *

*/ public interface SctpChannel extends Channel { @Override @@ -90,9 +94,9 @@ public interface SctpChannel extends Channel { * Bind a address to the already bound channel to enable multi-homing. * The Channel bust be bound and yet to be connected. * - * The given {@link ChannelFuture} will be notified and also returned. + * Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture} */ - ChannelFuture bindAddress(InetAddress localAddress, ChannelPromise future); + ChannelFuture bindAddress(InetAddress localAddress, ChannelPromise promise); /** * Unbind the address from channel's multi-homing address list. @@ -104,7 +108,7 @@ public interface SctpChannel extends Channel { * Unbind the address from channel's multi-homing address list. * The address should be added already in multi-homing address list. * - * The given {@link ChannelFuture} will be notified and also returned. + * Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture} */ - ChannelFuture unbindAddress(InetAddress localAddress, ChannelPromise future); + ChannelFuture unbindAddress(InetAddress localAddress, ChannelPromise promise); } diff --git a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpNotificationEvent.java b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpNotificationEvent.java index 7eedd7fad7..9e0c9e673b 100644 --- a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpNotificationEvent.java +++ b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpNotificationEvent.java @@ -21,8 +21,17 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; /** - * Will be passed to {@link ChannelPipeline#fireUserEventTriggered(Object)} method and so forwarded to the added - * {@link ChannelHandler#userEventTriggered(ChannelHandlerContext, Object)} method. + * A Notification event which carries a {@link Notification} from the SCTP stack to a SCTP {@link ChannelPipeline}. + *

+ * Following notifications may be supported by a {@link SctpChannel}; + * AssociationChangeNotification, PeerAddressChangeNotification, SendFailedNotification, ShutdownNotification and + * additional implementation specific notifications. + *

+ * + *

+ * User can handle the notification events of a {@link SctpChannel} by override the following method + * {@link ChannelHandler#userEventTriggered(ChannelHandlerContext, Object)}. + *

*/ public final class SctpNotificationEvent { private final Notification notification; diff --git a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpServerChannel.java b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpServerChannel.java index 396e9d055d..bff1accb19 100644 --- a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpServerChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/SctpServerChannel.java @@ -15,16 +15,20 @@ */ package io.netty.channel.socket.sctp; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelPromise; import io.netty.channel.ServerChannel; import java.net.InetSocketAddress; +import java.net.InetAddress; import java.util.Set; /** - * A SCTP/IP {@link ServerChannel} which accepts incoming SCTP/IP connections. + * A SCTP/IP {@link ServerChannel} which accepts incoming SCTP/IP associations. * - * The {@link SctpServerChannel} provides the additional operations, available in the - * underlying JDK SCTP Server Channel like multi-homing etc. + *

+ * Multi-homing address binding/unbinding can done through bindAddress/unbindAddress methods. + *

*/ public interface SctpServerChannel extends ServerChannel { @@ -52,4 +56,32 @@ public interface SctpServerChannel extends ServerChannel { * Please note that, it will return more than one address if this channel is using multi-homing */ Set allLocalAddresses(); + + /** + * Bind a address to the already bound channel to enable multi-homing. + * The Channel must be bound and yet to be connected. + */ + ChannelFuture bindAddress(InetAddress localAddress); + + /** + * Bind a address to the already bound channel to enable multi-homing. + * The Channel must be bound and yet to be connected. + * + * Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture} + */ + ChannelFuture bindAddress(InetAddress localAddress, ChannelPromise promise); + + /** + * 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); + + /** + * Unbind the address from channel's multi-homing address list. + * The address should be added already in multi-homing address list. + * + * Will notify the given {@link ChannelPromise} and return a {@link ChannelFuture} + */ + ChannelFuture unbindAddress(InetAddress localAddress, ChannelPromise promise); } diff --git a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/nio/NioSctpServerChannel.java b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/nio/NioSctpServerChannel.java index fd4c1520dc..f466249134 100644 --- a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/nio/NioSctpServerChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/nio/NioSctpServerChannel.java @@ -20,12 +20,15 @@ import com.sun.nio.sctp.SctpServerChannel; import io.netty.buffer.BufType; import io.netty.buffer.MessageBuf; import io.netty.channel.ChannelException; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelMetadata; +import io.netty.channel.ChannelPromise; import io.netty.channel.socket.nio.AbstractNioMessageChannel; import io.netty.channel.socket.sctp.DefaultSctpServerChannelConfig; import io.netty.channel.socket.sctp.SctpServerChannelConfig; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.SelectionKey; @@ -136,6 +139,56 @@ public class NioSctpServerChannel extends AbstractNioMessageChannel return 1; } + @Override + public ChannelFuture bindAddress(InetAddress localAddress) { + return bindAddress(localAddress, newPromise()); + } + + @Override + public ChannelFuture bindAddress(final InetAddress localAddress, final ChannelPromise promise) { + if (eventLoop().inEventLoop()) { + try { + javaChannel().bindAddress(localAddress); + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + bindAddress(localAddress, promise); + } + }); + } + return promise; + } + + @Override + public ChannelFuture unbindAddress(InetAddress localAddress) { + return unbindAddress(localAddress, newPromise()); + } + + @Override + public ChannelFuture unbindAddress(final InetAddress localAddress, final ChannelPromise promise) { + if (eventLoop().inEventLoop()) { + try { + javaChannel().unbindAddress(localAddress); + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + unbindAddress(localAddress, promise); + } + }); + } + return promise; + } + // Unnecessary stuff @Override protected boolean doConnect( diff --git a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/oio/OioSctpServerChannel.java b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/oio/OioSctpServerChannel.java index d53717256d..b6922095ec 100755 --- a/transport-sctp/src/main/java/io/netty/channel/socket/sctp/oio/OioSctpServerChannel.java +++ b/transport-sctp/src/main/java/io/netty/channel/socket/sctp/oio/OioSctpServerChannel.java @@ -20,7 +20,9 @@ import com.sun.nio.sctp.SctpServerChannel; import io.netty.buffer.BufType; import io.netty.buffer.MessageBuf; import io.netty.channel.ChannelException; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelMetadata; +import io.netty.channel.ChannelPromise; import io.netty.channel.socket.oio.AbstractOioMessageChannel; import io.netty.channel.socket.sctp.DefaultSctpServerChannelConfig; import io.netty.channel.socket.sctp.SctpServerChannelConfig; @@ -28,6 +30,7 @@ import io.netty.logging.InternalLogger; import io.netty.logging.InternalLoggerFactory; import java.io.IOException; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.SelectionKey; @@ -216,6 +219,56 @@ public class OioSctpServerChannel extends AbstractOioMessageChannel return 0; } + @Override + public ChannelFuture bindAddress(InetAddress localAddress) { + return bindAddress(localAddress, newPromise()); + } + + @Override + public ChannelFuture bindAddress(final InetAddress localAddress, final ChannelPromise promise) { + if (eventLoop().inEventLoop()) { + try { + sch.bindAddress(localAddress); + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + bindAddress(localAddress, promise); + } + }); + } + return promise; + } + + @Override + public ChannelFuture unbindAddress(InetAddress localAddress) { + return unbindAddress(localAddress, newPromise()); + } + + @Override + public ChannelFuture unbindAddress(final InetAddress localAddress, final ChannelPromise promise) { + if (eventLoop().inEventLoop()) { + try { + sch.unbindAddress(localAddress); + promise.setSuccess(); + } catch (Throwable t) { + promise.setFailure(t); + } + } else { + eventLoop().execute(new Runnable() { + @Override + public void run() { + unbindAddress(localAddress, promise); + } + }); + } + return promise; + } + @Override protected void doConnect( SocketAddress remoteAddress, SocketAddress localAddress) throws Exception { diff --git a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java index ae64b6bfaa..d3f3e419c0 100644 --- a/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java +++ b/transport-sctp/src/main/java/io/netty/handler/codec/sctp/SctpMessageCompletionHandler.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.Map; /** - * {@link ChannelInboundMessageHandlerAdapter} which will take care of handle fragemented {@link SctpMessage}s, so + * {@link ChannelInboundMessageHandlerAdapter} which will take care of handle fragmented {@link SctpMessage}s, so * only complete {@link SctpMessage}s will be forwarded to the next * {@link ChannelInboundMessageHandler}. */