1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.channel.socket.nio;
17
18 import java.io.IOException;
19 import java.net.InetAddress;
20 import java.net.NetworkInterface;
21 import java.net.SocketException;
22 import java.net.StandardSocketOptions;
23 import java.nio.channels.DatagramChannel;
24 import java.util.Enumeration;
25 import java.util.Map;
26
27 import org.jboss.netty.channel.ChannelException;
28 import org.jboss.netty.channel.socket.DefaultDatagramChannelConfig;
29 import org.jboss.netty.logging.InternalLogger;
30 import org.jboss.netty.logging.InternalLoggerFactory;
31 import org.jboss.netty.util.internal.ConversionUtil;
32 import org.jboss.netty.util.internal.DetectionUtil;
33
34
35
36
37 class DefaultNioDatagramChannelConfig extends DefaultDatagramChannelConfig
38 implements NioDatagramChannelConfig {
39
40 private static final InternalLogger logger =
41 InternalLoggerFactory
42 .getInstance(DefaultNioDatagramChannelConfig.class);
43
44 private volatile int writeBufferHighWaterMark = 64 * 1024;
45 private volatile int writeBufferLowWaterMark = 32 * 1024;
46 private volatile int writeSpinCount = 16;
47 private final DatagramChannel channel;
48
49 DefaultNioDatagramChannelConfig(DatagramChannel channel) {
50 super(channel.socket());
51 this.channel = channel;
52 }
53
54 @Override
55 public void setOptions(Map<String, Object> options) {
56 super.setOptions(options);
57 if (getWriteBufferHighWaterMark() < getWriteBufferLowWaterMark()) {
58
59 setWriteBufferLowWaterMark0(getWriteBufferHighWaterMark() >>> 1);
60 if (logger.isWarnEnabled()) {
61
62 logger.warn("writeBufferLowWaterMark cannot be greater than "
63 + "writeBufferHighWaterMark; setting to the half of the "
64 + "writeBufferHighWaterMark.");
65 }
66 }
67 }
68
69 @Override
70 public boolean setOption(String key, Object value) {
71 if (super.setOption(key, value)) {
72 return true;
73 }
74
75 if ("writeBufferHighWaterMark".equals(key)) {
76 setWriteBufferHighWaterMark0(ConversionUtil.toInt(value));
77 } else if ("writeBufferLowWaterMark".equals(key)) {
78 setWriteBufferLowWaterMark0(ConversionUtil.toInt(value));
79 } else if ("writeSpinCount".equals(key)) {
80 setWriteSpinCount(ConversionUtil.toInt(value));
81 } else {
82 return false;
83 }
84 return true;
85 }
86
87 public int getWriteBufferHighWaterMark() {
88 return writeBufferHighWaterMark;
89 }
90
91 public void setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
92 if (writeBufferHighWaterMark < getWriteBufferLowWaterMark()) {
93 throw new IllegalArgumentException(
94 "writeBufferHighWaterMark cannot be less than " +
95 "writeBufferLowWaterMark (" +
96 getWriteBufferLowWaterMark() + "): " +
97 writeBufferHighWaterMark);
98 }
99 setWriteBufferHighWaterMark0(writeBufferHighWaterMark);
100 }
101
102 private void setWriteBufferHighWaterMark0(int writeBufferHighWaterMark) {
103 if (writeBufferHighWaterMark < 0) {
104 throw new IllegalArgumentException("writeBufferHighWaterMark: " +
105 writeBufferHighWaterMark);
106 }
107 this.writeBufferHighWaterMark = writeBufferHighWaterMark;
108 }
109
110 public int getWriteBufferLowWaterMark() {
111 return writeBufferLowWaterMark;
112 }
113
114 public void setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
115 if (writeBufferLowWaterMark > getWriteBufferHighWaterMark()) {
116 throw new IllegalArgumentException(
117 "writeBufferLowWaterMark cannot be greater than " +
118 "writeBufferHighWaterMark (" +
119 getWriteBufferHighWaterMark() + "): " +
120 writeBufferLowWaterMark);
121 }
122 setWriteBufferLowWaterMark0(writeBufferLowWaterMark);
123 }
124
125 private void setWriteBufferLowWaterMark0(int writeBufferLowWaterMark) {
126 if (writeBufferLowWaterMark < 0) {
127 throw new IllegalArgumentException("writeBufferLowWaterMark: " +
128 writeBufferLowWaterMark);
129 }
130 this.writeBufferLowWaterMark = writeBufferLowWaterMark;
131 }
132
133 public int getWriteSpinCount() {
134 return writeSpinCount;
135 }
136
137 public void setWriteSpinCount(int writeSpinCount) {
138 if (writeSpinCount <= 0) {
139 throw new IllegalArgumentException(
140 "writeSpinCount must be a positive integer.");
141 }
142 this.writeSpinCount = writeSpinCount;
143 }
144
145 @Override
146 public void setNetworkInterface(NetworkInterface networkInterface) {
147 if (DetectionUtil.javaVersion() < 7) {
148 throw new UnsupportedOperationException();
149 } else {
150 try {
151 channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
152 } catch (IOException e) {
153 throw new ChannelException(e);
154 }
155 }
156 }
157
158 @Override
159 public NetworkInterface getNetworkInterface() {
160 if (DetectionUtil.javaVersion() < 7) {
161 throw new UnsupportedOperationException();
162 } else {
163 try {
164 return channel.getOption(StandardSocketOptions.IP_MULTICAST_IF);
165 } catch (IOException e) {
166 throw new ChannelException(e);
167 }
168 }
169 }
170
171 @Override
172 public int getTimeToLive() {
173 if (DetectionUtil.javaVersion() < 7) {
174 throw new UnsupportedOperationException();
175 } else {
176 try {
177 return channel.getOption(StandardSocketOptions.IP_MULTICAST_TTL);
178 } catch (IOException e) {
179 throw new ChannelException(e);
180 }
181 }
182 }
183
184 @Override
185 public void setTimeToLive(int ttl) {
186 if (DetectionUtil.javaVersion() < 7) {
187 throw new UnsupportedOperationException();
188 } else {
189 try {
190 channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
191 } catch (IOException e) {
192 throw new ChannelException(e);
193 }
194 }
195 }
196
197 @Override
198 public InetAddress getInterface() {
199 NetworkInterface inf = getNetworkInterface();
200 if (inf == null) {
201 return null;
202 } else {
203 Enumeration<InetAddress> addresses = inf.getInetAddresses();
204 if (addresses.hasMoreElements()) {
205 return addresses.nextElement();
206 }
207 return null;
208 }
209 }
210
211 @Override
212 public void setInterface(InetAddress interfaceAddress) {
213 try {
214 setNetworkInterface(NetworkInterface.getByInetAddress(interfaceAddress));
215 } catch (SocketException e) {
216 throw new ChannelException(e);
217 }
218 }
219
220 @Override
221 public boolean isLoopbackModeDisabled() {
222 if (DetectionUtil.javaVersion() < 7) {
223 throw new UnsupportedOperationException();
224 } else {
225 try {
226 return channel.getOption(StandardSocketOptions.IP_MULTICAST_LOOP);
227 } catch (IOException e) {
228 throw new ChannelException(e);
229 }
230 }
231 }
232
233 @Override
234 public void setLoopbackModeDisabled(boolean loopbackModeDisabled) {
235 if (DetectionUtil.javaVersion() < 7) {
236 throw new UnsupportedOperationException();
237 } else {
238 try {
239 channel.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, loopbackModeDisabled);
240 } catch (IOException e) {
241 throw new ChannelException(e);
242 }
243 }
244 }
245 }