/* * Copyright (c) 2013 Robert Varga. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.tcpmd5.nio; import com.google.common.base.Preconditions; import java.io.IOException; import java.net.ServerSocket; import java.net.SocketAddress; import java.net.SocketOption; import java.nio.channels.ServerSocketChannel; import java.util.Set; import org.opendaylight.tcpmd5.api.KeyAccessFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * {@link ServerSocketChannel} augmented with support for TCP MD5 Signature option. */ public final class MD5ServerSocketChannel extends ServerSocketChannel implements ProxyChannel<ServerSocketChannel> { private static final Logger LOG = LoggerFactory.getLogger(MD5ServerSocketChannel.class); private final KeyAccessFactory keyAccessFactory; private final ServerSocketChannel inner; private final MD5ChannelOptions options; public MD5ServerSocketChannel(final ServerSocketChannel inner, final KeyAccessFactory keyAccessFactory) { super(MD5SelectorProvider.getInstance(keyAccessFactory, inner.provider())); this.inner = inner; this.keyAccessFactory = Preconditions.checkNotNull(keyAccessFactory); this.options = MD5ChannelOptions.create(keyAccessFactory, inner); } public MD5ServerSocketChannel(final ServerSocketChannel inner) { this(inner, DefaultKeyAccessFactoryFactory.getKeyAccessFactory()); } public static MD5ServerSocketChannel open() throws IOException { return new MD5ServerSocketChannel(ServerSocketChannel.open()); } public static MD5ServerSocketChannel open(final KeyAccessFactory keyAccessFactory) throws IOException { return new MD5ServerSocketChannel(ServerSocketChannel.open(), keyAccessFactory); } @Override public SocketAddress getLocalAddress() throws IOException { return inner.getLocalAddress(); } @Override public <T> T getOption(final SocketOption<T> name) throws IOException { return options.getOption(name); } @Override public Set<SocketOption<?>> supportedOptions() { return options.supportedOptions(); } @Override public ServerSocketChannel bind(final SocketAddress local, final int backlog) throws IOException { inner.bind(local, backlog); return this; } @Override public <T> ServerSocketChannel setOption(final SocketOption<T> name, final T value) throws IOException { options.setOption(name, value); return this; } @Override public ServerSocket socket() { final ServerSocket s = inner.socket(); LOG.info("Leaking inner socket {} from server {}", s, this); return s; } @Override public MD5SocketChannel accept() throws IOException { return new MD5SocketChannel(inner.accept(), keyAccessFactory); } @Override protected void implCloseSelectableChannel() throws IOException { inner.close(); } @Override protected void implConfigureBlocking(final boolean block) throws IOException { inner.configureBlocking(block); } @Override public ServerSocketChannel getDelegate() { return inner; } }