BUG-632: fix netty binding
[bgpcep.git] / tcp-md5 / netty / src / main / java / org / opendaylight / bgpcep / tcpmd5 / netty / MD5NioServerSocketChannel.java
1 /*
2  * Copyright (c) 2013 Robert Varga. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.bgpcep.tcpmd5.netty;
9
10 import io.netty.channel.ChannelException;
11 import io.netty.channel.ChannelMetadata;
12 import io.netty.channel.ChannelOutboundBuffer;
13 import io.netty.channel.nio.AbstractNioMessageChannel;
14 import io.netty.channel.socket.nio.NioServerSocketChannel;
15
16 import java.io.IOException;
17 import java.net.InetSocketAddress;
18 import java.net.SocketAddress;
19 import java.nio.channels.SelectionKey;
20 import java.nio.channels.ServerSocketChannel;
21 import java.nio.channels.SocketChannel;
22 import java.util.List;
23
24 import org.opendaylight.bgpcep.tcpmd5.KeyAccessFactory;
25
26 import com.google.common.base.Preconditions;
27
28 /**
29  * {@link NioServerSocketChannel} enabled with support for TCP MD5 Signature
30  * option.
31  */
32 public class MD5NioServerSocketChannel extends AbstractNioMessageChannel implements io.netty.channel.socket.ServerSocketChannel {
33         private static final ChannelMetadata METADATA = new ChannelMetadata(false);
34
35         private final MD5ServerSocketChannelConfig config;
36         private final KeyAccessFactory keyAccessFactory;
37
38         private static ServerSocketChannel newChannel() {
39                 try {
40                         return ServerSocketChannel.open();
41                 } catch (IOException e) {
42                         throw new ChannelException("Failed to instantiate channel", e);
43                 }
44         }
45
46         private MD5NioServerSocketChannel(final ServerSocketChannel channel, final KeyAccessFactory keyAccessFactory) {
47                 super(null, channel, SelectionKey.OP_ACCEPT);
48                 this.config = new DefaultMD5ServerSocketChannelConfig(this, keyAccessFactory);
49                 this.keyAccessFactory = Preconditions.checkNotNull(keyAccessFactory);
50         }
51
52         public MD5NioServerSocketChannel(final KeyAccessFactory keyAccessFactory) {
53                 this(newChannel(), keyAccessFactory);
54         }
55
56         @Override
57         public MD5ServerSocketChannelConfig config() {
58                 return this.config;
59         }
60
61         @Override
62         public InetSocketAddress localAddress() {
63                 return (InetSocketAddress) super.localAddress();
64         }
65
66         @Override
67         public ChannelMetadata metadata() {
68                 return METADATA;
69         }
70
71         @Override
72         public boolean isActive() {
73                 return javaChannel().socket().isBound();
74         }
75
76         @Override
77         public InetSocketAddress remoteAddress() {
78                 return null;
79         }
80
81         @Override
82         protected ServerSocketChannel javaChannel() {
83                 return (ServerSocketChannel) super.javaChannel();
84         }
85
86         @Override
87         protected SocketAddress localAddress0() {
88                 return javaChannel().socket().getLocalSocketAddress();
89         }
90
91         @Override
92         protected void doBind(final SocketAddress localAddress) throws Exception {
93                 javaChannel().socket().bind(localAddress, config.getBacklog());
94         }
95
96         @Override
97         protected void doClose() throws Exception {
98                 javaChannel().close();
99         }
100
101         @Override
102         protected int doReadMessages(final List<Object> buf) throws Exception {
103                 final SocketChannel jc = javaChannel().accept();
104                 if (jc == null) {
105                         return 0;
106                 }
107
108                 final MD5NioSocketChannel ch = new MD5NioSocketChannel(this, jc, keyAccessFactory);
109                 buf.add(ch);
110                 return 1;
111         }
112
113         @Override
114         protected boolean doWriteMessage(final Object msg, final ChannelOutboundBuffer in)
115                         throws Exception {
116                 throw new UnsupportedOperationException();
117         }
118
119         @Override
120         protected boolean doConnect(final SocketAddress remoteAddress,
121                         final SocketAddress localAddress) throws Exception {
122                 throw new UnsupportedOperationException();
123         }
124
125         @Override
126         protected void doFinishConnect() throws Exception {
127                 throw new UnsupportedOperationException();
128         }
129
130         @Override
131         protected SocketAddress remoteAddress0() {
132                 return null;
133         }
134
135         @Override
136         protected void doDisconnect() throws Exception {
137                 throw new UnsupportedOperationException();
138         }
139 }