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