View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.epoll;
17  
18  import io.netty.buffer.ByteBufAllocator;
19  import io.netty.channel.ChannelException;
20  import io.netty.channel.ChannelOption;
21  import io.netty.channel.FixedRecvByteBufAllocator;
22  import io.netty.channel.MessageSizeEstimator;
23  import io.netty.channel.RecvByteBufAllocator;
24  import io.netty.channel.WriteBufferWaterMark;
25  import io.netty.channel.socket.DatagramChannelConfig;
26  
27  import java.io.IOException;
28  import java.net.InetAddress;
29  import java.net.NetworkInterface;
30  import java.util.Map;
31  
32  public final class EpollDatagramChannelConfig extends EpollChannelConfig implements DatagramChannelConfig {
33      private static final RecvByteBufAllocator DEFAULT_RCVBUF_ALLOCATOR = new FixedRecvByteBufAllocator(2048);
34      private final EpollDatagramChannel datagramChannel;
35      private boolean activeOnOpen;
36  
37      EpollDatagramChannelConfig(EpollDatagramChannel channel) {
38          super(channel);
39          datagramChannel = channel;
40          setRecvByteBufAllocator(DEFAULT_RCVBUF_ALLOCATOR);
41      }
42  
43      @Override
44      @SuppressWarnings("deprecation")
45      public Map<ChannelOption<?>, Object> getOptions() {
46          return getOptions(
47                  super.getOptions(),
48                  ChannelOption.SO_BROADCAST, ChannelOption.SO_RCVBUF, ChannelOption.SO_SNDBUF,
49                  ChannelOption.SO_REUSEADDR, ChannelOption.IP_MULTICAST_LOOP_DISABLED,
50                  ChannelOption.IP_MULTICAST_ADDR, ChannelOption.IP_MULTICAST_IF, ChannelOption.IP_MULTICAST_TTL,
51                  ChannelOption.IP_TOS, ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION,
52                  EpollChannelOption.SO_REUSEPORT, EpollChannelOption.IP_TRANSPARENT);
53      }
54  
55      @SuppressWarnings({ "unchecked", "deprecation" })
56      @Override
57      public <T> T getOption(ChannelOption<T> option) {
58          if (option == ChannelOption.SO_BROADCAST) {
59              return (T) Boolean.valueOf(isBroadcast());
60          }
61          if (option == ChannelOption.SO_RCVBUF) {
62              return (T) Integer.valueOf(getReceiveBufferSize());
63          }
64          if (option == ChannelOption.SO_SNDBUF) {
65              return (T) Integer.valueOf(getSendBufferSize());
66          }
67          if (option == ChannelOption.SO_REUSEADDR) {
68              return (T) Boolean.valueOf(isReuseAddress());
69          }
70          if (option == ChannelOption.IP_MULTICAST_LOOP_DISABLED) {
71              return (T) Boolean.valueOf(isLoopbackModeDisabled());
72          }
73          if (option == ChannelOption.IP_MULTICAST_ADDR) {
74              return (T) getInterface();
75          }
76          if (option == ChannelOption.IP_MULTICAST_IF) {
77              return (T) getNetworkInterface();
78          }
79          if (option == ChannelOption.IP_MULTICAST_TTL) {
80              return (T) Integer.valueOf(getTimeToLive());
81          }
82          if (option == ChannelOption.IP_TOS) {
83              return (T) Integer.valueOf(getTrafficClass());
84          }
85          if (option == ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
86              return (T) Boolean.valueOf(activeOnOpen);
87          }
88          if (option == EpollChannelOption.SO_REUSEPORT) {
89              return (T) Boolean.valueOf(isReusePort());
90          }
91          if (option == EpollChannelOption.IP_TRANSPARENT) {
92              return (T) Boolean.valueOf(isIpTransparent());
93          }
94          return super.getOption(option);
95      }
96  
97      @Override
98      @SuppressWarnings("deprecation")
99      public <T> boolean setOption(ChannelOption<T> option, T value) {
100         validate(option, value);
101 
102         if (option == ChannelOption.SO_BROADCAST) {
103             setBroadcast((Boolean) value);
104         } else if (option == ChannelOption.SO_RCVBUF) {
105             setReceiveBufferSize((Integer) value);
106         } else if (option == ChannelOption.SO_SNDBUF) {
107             setSendBufferSize((Integer) value);
108         } else if (option == ChannelOption.SO_REUSEADDR) {
109             setReuseAddress((Boolean) value);
110         } else if (option == ChannelOption.IP_MULTICAST_LOOP_DISABLED) {
111             setLoopbackModeDisabled((Boolean) value);
112         } else if (option == ChannelOption.IP_MULTICAST_ADDR) {
113             setInterface((InetAddress) value);
114         } else if (option == ChannelOption.IP_MULTICAST_IF) {
115             setNetworkInterface((NetworkInterface) value);
116         } else if (option == ChannelOption.IP_MULTICAST_TTL) {
117             setTimeToLive((Integer) value);
118         } else if (option == ChannelOption.IP_TOS) {
119             setTrafficClass((Integer) value);
120         } else if (option == ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
121             setActiveOnOpen((Boolean) value);
122         } else if (option == EpollChannelOption.SO_REUSEPORT) {
123             setReusePort((Boolean) value);
124         } else if (option == EpollChannelOption.IP_TRANSPARENT) {
125             setIpTransparent((Boolean) value);
126         } else {
127             return super.setOption(option, value);
128         }
129 
130         return true;
131     }
132 
133     private void setActiveOnOpen(boolean activeOnOpen) {
134         if (channel.isRegistered()) {
135             throw new IllegalStateException("Can only changed before channel was registered");
136         }
137         this.activeOnOpen = activeOnOpen;
138     }
139 
140     boolean getActiveOnOpen() {
141         return activeOnOpen;
142     }
143 
144     @Override
145     public EpollDatagramChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
146         super.setMessageSizeEstimator(estimator);
147         return this;
148     }
149 
150     @Override
151     @Deprecated
152     public EpollDatagramChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
153         super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
154         return this;
155     }
156 
157     @Override
158     @Deprecated
159     public EpollDatagramChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
160         super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
161         return this;
162     }
163 
164     @Override
165     public EpollDatagramChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
166         super.setWriteBufferWaterMark(writeBufferWaterMark);
167         return this;
168     }
169 
170     @Override
171     public EpollDatagramChannelConfig setAutoClose(boolean autoClose) {
172         super.setAutoClose(autoClose);
173         return this;
174     }
175 
176     @Override
177     public EpollDatagramChannelConfig setAutoRead(boolean autoRead) {
178         super.setAutoRead(autoRead);
179         return this;
180     }
181 
182     @Override
183     public EpollDatagramChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
184         super.setRecvByteBufAllocator(allocator);
185         return this;
186     }
187 
188     @Override
189     public EpollDatagramChannelConfig setWriteSpinCount(int writeSpinCount) {
190         super.setWriteSpinCount(writeSpinCount);
191         return this;
192     }
193 
194     @Override
195     public EpollDatagramChannelConfig setAllocator(ByteBufAllocator allocator) {
196         super.setAllocator(allocator);
197         return this;
198     }
199 
200     @Override
201     public EpollDatagramChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
202         super.setConnectTimeoutMillis(connectTimeoutMillis);
203         return this;
204     }
205 
206     @Override
207     @Deprecated
208     public EpollDatagramChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
209         super.setMaxMessagesPerRead(maxMessagesPerRead);
210         return this;
211     }
212 
213     @Override
214     public int getSendBufferSize() {
215         try {
216             return datagramChannel.socket.getSendBufferSize();
217         } catch (IOException e) {
218             throw new ChannelException(e);
219         }
220     }
221 
222     @Override
223     public EpollDatagramChannelConfig setSendBufferSize(int sendBufferSize) {
224         try {
225             datagramChannel.socket.setSendBufferSize(sendBufferSize);
226             return this;
227         } catch (IOException e) {
228             throw new ChannelException(e);
229         }
230     }
231 
232     @Override
233     public int getReceiveBufferSize() {
234         try {
235             return datagramChannel.socket.getReceiveBufferSize();
236         } catch (IOException e) {
237             throw new ChannelException(e);
238         }
239     }
240 
241     @Override
242     public EpollDatagramChannelConfig setReceiveBufferSize(int receiveBufferSize) {
243         try {
244             datagramChannel.socket.setReceiveBufferSize(receiveBufferSize);
245             return this;
246         } catch (IOException e) {
247             throw new ChannelException(e);
248         }
249     }
250 
251     @Override
252     public int getTrafficClass() {
253         try {
254             return datagramChannel.socket.getTrafficClass();
255         } catch (IOException e) {
256             throw new ChannelException(e);
257         }
258     }
259 
260     @Override
261     public EpollDatagramChannelConfig setTrafficClass(int trafficClass) {
262         try {
263             datagramChannel.socket.setTrafficClass(trafficClass);
264             return this;
265         } catch (IOException e) {
266             throw new ChannelException(e);
267         }
268     }
269 
270     @Override
271     public boolean isReuseAddress() {
272         try {
273             return datagramChannel.socket.isReuseAddress();
274         } catch (IOException e) {
275             throw new ChannelException(e);
276         }
277     }
278 
279     @Override
280     public EpollDatagramChannelConfig setReuseAddress(boolean reuseAddress) {
281         try {
282             datagramChannel.socket.setReuseAddress(reuseAddress);
283             return this;
284         } catch (IOException e) {
285             throw new ChannelException(e);
286         }
287     }
288 
289     @Override
290     public boolean isBroadcast() {
291         try {
292             return datagramChannel.socket.isBroadcast();
293         } catch (IOException e) {
294             throw new ChannelException(e);
295         }
296     }
297 
298     @Override
299     public EpollDatagramChannelConfig setBroadcast(boolean broadcast) {
300         try {
301             datagramChannel.socket.setBroadcast(broadcast);
302             return this;
303         } catch (IOException e) {
304             throw new ChannelException(e);
305         }
306     }
307 
308     @Override
309     public boolean isLoopbackModeDisabled() {
310         return false;
311     }
312 
313     @Override
314     public DatagramChannelConfig setLoopbackModeDisabled(boolean loopbackModeDisabled) {
315         throw new UnsupportedOperationException("Multicast not supported");
316     }
317 
318     @Override
319     public int getTimeToLive() {
320         return -1;
321     }
322 
323     @Override
324     public EpollDatagramChannelConfig setTimeToLive(int ttl) {
325         throw new UnsupportedOperationException("Multicast not supported");
326     }
327 
328     @Override
329     public InetAddress getInterface() {
330         return null;
331     }
332 
333     @Override
334     public EpollDatagramChannelConfig setInterface(InetAddress interfaceAddress) {
335         throw new UnsupportedOperationException("Multicast not supported");
336     }
337 
338     @Override
339     public NetworkInterface getNetworkInterface() {
340         return null;
341     }
342 
343     @Override
344     public EpollDatagramChannelConfig setNetworkInterface(NetworkInterface networkInterface) {
345         throw new UnsupportedOperationException("Multicast not supported");
346     }
347 
348     @Override
349     public EpollDatagramChannelConfig setEpollMode(EpollMode mode) {
350         super.setEpollMode(mode);
351         return this;
352     }
353 
354     /**
355      * Returns {@code true} if the SO_REUSEPORT option is set.
356      */
357     public boolean isReusePort() {
358         try {
359             return datagramChannel.socket.isReusePort();
360         } catch (IOException e) {
361             throw new ChannelException(e);
362         }
363     }
364 
365     /**
366      * Set the SO_REUSEPORT option on the underlying Channel. This will allow to bind multiple
367      * {@link EpollSocketChannel}s to the same port and so accept connections with multiple threads.
368      *
369      * Be aware this method needs be called before {@link EpollDatagramChannel#bind(java.net.SocketAddress)} to have
370      * any affect.
371      */
372     public EpollDatagramChannelConfig setReusePort(boolean reusePort) {
373         try {
374             datagramChannel.socket.setReusePort(reusePort);
375             return this;
376         } catch (IOException e) {
377             throw new ChannelException(e);
378         }
379     }
380 
381     /**
382      * Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
383      * {@code false} otherwise.
384      */
385     public boolean isIpTransparent() {
386         try {
387             return datagramChannel.socket.isIpTransparent();
388         } catch (IOException e) {
389             throw new ChannelException(e);
390         }
391     }
392 
393     /**
394      * If {@code true} is used <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
395      * {@code false} for disable it. Default is disabled.
396      */
397     public EpollDatagramChannelConfig setIpTransparent(boolean ipTransparent) {
398         try {
399             datagramChannel.socket.setIpTransparent(ipTransparent);
400             return this;
401         } catch (IOException e) {
402             throw new ChannelException(e);
403         }
404     }
405 
406 }