1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.socket;
17
18 import io.netty.buffer.ByteBufAllocator;
19 import io.netty.channel.ChannelException;
20 import io.netty.channel.ChannelOption;
21 import io.netty.channel.DefaultChannelConfig;
22 import io.netty.channel.FixedRecvByteBufAllocator;
23 import io.netty.channel.MessageSizeEstimator;
24 import io.netty.channel.RecvByteBufAllocator;
25 import io.netty.channel.WriteBufferWaterMark;
26 import io.netty.util.internal.ObjectUtil;
27 import io.netty.util.internal.PlatformDependent;
28 import io.netty.util.internal.logging.InternalLogger;
29 import io.netty.util.internal.logging.InternalLoggerFactory;
30
31 import java.io.IOException;
32 import java.net.DatagramSocket;
33 import java.net.InetAddress;
34 import java.net.MulticastSocket;
35 import java.net.NetworkInterface;
36 import java.net.SocketException;
37 import java.util.Map;
38
39 import static io.netty.channel.ChannelOption.*;
40
41
42
43
44 public class DefaultDatagramChannelConfig extends DefaultChannelConfig implements DatagramChannelConfig {
45
46 private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultDatagramChannelConfig.class);
47
48 private final DatagramSocket javaSocket;
49 private volatile boolean activeOnOpen;
50
51
52
53
54 public DefaultDatagramChannelConfig(DatagramChannel channel, DatagramSocket javaSocket) {
55 super(channel, new FixedRecvByteBufAllocator(2048));
56 this.javaSocket = ObjectUtil.checkNotNull(javaSocket, "javaSocket");
57 }
58
59 protected final DatagramSocket javaSocket() {
60 return javaSocket;
61 }
62
63 @Override
64 @SuppressWarnings("deprecation")
65 public Map<ChannelOption<?>, Object> getOptions() {
66 return getOptions(
67 super.getOptions(),
68 SO_BROADCAST, SO_RCVBUF, SO_SNDBUF, SO_REUSEADDR, IP_MULTICAST_LOOP_DISABLED,
69 IP_MULTICAST_ADDR, IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_TOS, DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION);
70 }
71
72 @Override
73 @SuppressWarnings({ "unchecked", "deprecation" })
74 public <T> T getOption(ChannelOption<T> option) {
75 if (option == SO_BROADCAST) {
76 return (T) Boolean.valueOf(isBroadcast());
77 }
78 if (option == SO_RCVBUF) {
79 return (T) Integer.valueOf(getReceiveBufferSize());
80 }
81 if (option == SO_SNDBUF) {
82 return (T) Integer.valueOf(getSendBufferSize());
83 }
84 if (option == SO_REUSEADDR) {
85 return (T) Boolean.valueOf(isReuseAddress());
86 }
87 if (option == IP_MULTICAST_LOOP_DISABLED) {
88 return (T) Boolean.valueOf(isLoopbackModeDisabled());
89 }
90 if (option == IP_MULTICAST_ADDR) {
91 return (T) getInterface();
92 }
93 if (option == IP_MULTICAST_IF) {
94 return (T) getNetworkInterface();
95 }
96 if (option == IP_MULTICAST_TTL) {
97 return (T) Integer.valueOf(getTimeToLive());
98 }
99 if (option == IP_TOS) {
100 return (T) Integer.valueOf(getTrafficClass());
101 }
102 if (option == DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
103 return (T) Boolean.valueOf(activeOnOpen);
104 }
105 return super.getOption(option);
106 }
107
108 @Override
109 @SuppressWarnings("deprecation")
110 public <T> boolean setOption(ChannelOption<T> option, T value) {
111 validate(option, value);
112
113 if (option == SO_BROADCAST) {
114 setBroadcast((Boolean) value);
115 } else if (option == SO_RCVBUF) {
116 setReceiveBufferSize((Integer) value);
117 } else if (option == SO_SNDBUF) {
118 setSendBufferSize((Integer) value);
119 } else if (option == SO_REUSEADDR) {
120 setReuseAddress((Boolean) value);
121 } else if (option == IP_MULTICAST_LOOP_DISABLED) {
122 setLoopbackModeDisabled((Boolean) value);
123 } else if (option == IP_MULTICAST_ADDR) {
124 setInterface((InetAddress) value);
125 } else if (option == IP_MULTICAST_IF) {
126 setNetworkInterface((NetworkInterface) value);
127 } else if (option == IP_MULTICAST_TTL) {
128 setTimeToLive((Integer) value);
129 } else if (option == IP_TOS) {
130 setTrafficClass((Integer) value);
131 } else if (option == DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION) {
132 setActiveOnOpen((Boolean) value);
133 } else {
134 return super.setOption(option, value);
135 }
136
137 return true;
138 }
139
140 private void setActiveOnOpen(boolean activeOnOpen) {
141 if (channel.isRegistered()) {
142 throw new IllegalStateException("Can only changed before channel was registered");
143 }
144 this.activeOnOpen = activeOnOpen;
145 }
146
147 @Override
148 public boolean isBroadcast() {
149 try {
150 return javaSocket.getBroadcast();
151 } catch (SocketException e) {
152 throw new ChannelException(e);
153 }
154 }
155
156 @Override
157 public DatagramChannelConfig setBroadcast(boolean broadcast) {
158 try {
159
160 if (broadcast &&
161 !javaSocket.getLocalAddress().isAnyLocalAddress() &&
162 !PlatformDependent.isWindows() && !PlatformDependent.maybeSuperUser()) {
163
164
165 logger.warn(
166 "A non-root user can't receive a broadcast packet if the socket " +
167 "is not bound to a wildcard address; setting the SO_BROADCAST flag " +
168 "anyway as requested on the socket which is bound to " +
169 javaSocket.getLocalSocketAddress() + '.');
170 }
171
172 javaSocket.setBroadcast(broadcast);
173 } catch (SocketException e) {
174 throw new ChannelException(e);
175 }
176 return this;
177 }
178
179 @Override
180 public InetAddress getInterface() {
181 if (javaSocket instanceof MulticastSocket) {
182 try {
183 return ((MulticastSocket) javaSocket).getInterface();
184 } catch (SocketException e) {
185 throw new ChannelException(e);
186 }
187 } else {
188 throw new UnsupportedOperationException();
189 }
190 }
191
192 @Override
193 public DatagramChannelConfig setInterface(InetAddress interfaceAddress) {
194 if (javaSocket instanceof MulticastSocket) {
195 try {
196 ((MulticastSocket) javaSocket).setInterface(interfaceAddress);
197 } catch (SocketException e) {
198 throw new ChannelException(e);
199 }
200 } else {
201 throw new UnsupportedOperationException();
202 }
203 return this;
204 }
205
206 @Override
207 public boolean isLoopbackModeDisabled() {
208 if (javaSocket instanceof MulticastSocket) {
209 try {
210 return ((MulticastSocket) javaSocket).getLoopbackMode();
211 } catch (SocketException e) {
212 throw new ChannelException(e);
213 }
214 } else {
215 throw new UnsupportedOperationException();
216 }
217 }
218
219 @Override
220 public DatagramChannelConfig setLoopbackModeDisabled(boolean loopbackModeDisabled) {
221 if (javaSocket instanceof MulticastSocket) {
222 try {
223 ((MulticastSocket) javaSocket).setLoopbackMode(loopbackModeDisabled);
224 } catch (SocketException e) {
225 throw new ChannelException(e);
226 }
227 } else {
228 throw new UnsupportedOperationException();
229 }
230 return this;
231 }
232
233 @Override
234 public NetworkInterface getNetworkInterface() {
235 if (javaSocket instanceof MulticastSocket) {
236 try {
237 return ((MulticastSocket) javaSocket).getNetworkInterface();
238 } catch (SocketException e) {
239 throw new ChannelException(e);
240 }
241 } else {
242 throw new UnsupportedOperationException();
243 }
244 }
245
246 @Override
247 public DatagramChannelConfig setNetworkInterface(NetworkInterface networkInterface) {
248 if (javaSocket instanceof MulticastSocket) {
249 try {
250 ((MulticastSocket) javaSocket).setNetworkInterface(networkInterface);
251 } catch (SocketException e) {
252 throw new ChannelException(e);
253 }
254 } else {
255 throw new UnsupportedOperationException();
256 }
257 return this;
258 }
259
260 @Override
261 public boolean isReuseAddress() {
262 try {
263 return javaSocket.getReuseAddress();
264 } catch (SocketException e) {
265 throw new ChannelException(e);
266 }
267 }
268
269 @Override
270 public DatagramChannelConfig setReuseAddress(boolean reuseAddress) {
271 try {
272 javaSocket.setReuseAddress(reuseAddress);
273 } catch (SocketException e) {
274 throw new ChannelException(e);
275 }
276 return this;
277 }
278
279 @Override
280 public int getReceiveBufferSize() {
281 try {
282 return javaSocket.getReceiveBufferSize();
283 } catch (SocketException e) {
284 throw new ChannelException(e);
285 }
286 }
287
288 @Override
289 public DatagramChannelConfig setReceiveBufferSize(int receiveBufferSize) {
290 try {
291 javaSocket.setReceiveBufferSize(receiveBufferSize);
292 } catch (SocketException e) {
293 throw new ChannelException(e);
294 }
295 return this;
296 }
297
298 @Override
299 public int getSendBufferSize() {
300 try {
301 return javaSocket.getSendBufferSize();
302 } catch (SocketException e) {
303 throw new ChannelException(e);
304 }
305 }
306
307 @Override
308 public DatagramChannelConfig setSendBufferSize(int sendBufferSize) {
309 try {
310 javaSocket.setSendBufferSize(sendBufferSize);
311 } catch (SocketException e) {
312 throw new ChannelException(e);
313 }
314 return this;
315 }
316
317 @Override
318 public int getTimeToLive() {
319 if (javaSocket instanceof MulticastSocket) {
320 try {
321 return ((MulticastSocket) javaSocket).getTimeToLive();
322 } catch (IOException e) {
323 throw new ChannelException(e);
324 }
325 } else {
326 throw new UnsupportedOperationException();
327 }
328 }
329
330 @Override
331 public DatagramChannelConfig setTimeToLive(int ttl) {
332 if (javaSocket instanceof MulticastSocket) {
333 try {
334 ((MulticastSocket) javaSocket).setTimeToLive(ttl);
335 } catch (IOException e) {
336 throw new ChannelException(e);
337 }
338 } else {
339 throw new UnsupportedOperationException();
340 }
341 return this;
342 }
343
344 @Override
345 public int getTrafficClass() {
346 try {
347 return javaSocket.getTrafficClass();
348 } catch (SocketException e) {
349 throw new ChannelException(e);
350 }
351 }
352
353 @Override
354 public DatagramChannelConfig setTrafficClass(int trafficClass) {
355 try {
356 javaSocket.setTrafficClass(trafficClass);
357 } catch (SocketException e) {
358 throw new ChannelException(e);
359 }
360 return this;
361 }
362
363 @Override
364 public DatagramChannelConfig setWriteSpinCount(int writeSpinCount) {
365 super.setWriteSpinCount(writeSpinCount);
366 return this;
367 }
368
369 @Override
370 public DatagramChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
371 super.setConnectTimeoutMillis(connectTimeoutMillis);
372 return this;
373 }
374
375 @Override
376 @Deprecated
377 public DatagramChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
378 super.setMaxMessagesPerRead(maxMessagesPerRead);
379 return this;
380 }
381
382 @Override
383 public DatagramChannelConfig setAllocator(ByteBufAllocator allocator) {
384 super.setAllocator(allocator);
385 return this;
386 }
387
388 @Override
389 public DatagramChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
390 super.setRecvByteBufAllocator(allocator);
391 return this;
392 }
393
394 @Override
395 public DatagramChannelConfig setAutoRead(boolean autoRead) {
396 super.setAutoRead(autoRead);
397 return this;
398 }
399
400 @Override
401 public DatagramChannelConfig setAutoClose(boolean autoClose) {
402 super.setAutoClose(autoClose);
403 return this;
404 }
405
406 @Override
407 public DatagramChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
408 super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
409 return this;
410 }
411
412 @Override
413 public DatagramChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
414 super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
415 return this;
416 }
417
418 @Override
419 public DatagramChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
420 super.setWriteBufferWaterMark(writeBufferWaterMark);
421 return this;
422 }
423
424 @Override
425 public DatagramChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
426 super.setMessageSizeEstimator(estimator);
427 return this;
428 }
429
430 @Override
431 public DatagramChannelConfig setMaxMessagesPerWrite(int maxMessagesPerWrite) {
432 super.setMaxMessagesPerWrite(maxMessagesPerWrite);
433 return this;
434 }
435 }