1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport.socket;
21
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.InetSocketAddress;
25 import java.net.ServerSocket;
26 import java.net.Socket;
27 import java.net.SocketException;
28 import java.net.UnknownHostException;
29 import java.util.LinkedHashMap;
30 import java.util.Map;
31 import java.util.Map.Entry;
32
33 import org.apache.mina.core.service.IoService;
34 import org.apache.mina.util.ExceptionMonitor;
35
36
37
38
39
40
41
42 public class DefaultSocketSessionConfig extends AbstractSocketSessionConfig {
43
44 private static Map<InetSocketAddress, InetAddress> TEST_ADDRESSES = new LinkedHashMap<InetSocketAddress, InetAddress>();
45
46 private static boolean SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
47 private static boolean SET_SEND_BUFFER_SIZE_AVAILABLE = false;
48 private static boolean GET_TRAFFIC_CLASS_AVAILABLE = false;
49 private static boolean SET_TRAFFIC_CLASS_AVAILABLE = false;
50 private static boolean DEFAULT_REUSE_ADDRESS = false;
51 private static int DEFAULT_RECEIVE_BUFFER_SIZE = 1024;
52 private static int DEFAULT_SEND_BUFFER_SIZE = 1024;
53 private static int DEFAULT_TRAFFIC_CLASS = 0;
54 private static boolean DEFAULT_KEEP_ALIVE = false;
55 private static boolean DEFAULT_OOB_INLINE = false;
56 private static int DEFAULT_SO_LINGER = -1;
57 private static boolean DEFAULT_TCP_NO_DELAY = false;
58
59 static {
60 initializeTestAddresses();
61
62 boolean success = false;
63 for (Entry<InetSocketAddress, InetAddress> e : TEST_ADDRESSES
64 .entrySet()) {
65 success = initializeDefaultSocketParameters(e.getKey(), e
66 .getValue());
67 if (success) {
68 break;
69 }
70 }
71
72 if (!success) {
73 initializeFallbackDefaultSocketParameters();
74 }
75 }
76
77 private static void initializeFallbackDefaultSocketParameters() {
78 Socket unconnectedSocket = new Socket();
79 try {
80 initializeDefaultSocketParameters(unconnectedSocket);
81 } catch (SocketException se) {
82 ExceptionMonitor.getInstance().exceptionCaught(se);
83
84 try {
85 unconnectedSocket.close();
86 } catch (IOException ioe) {
87 ExceptionMonitor.getInstance().exceptionCaught(ioe);
88 }
89 }
90 }
91
92 private static void initializeTestAddresses() {
93 try {
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
111 .getByAddress(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 1 }));
113
114
115 TEST_ADDRESSES.put(new InetSocketAddress(0), InetAddress
116 .getByAddress(new byte[] { 127, 0, 0, 1 }));
117
118 } catch (UnknownHostException e) {
119 ExceptionMonitor.getInstance().exceptionCaught(e);
120 }
121 }
122
123 private static boolean initializeDefaultSocketParameters(
124 InetSocketAddress bindAddress, InetAddress connectAddress) {
125 ServerSocket ss = null;
126 Socket socket = null;
127
128 try {
129 ss = new ServerSocket();
130 ss.bind(bindAddress);
131 socket = new Socket();
132
133
134
135 socket.connect(new InetSocketAddress(connectAddress, ss
136 .getLocalPort()), 10000);
137
138 initializeDefaultSocketParameters(socket);
139 return true;
140 } catch (IOException ioe) {
141 return false;
142 } finally {
143 if (socket != null) {
144 try {
145 socket.close();
146 } catch (IOException e) {
147 ExceptionMonitor.getInstance().exceptionCaught(e);
148 }
149 }
150
151 if (ss != null) {
152 try {
153 ss.close();
154 } catch (IOException e) {
155 ExceptionMonitor.getInstance().exceptionCaught(e);
156 }
157 }
158 }
159 }
160
161 private static void initializeDefaultSocketParameters(Socket socket)
162 throws SocketException {
163 DEFAULT_REUSE_ADDRESS = socket.getReuseAddress();
164 DEFAULT_RECEIVE_BUFFER_SIZE = socket.getReceiveBufferSize();
165 DEFAULT_SEND_BUFFER_SIZE = socket.getSendBufferSize();
166 DEFAULT_KEEP_ALIVE = socket.getKeepAlive();
167 DEFAULT_OOB_INLINE = socket.getOOBInline();
168 DEFAULT_SO_LINGER = socket.getSoLinger();
169 DEFAULT_TCP_NO_DELAY = socket.getTcpNoDelay();
170
171
172 try {
173 socket.setReceiveBufferSize(DEFAULT_RECEIVE_BUFFER_SIZE);
174 SET_RECEIVE_BUFFER_SIZE_AVAILABLE = true;
175 } catch (SocketException e) {
176 SET_RECEIVE_BUFFER_SIZE_AVAILABLE = false;
177 }
178
179
180 try {
181 socket.setSendBufferSize(DEFAULT_SEND_BUFFER_SIZE);
182 SET_SEND_BUFFER_SIZE_AVAILABLE = true;
183 } catch (SocketException e) {
184 SET_SEND_BUFFER_SIZE_AVAILABLE = false;
185 }
186
187
188 try {
189 DEFAULT_TRAFFIC_CLASS = socket.getTrafficClass();
190 GET_TRAFFIC_CLASS_AVAILABLE = true;
191 } catch (SocketException e) {
192 GET_TRAFFIC_CLASS_AVAILABLE = false;
193 DEFAULT_TRAFFIC_CLASS = 0;
194 }
195 }
196
197 public static boolean isSetReceiveBufferSizeAvailable() {
198 return SET_RECEIVE_BUFFER_SIZE_AVAILABLE;
199 }
200
201 public static boolean isSetSendBufferSizeAvailable() {
202 return SET_SEND_BUFFER_SIZE_AVAILABLE;
203 }
204
205 public static boolean isGetTrafficClassAvailable() {
206 return GET_TRAFFIC_CLASS_AVAILABLE;
207 }
208
209 public static boolean isSetTrafficClassAvailable() {
210 return SET_TRAFFIC_CLASS_AVAILABLE;
211 }
212
213 private IoService parent;
214 private boolean defaultReuseAddress;
215 private int defaultReceiveBufferSize = DEFAULT_RECEIVE_BUFFER_SIZE;
216
217 private boolean reuseAddress;
218 private int receiveBufferSize = defaultReceiveBufferSize;
219 private int sendBufferSize = DEFAULT_SEND_BUFFER_SIZE;
220 private int trafficClass = DEFAULT_TRAFFIC_CLASS;
221 private boolean keepAlive = DEFAULT_KEEP_ALIVE;
222 private boolean oobInline = DEFAULT_OOB_INLINE;
223 private int soLinger = DEFAULT_SO_LINGER;
224 private boolean tcpNoDelay = DEFAULT_TCP_NO_DELAY;
225
226
227
228
229 public DefaultSocketSessionConfig() {
230 }
231
232 public void init(IoService parent) {
233 this.parent = parent;
234 if (parent instanceof SocketAcceptor) {
235 defaultReuseAddress = true;
236 } else {
237 defaultReuseAddress = DEFAULT_REUSE_ADDRESS;
238 }
239 reuseAddress = defaultReuseAddress;
240 }
241
242 public boolean isReuseAddress() {
243 return reuseAddress;
244 }
245
246 public void setReuseAddress(boolean reuseAddress) {
247 this.reuseAddress = reuseAddress;
248 }
249
250 public int getReceiveBufferSize() {
251 return receiveBufferSize;
252 }
253
254 public void setReceiveBufferSize(int receiveBufferSize) {
255 this.receiveBufferSize = receiveBufferSize;
256
257
258
259
260
261
262
263
264
265 if (!parent.isActive() && parent instanceof SocketAcceptor) {
266 defaultReceiveBufferSize = receiveBufferSize;
267 }
268 }
269
270 public int getSendBufferSize() {
271 return sendBufferSize;
272 }
273
274 public void setSendBufferSize(int sendBufferSize) {
275 this.sendBufferSize = sendBufferSize;
276 }
277
278 public int getTrafficClass() {
279 return trafficClass;
280 }
281
282 public void setTrafficClass(int trafficClass) {
283 this.trafficClass = trafficClass;
284 }
285
286 public boolean isKeepAlive() {
287 return keepAlive;
288 }
289
290 public void setKeepAlive(boolean keepAlive) {
291 this.keepAlive = keepAlive;
292 }
293
294 public boolean isOobInline() {
295 return oobInline;
296 }
297
298 public void setOobInline(boolean oobInline) {
299 this.oobInline = oobInline;
300 }
301
302 public int getSoLinger() {
303 return soLinger;
304 }
305
306 public void setSoLinger(int soLinger) {
307 this.soLinger = soLinger;
308 }
309
310 public boolean isTcpNoDelay() {
311 return tcpNoDelay;
312 }
313
314 public void setTcpNoDelay(boolean tcpNoDelay) {
315 this.tcpNoDelay = tcpNoDelay;
316 }
317
318 @Override
319 protected boolean isKeepAliveChanged() {
320 return keepAlive != DEFAULT_KEEP_ALIVE;
321 }
322
323 @Override
324 protected boolean isOobInlineChanged() {
325 return oobInline != DEFAULT_OOB_INLINE;
326 }
327
328 @Override
329 protected boolean isReceiveBufferSizeChanged() {
330 return receiveBufferSize != defaultReceiveBufferSize;
331 }
332
333 @Override
334 protected boolean isReuseAddressChanged() {
335 return reuseAddress != defaultReuseAddress;
336 }
337
338 @Override
339 protected boolean isSendBufferSizeChanged() {
340 return sendBufferSize != DEFAULT_SEND_BUFFER_SIZE;
341 }
342
343 @Override
344 protected boolean isSoLingerChanged() {
345 return soLinger != DEFAULT_SO_LINGER;
346 }
347
348 @Override
349 protected boolean isTcpNoDelayChanged() {
350 return tcpNoDelay != DEFAULT_TCP_NO_DELAY;
351 }
352
353 @Override
354 protected boolean isTrafficClassChanged() {
355 return trafficClass != DEFAULT_TRAFFIC_CLASS;
356 }
357 }