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  import java.io.IOException;
27  import java.net.InetAddress;
28  import java.net.NetworkInterface;
29  import java.util.Map;
30  
31  public final class EpollDatagramChannelConfig extends EpollChannelConfig implements DatagramChannelConfig {
32      private static final RecvByteBufAllocator DEFAULT_RCVBUF_ALLOCATOR = new FixedRecvByteBufAllocator(2048);
33      private final EpollDatagramChannel datagramChannel;
34      private boolean activeOnOpen;
35  
36      EpollDatagramChannelConfig(EpollDatagramChannel channel) {
37          super(channel);
38          datagramChannel = channel;
39          setRecvByteBufAllocator(DEFAULT_RCVBUF_ALLOCATOR);
40      }
41  
42      @Override
43      @SuppressWarnings("deprecation")
44      public Map<ChannelOption<?>, Object> getOptions() {
45          return getOptions(
46                  super.getOptions(),
47                  ChannelOption.SO_BROADCAST, ChannelOption.SO_RCVBUF, ChannelOption.SO_SNDBUF,
48                  ChannelOption.SO_REUSEADDR, ChannelOption.IP_MULTICAST_LOOP_DISABLED,
49                  ChannelOption.IP_MULTICAST_ADDR, ChannelOption.IP_MULTICAST_IF, ChannelOption.IP_MULTICAST_TTL,
50                  ChannelOption.IP_TOS, ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION,
51                  EpollChannelOption.SO_REUSEPORT);
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          return super.getOption(option);
91      }
92  
93      @Override
94      @SuppressWarnings("deprecation")
95      public <T> boolean setOption(ChannelOption<T> option, T value) {
96          validate(option, value);
97  
98          if (option == ChannelOption.SO_BROADCAST) {
99              setBroadcast((Boolean) value);
100         } else if (option == ChannelOption.SO_RCVBUF) {
101             setReceiveBufferSize((Integer) value);
102         } else if (option == ChannelOption.SO_SNDBUF) {
103             setSendBufferSize((Integer) value);
104         } else if (option == ChannelOption.SO_REUSEADDR) {
105             setReuseAddress((Boolean) value);
106         } else if (option == ChannelOption.IP_MULTICAST_LOOP_DISABLED) {
107             setLoopbackModeDisabled((Boolean) value);
108         } else if (option == ChannelOption.IP_MULTICAST_ADDR) {
109             setInterface((InetAddress) value);
110         } else if (option == ChannelOption.IP_MULTICAST_IF) {
111             setNetworkInterface((NetworkInterface) value);
112         } else if (option == ChannelOption.IP_MULTICAST_TTL) {
113             setTimeToLive((Integer) value);
114         } else if (option == ChannelOption.IP_TOS) {
115             setTrafficClass((Integer) value);
116         } else if (option == ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
117             setActiveOnOpen((Boolean) value);
118         } else if (option == EpollChannelOption.SO_REUSEPORT) {
119             setReusePort((Boolean) value);
120         } else {
121             return super.setOption(option, value);
122         }
123 
124         return true;
125     }
126 
127     private void setActiveOnOpen(boolean activeOnOpen) {
128         if (channel.isRegistered()) {
129             throw new IllegalStateException("Can only changed before channel was registered");
130         }
131         this.activeOnOpen = activeOnOpen;
132     }
133 
134     boolean getActiveOnOpen() {
135         return activeOnOpen;
136     }
137 
138     @Override
139     public EpollDatagramChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
140         super.setMessageSizeEstimator(estimator);
141         return this;
142     }
143 
144     @Override
145     @Deprecated
146     public EpollDatagramChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
147         super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
148         return this;
149     }
150 
151     @Override
152     @Deprecated
153     public EpollDatagramChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
154         super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
155         return this;
156     }
157 
158     @Override
159     public EpollDatagramChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
160         super.setWriteBufferWaterMark(writeBufferWaterMark);
161         return this;
162     }
163 
164     @Override
165     public EpollDatagramChannelConfig setAutoClose(boolean autoClose) {
166         super.setAutoClose(autoClose);
167         return this;
168     }
169 
170     @Override
171     public EpollDatagramChannelConfig setAutoRead(boolean autoRead) {
172         super.setAutoRead(autoRead);
173         return this;
174     }
175 
176     @Override
177     public EpollDatagramChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
178         super.setRecvByteBufAllocator(allocator);
179         return this;
180     }
181 
182     @Override
183     public EpollDatagramChannelConfig setWriteSpinCount(int writeSpinCount) {
184         super.setWriteSpinCount(writeSpinCount);
185         return this;
186     }
187 
188     @Override
189     public EpollDatagramChannelConfig setAllocator(ByteBufAllocator allocator) {
190         super.setAllocator(allocator);
191         return this;
192     }
193 
194     @Override
195     public EpollDatagramChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
196         super.setConnectTimeoutMillis(connectTimeoutMillis);
197         return this;
198     }
199 
200     @Override
201     @Deprecated
202     public EpollDatagramChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
203         super.setMaxMessagesPerRead(maxMessagesPerRead);
204         return this;
205     }
206 
207     @Override
208     public int getSendBufferSize() {
209         try {
210             return datagramChannel.socket.getSendBufferSize();
211         } catch (IOException e) {
212             throw new ChannelException(e);
213         }
214     }
215 
216     @Override
217     public EpollDatagramChannelConfig setSendBufferSize(int sendBufferSize) {
218         try {
219             datagramChannel.socket.setSendBufferSize(sendBufferSize);
220             return this;
221         } catch (IOException e) {
222             throw new ChannelException(e);
223         }
224     }
225 
226     @Override
227     public int getReceiveBufferSize() {
228         try {
229             return datagramChannel.socket.getReceiveBufferSize();
230         } catch (IOException e) {
231             throw new ChannelException(e);
232         }
233     }
234 
235     @Override
236     public EpollDatagramChannelConfig setReceiveBufferSize(int receiveBufferSize) {
237         try {
238             datagramChannel.socket.setReceiveBufferSize(receiveBufferSize);
239             return this;
240         } catch (IOException e) {
241             throw new ChannelException(e);
242         }
243     }
244 
245     @Override
246     public int getTrafficClass() {
247         try {
248             return datagramChannel.socket.getTrafficClass();
249         } catch (IOException e) {
250             throw new ChannelException(e);
251         }
252     }
253 
254     @Override
255     public EpollDatagramChannelConfig setTrafficClass(int trafficClass) {
256         try {
257             datagramChannel.socket.setTrafficClass(trafficClass);
258             return this;
259         } catch (IOException e) {
260             throw new ChannelException(e);
261         }
262     }
263 
264     @Override
265     public boolean isReuseAddress() {
266         try {
267             return datagramChannel.socket.isReuseAddress();
268         } catch (IOException e) {
269             throw new ChannelException(e);
270         }
271     }
272 
273     @Override
274     public EpollDatagramChannelConfig setReuseAddress(boolean reuseAddress) {
275         try {
276             datagramChannel.socket.setReuseAddress(reuseAddress);
277             return this;
278         } catch (IOException e) {
279             throw new ChannelException(e);
280         }
281     }
282 
283     @Override
284     public boolean isBroadcast() {
285         try {
286             return datagramChannel.socket.isBroadcast();
287         } catch (IOException e) {
288             throw new ChannelException(e);
289         }
290     }
291 
292     @Override
293     public EpollDatagramChannelConfig setBroadcast(boolean broadcast) {
294         try {
295             datagramChannel.socket.setBroadcast(broadcast);
296             return this;
297         } catch (IOException e) {
298             throw new ChannelException(e);
299         }
300     }
301 
302     @Override
303     public boolean isLoopbackModeDisabled() {
304         return false;
305     }
306 
307     @Override
308     public DatagramChannelConfig setLoopbackModeDisabled(boolean loopbackModeDisabled) {
309         throw new UnsupportedOperationException("Multicast not supported");
310     }
311 
312     @Override
313     public int getTimeToLive() {
314         return -1;
315     }
316 
317     @Override
318     public EpollDatagramChannelConfig setTimeToLive(int ttl) {
319         throw new UnsupportedOperationException("Multicast not supported");
320     }
321 
322     @Override
323     public InetAddress getInterface() {
324         return null;
325     }
326 
327     @Override
328     public EpollDatagramChannelConfig setInterface(InetAddress interfaceAddress) {
329         throw new UnsupportedOperationException("Multicast not supported");
330     }
331 
332     @Override
333     public NetworkInterface getNetworkInterface() {
334         return null;
335     }
336 
337     @Override
338     public EpollDatagramChannelConfig setNetworkInterface(NetworkInterface networkInterface) {
339         throw new UnsupportedOperationException("Multicast not supported");
340     }
341 
342     @Override
343     public EpollDatagramChannelConfig setEpollMode(EpollMode mode) {
344         super.setEpollMode(mode);
345         return this;
346     }
347 
348     /**
349      * Returns {@code true} if the SO_REUSEPORT option is set.
350      */
351     public boolean isReusePort() {
352         try {
353             return datagramChannel.socket.isReusePort();
354         } catch (IOException e) {
355             throw new ChannelException(e);
356         }
357     }
358 
359     /**
360      * Set the SO_REUSEPORT option on the underlying Channel. This will allow to bind multiple
361      * {@link EpollSocketChannel}s to the same port and so accept connections with multiple threads.
362      *
363      * Be aware this method needs be called before {@link EpollDatagramChannel#bind(java.net.SocketAddress)} to have
364      * any affect.
365      */
366     public EpollDatagramChannelConfig setReusePort(boolean reusePort) {
367         try {
368             datagramChannel.socket.setReusePort(reusePort);
369             return this;
370         } catch (IOException e) {
371             throw new ChannelException(e);
372         }
373     }
374 }