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 boolean activeOnOpen;
35  
36      EpollDatagramChannelConfig(EpollDatagramChannel channel) {
37          super(channel);
38          setRecvByteBufAllocator(DEFAULT_RCVBUF_ALLOCATOR);
39      }
40  
41      @Override
42      @SuppressWarnings("deprecation")
43      public Map<ChannelOption<?>, Object> getOptions() {
44          return getOptions(
45                  super.getOptions(),
46                  ChannelOption.SO_BROADCAST, ChannelOption.SO_RCVBUF, ChannelOption.SO_SNDBUF,
47                  ChannelOption.SO_REUSEADDR, ChannelOption.IP_MULTICAST_LOOP_DISABLED,
48                  ChannelOption.IP_MULTICAST_ADDR, ChannelOption.IP_MULTICAST_IF, ChannelOption.IP_MULTICAST_TTL,
49                  ChannelOption.IP_TOS, ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION,
50                  EpollChannelOption.SO_REUSEPORT, EpollChannelOption.IP_FREEBIND, EpollChannelOption.IP_TRANSPARENT,
51                  EpollChannelOption.IP_RECVORIGDSTADDR);
52      }
53  
54      @SuppressWarnings({ "unchecked", "deprecation" })
55      @Override
56      public <T> T getOption(ChannelOption<T> option) {
57          if (option == ChannelOption.SO_BROADCAST) {
58              return (T) Boolean.valueOf(isBroadcast());
59          }
60          if (option == ChannelOption.SO_RCVBUF) {
61              return (T) Integer.valueOf(getReceiveBufferSize());
62          }
63          if (option == ChannelOption.SO_SNDBUF) {
64              return (T) Integer.valueOf(getSendBufferSize());
65          }
66          if (option == ChannelOption.SO_REUSEADDR) {
67              return (T) Boolean.valueOf(isReuseAddress());
68          }
69          if (option == ChannelOption.IP_MULTICAST_LOOP_DISABLED) {
70              return (T) Boolean.valueOf(isLoopbackModeDisabled());
71          }
72          if (option == ChannelOption.IP_MULTICAST_ADDR) {
73              return (T) getInterface();
74          }
75          if (option == ChannelOption.IP_MULTICAST_IF) {
76              return (T) getNetworkInterface();
77          }
78          if (option == ChannelOption.IP_MULTICAST_TTL) {
79              return (T) Integer.valueOf(getTimeToLive());
80          }
81          if (option == ChannelOption.IP_TOS) {
82              return (T) Integer.valueOf(getTrafficClass());
83          }
84          if (option == ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
85              return (T) Boolean.valueOf(activeOnOpen);
86          }
87          if (option == EpollChannelOption.SO_REUSEPORT) {
88              return (T) Boolean.valueOf(isReusePort());
89          }
90          if (option == EpollChannelOption.IP_TRANSPARENT) {
91              return (T) Boolean.valueOf(isIpTransparent());
92          }
93          if (option == EpollChannelOption.IP_FREEBIND) {
94              return (T) Boolean.valueOf(isFreeBind());
95          }
96          if (option == EpollChannelOption.IP_RECVORIGDSTADDR) {
97              return (T) Boolean.valueOf(isIpRecvOrigDestAddr());
98          }
99          return super.getOption(option);
100     }
101 
102     @Override
103     @SuppressWarnings("deprecation")
104     public <T> boolean setOption(ChannelOption<T> option, T value) {
105         validate(option, value);
106 
107         if (option == ChannelOption.SO_BROADCAST) {
108             setBroadcast((Boolean) value);
109         } else if (option == ChannelOption.SO_RCVBUF) {
110             setReceiveBufferSize((Integer) value);
111         } else if (option == ChannelOption.SO_SNDBUF) {
112             setSendBufferSize((Integer) value);
113         } else if (option == ChannelOption.SO_REUSEADDR) {
114             setReuseAddress((Boolean) value);
115         } else if (option == ChannelOption.IP_MULTICAST_LOOP_DISABLED) {
116             setLoopbackModeDisabled((Boolean) value);
117         } else if (option == ChannelOption.IP_MULTICAST_ADDR) {
118             setInterface((InetAddress) value);
119         } else if (option == ChannelOption.IP_MULTICAST_IF) {
120             setNetworkInterface((NetworkInterface) value);
121         } else if (option == ChannelOption.IP_MULTICAST_TTL) {
122             setTimeToLive((Integer) value);
123         } else if (option == ChannelOption.IP_TOS) {
124             setTrafficClass((Integer) value);
125         } else if (option == ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
126             setActiveOnOpen((Boolean) value);
127         } else if (option == EpollChannelOption.SO_REUSEPORT) {
128             setReusePort((Boolean) value);
129         } else if (option == EpollChannelOption.IP_FREEBIND) {
130             setFreeBind((Boolean) value);
131         } else if (option == EpollChannelOption.IP_TRANSPARENT) {
132             setIpTransparent((Boolean) value);
133         } else if (option == EpollChannelOption.IP_RECVORIGDSTADDR) {
134             setIpRecvOrigDestAddr((Boolean) value);
135         } else {
136             return super.setOption(option, value);
137         }
138 
139         return true;
140     }
141 
142     private void setActiveOnOpen(boolean activeOnOpen) {
143         if (channel.isRegistered()) {
144             throw new IllegalStateException("Can only changed before channel was registered");
145         }
146         this.activeOnOpen = activeOnOpen;
147     }
148 
149     boolean getActiveOnOpen() {
150         return activeOnOpen;
151     }
152 
153     @Override
154     public EpollDatagramChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
155         super.setMessageSizeEstimator(estimator);
156         return this;
157     }
158 
159     @Override
160     @Deprecated
161     public EpollDatagramChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
162         super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
163         return this;
164     }
165 
166     @Override
167     @Deprecated
168     public EpollDatagramChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
169         super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
170         return this;
171     }
172 
173     @Override
174     public EpollDatagramChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
175         super.setWriteBufferWaterMark(writeBufferWaterMark);
176         return this;
177     }
178 
179     @Override
180     public EpollDatagramChannelConfig setAutoClose(boolean autoClose) {
181         super.setAutoClose(autoClose);
182         return this;
183     }
184 
185     @Override
186     public EpollDatagramChannelConfig setAutoRead(boolean autoRead) {
187         super.setAutoRead(autoRead);
188         return this;
189     }
190 
191     @Override
192     public EpollDatagramChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
193         super.setRecvByteBufAllocator(allocator);
194         return this;
195     }
196 
197     @Override
198     public EpollDatagramChannelConfig setWriteSpinCount(int writeSpinCount) {
199         super.setWriteSpinCount(writeSpinCount);
200         return this;
201     }
202 
203     @Override
204     public EpollDatagramChannelConfig setAllocator(ByteBufAllocator allocator) {
205         super.setAllocator(allocator);
206         return this;
207     }
208 
209     @Override
210     public EpollDatagramChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
211         super.setConnectTimeoutMillis(connectTimeoutMillis);
212         return this;
213     }
214 
215     @Override
216     @Deprecated
217     public EpollDatagramChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
218         super.setMaxMessagesPerRead(maxMessagesPerRead);
219         return this;
220     }
221 
222     @Override
223     public int getSendBufferSize() {
224         try {
225             return ((EpollDatagramChannel) channel).socket.getSendBufferSize();
226         } catch (IOException e) {
227             throw new ChannelException(e);
228         }
229     }
230 
231     @Override
232     public EpollDatagramChannelConfig setSendBufferSize(int sendBufferSize) {
233         try {
234             ((EpollDatagramChannel) channel).socket.setSendBufferSize(sendBufferSize);
235             return this;
236         } catch (IOException e) {
237             throw new ChannelException(e);
238         }
239     }
240 
241     @Override
242     public int getReceiveBufferSize() {
243         try {
244             return ((EpollDatagramChannel) channel).socket.getReceiveBufferSize();
245         } catch (IOException e) {
246             throw new ChannelException(e);
247         }
248     }
249 
250     @Override
251     public EpollDatagramChannelConfig setReceiveBufferSize(int receiveBufferSize) {
252         try {
253             ((EpollDatagramChannel) channel).socket.setReceiveBufferSize(receiveBufferSize);
254             return this;
255         } catch (IOException e) {
256             throw new ChannelException(e);
257         }
258     }
259 
260     @Override
261     public int getTrafficClass() {
262         try {
263             return ((EpollDatagramChannel) channel).socket.getTrafficClass();
264         } catch (IOException e) {
265             throw new ChannelException(e);
266         }
267     }
268 
269     @Override
270     public EpollDatagramChannelConfig setTrafficClass(int trafficClass) {
271         try {
272             ((EpollDatagramChannel) channel).socket.setTrafficClass(trafficClass);
273             return this;
274         } catch (IOException e) {
275             throw new ChannelException(e);
276         }
277     }
278 
279     @Override
280     public boolean isReuseAddress() {
281         try {
282             return ((EpollDatagramChannel) channel).socket.isReuseAddress();
283         } catch (IOException e) {
284             throw new ChannelException(e);
285         }
286     }
287 
288     @Override
289     public EpollDatagramChannelConfig setReuseAddress(boolean reuseAddress) {
290         try {
291             ((EpollDatagramChannel) channel).socket.setReuseAddress(reuseAddress);
292             return this;
293         } catch (IOException e) {
294             throw new ChannelException(e);
295         }
296     }
297 
298     @Override
299     public boolean isBroadcast() {
300         try {
301             return ((EpollDatagramChannel) channel).socket.isBroadcast();
302         } catch (IOException e) {
303             throw new ChannelException(e);
304         }
305     }
306 
307     @Override
308     public EpollDatagramChannelConfig setBroadcast(boolean broadcast) {
309         try {
310             ((EpollDatagramChannel) channel).socket.setBroadcast(broadcast);
311             return this;
312         } catch (IOException e) {
313             throw new ChannelException(e);
314         }
315     }
316 
317     @Override
318     public boolean isLoopbackModeDisabled() {
319         return false;
320     }
321 
322     @Override
323     public DatagramChannelConfig setLoopbackModeDisabled(boolean loopbackModeDisabled) {
324         throw new UnsupportedOperationException("Multicast not supported");
325     }
326 
327     @Override
328     public int getTimeToLive() {
329         return -1;
330     }
331 
332     @Override
333     public EpollDatagramChannelConfig setTimeToLive(int ttl) {
334         throw new UnsupportedOperationException("Multicast not supported");
335     }
336 
337     @Override
338     public InetAddress getInterface() {
339         return null;
340     }
341 
342     @Override
343     public EpollDatagramChannelConfig setInterface(InetAddress interfaceAddress) {
344         throw new UnsupportedOperationException("Multicast not supported");
345     }
346 
347     @Override
348     public NetworkInterface getNetworkInterface() {
349         return null;
350     }
351 
352     @Override
353     public EpollDatagramChannelConfig setNetworkInterface(NetworkInterface networkInterface) {
354         throw new UnsupportedOperationException("Multicast not supported");
355     }
356 
357     @Override
358     public EpollDatagramChannelConfig setEpollMode(EpollMode mode) {
359         super.setEpollMode(mode);
360         return this;
361     }
362 
363     /**
364      * Returns {@code true} if the SO_REUSEPORT option is set.
365      */
366     public boolean isReusePort() {
367         try {
368             return ((EpollDatagramChannel) channel).socket.isReusePort();
369         } catch (IOException e) {
370             throw new ChannelException(e);
371         }
372     }
373 
374     /**
375      * Set the SO_REUSEPORT option on the underlying Channel. This will allow to bind multiple
376      * {@link EpollSocketChannel}s to the same port and so accept connections with multiple threads.
377      *
378      * Be aware this method needs be called before {@link EpollDatagramChannel#bind(java.net.SocketAddress)} to have
379      * any affect.
380      */
381     public EpollDatagramChannelConfig setReusePort(boolean reusePort) {
382         try {
383             ((EpollDatagramChannel) channel).socket.setReusePort(reusePort);
384             return this;
385         } catch (IOException e) {
386             throw new ChannelException(e);
387         }
388     }
389 
390     /**
391      * Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
392      * {@code false} otherwise.
393      */
394     public boolean isIpTransparent() {
395         try {
396             return ((EpollDatagramChannel) channel).socket.isIpTransparent();
397         } catch (IOException e) {
398             throw new ChannelException(e);
399         }
400     }
401 
402     /**
403      * If {@code true} is used <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_TRANSPARENT</a> is enabled,
404      * {@code false} for disable it. Default is disabled.
405      */
406     public EpollDatagramChannelConfig setIpTransparent(boolean ipTransparent) {
407         try {
408             ((EpollDatagramChannel) channel).socket.setIpTransparent(ipTransparent);
409             return this;
410         } catch (IOException e) {
411             throw new ChannelException(e);
412         }
413     }
414 
415     /**
416      * Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_FREEBIND</a> is enabled,
417      * {@code false} otherwise.
418      */
419     public boolean isFreeBind() {
420         try {
421             return ((EpollDatagramChannel) channel).socket.isIpFreeBind();
422         } catch (IOException e) {
423             throw new ChannelException(e);
424         }
425     }
426 
427     /**
428      * If {@code true} is used <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_FREEBIND</a> is enabled,
429      * {@code false} for disable it. Default is disabled.
430      */
431     public EpollDatagramChannelConfig setFreeBind(boolean freeBind) {
432         try {
433             ((EpollDatagramChannel) channel).socket.setIpFreeBind(freeBind);
434             return this;
435         } catch (IOException e) {
436             throw new ChannelException(e);
437         }
438     }
439 
440     /**
441      * Returns {@code true} if <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_RECVORIGDSTADDR</a> is
442      * enabled, {@code false} otherwise.
443      */
444     public boolean isIpRecvOrigDestAddr() {
445         try {
446             return ((EpollDatagramChannel) channel).socket.isIpRecvOrigDestAddr();
447         } catch (IOException e) {
448             throw new ChannelException(e);
449         }
450     }
451 
452     /**
453      * If {@code true} is used <a href="http://man7.org/linux/man-pages/man7/ip.7.html">IP_RECVORIGDSTADDR</a> is
454      * enabled, {@code false} for disable it. Default is disabled.
455      */
456     public EpollDatagramChannelConfig setIpRecvOrigDestAddr(boolean ipTransparent) {
457         try {
458             ((EpollDatagramChannel) channel).socket.setIpRecvOrigDestAddr(ipTransparent);
459             return this;
460         } catch (IOException e) {
461             throw new ChannelException(e);
462         }
463     }
464 
465 }