1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.tomcat.util.net;
18
19 import java.io.IOException;
20 import java.net.ServerSocket;
21 import java.net.Socket;
22 import java.net.SocketException;
23 import java.net.StandardSocketOptions;
24 import java.nio.channels.AsynchronousServerSocketChannel;
25 import java.nio.channels.AsynchronousSocketChannel;
26
27 import javax.management.ObjectName;
28
29 /**
30  * Properties that can be set in the <Connector> element
31  * in server.xml. All properties are prefixed with "socket."
32  * and are currently only working for the Nio connector
33  */

34 public class SocketProperties {
35
36     /**
37      * Enable/disable socket processor cache, this bounded cache stores
38      * SocketProcessor objects to reduce GC
39      * Default is 500
40      * -1 is unlimited
41      * 0 is disabled
42      * TODO: The default will be changed to 0 in Tomcat 10
43      */

44     protected int processorCache = 500;
45
46     /**
47      * Enable/disable poller event cache, this bounded cache stores
48      * PollerEvent objects to reduce GC for the poller
49      * Default is 500
50      * -1 is unlimited
51      * 0 is disabled
52      * >0 the max number of objects to keep in cache.
53      * TODO: The default will be changed to 0 in Tomcat 10
54      */

55     protected int eventCache = 500;
56
57     /**
58      * Enable/disable direct buffers for the network buffers
59      * Default value is disabled
60      */

61     protected boolean directBuffer = false;
62
63     /**
64      * Enable/disable direct buffers for the network buffers for SSL
65      * Default value is disabled
66      */

67     protected boolean directSslBuffer = false;
68
69     /**
70      * Socket receive buffer size in bytes (SO_RCVBUF).
71      * JVM default used if not set.
72      */

73     protected Integer rxBufSize = null;
74
75     /**
76      * Socket send buffer size in bytes (SO_SNDBUF).
77      * JVM default used if not set.
78      */

79     protected Integer txBufSize = null;
80
81     /**
82      * The application read buffer size in bytes.
83      * Default value is rxBufSize
84      */

85     protected int appReadBufSize = 8192;
86
87     /**
88      * The application write buffer size in bytes
89      * Default value is txBufSize
90      */

91     protected int appWriteBufSize = 8192;
92
93     /**
94      * NioChannel pool size for the endpoint,
95      * this value is how many channels
96      * -1 means unlimited cached, 0 means no cache
97      * Default value is 500
98      * TODO: The default should be changed in Tomcat 10, actually it should be
99      *   bufferPoolSize / (appReadBufSize + appWriteBufSize), assuming the SSL
100      *   buffers are ignored (that would be logical), and the value would be 6400.
101      *   So the default value will be changed to a new default value like -2 to
102      *   set a dynamic value based on bufferPoolSize in that case.
103      */

104     protected int bufferPool = 500;
105
106     /**
107      * Buffer pool size in bytes to be cached
108      * -1 means unlimited, 0 means no cache
109      * Default value is 100MB (1024*1024*100 bytes)
110      * TODO: The default value to be used could rather be based on the
111      *   JVM max heap, otherwise it could be a problem in some
112      *   environments. Big servers also need to use a much higher default,
113      *   while small cloud based ones should use 0 instead.
114      *   Possible default value strategy:
115      *     heap inf 1GB: 0
116      *     heap sup 1GB: heap / 32
117      */

118     protected int bufferPoolSize = 1024*1024*100;
119
120     /**
121      * TCP_NO_DELAY option. JVM default used if not set.
122      */

123     protected Boolean tcpNoDelay = Boolean.TRUE;
124
125     /**
126      * SO_KEEPALIVE option. JVM default used if not set.
127      */

128     protected Boolean soKeepAlive = null;
129
130     /**
131      * OOBINLINE option. JVM default used if not set.
132      */

133     protected Boolean ooBInline = null;
134
135     /**
136      * SO_REUSEADDR option. JVM default used if not set.
137      */

138     protected Boolean soReuseAddress = null;
139
140     /**
141      * SO_LINGER option, paired with the <code>soLingerTime</code> value.
142      * JVM defaults used unless both attributes are set.
143      */

144     protected Boolean soLingerOn = null;
145
146     /**
147      * SO_LINGER option, paired with the <code>soLingerOn</code> value.
148      * JVM defaults used unless both attributes are set.
149      */

150     protected Integer soLingerTime = null;
151
152     /**
153      * SO_TIMEOUT option. default is 20000.
154      */

155     protected Integer soTimeout = Integer.valueOf(20000);
156
157     /**
158      * Performance preferences according to
159      * http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
160      * All three performance attributes must be set or the JVM defaults will be
161      * used.
162      */

163     protected Integer performanceConnectionTime = null;
164
165     /**
166      * Performance preferences according to
167      * http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
168      * All three performance attributes must be set or the JVM defaults will be
169      * used.
170      */

171     protected Integer performanceLatency = null;
172
173     /**
174      * Performance preferences according to
175      * http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#setPerformancePreferences(int,%20int,%20int)
176      * All three performance attributes must be set or the JVM defaults will be
177      * used.
178      */

179     protected Integer performanceBandwidth = null;
180
181     /**
182      * The minimum frequency of the timeout interval to avoid excess load from
183      * the poller during high traffic
184      */

185     protected long timeoutInterval = 1000;
186
187     /**
188      * Timeout in milliseconds for an unlock to take place.
189      */

190     protected int unlockTimeout = 250;
191
192     private ObjectName oname = null;
193
194
195     public void setProperties(Socket socket) throws SocketException{
196         if (rxBufSize != null)
197             socket.setReceiveBufferSize(rxBufSize.intValue());
198         if (txBufSize != null)
199             socket.setSendBufferSize(txBufSize.intValue());
200         if (ooBInline !=null)
201             socket.setOOBInline(ooBInline.booleanValue());
202         if (soKeepAlive != null)
203             socket.setKeepAlive(soKeepAlive.booleanValue());
204         if (performanceConnectionTime != null && performanceLatency != null &&
205                 performanceBandwidth != null)
206             socket.setPerformancePreferences(
207                     performanceConnectionTime.intValue(),
208                     performanceLatency.intValue(),
209                     performanceBandwidth.intValue());
210         if (soReuseAddress != null)
211             socket.setReuseAddress(soReuseAddress.booleanValue());
212         if (soLingerOn != null && soLingerTime != null)
213             socket.setSoLinger(soLingerOn.booleanValue(),
214                     soLingerTime.intValue());
215         if (soTimeout != null && soTimeout.intValue() >= 0)
216             socket.setSoTimeout(soTimeout.intValue());
217         if (tcpNoDelay != null) {
218             try {
219                 socket.setTcpNoDelay(tcpNoDelay.booleanValue());
220             } catch (SocketException e) {
221                 // Some socket types may not support this option which is set by default
222             }
223         }
224     }
225
226     public void setProperties(ServerSocket socket) throws SocketException{
227         if (rxBufSize != null)
228             socket.setReceiveBufferSize(rxBufSize.intValue());
229         if (performanceConnectionTime != null && performanceLatency != null &&
230                 performanceBandwidth != null)
231             socket.setPerformancePreferences(
232                     performanceConnectionTime.intValue(),
233                     performanceLatency.intValue(),
234                     performanceBandwidth.intValue());
235         if (soReuseAddress != null)
236             socket.setReuseAddress(soReuseAddress.booleanValue());
237         if (soTimeout != null && soTimeout.intValue() >= 0)
238             socket.setSoTimeout(soTimeout.intValue());
239     }
240
241     public void setProperties(AsynchronousSocketChannel socket) throws IOException {
242         if (rxBufSize != null)
243             socket.setOption(StandardSocketOptions.SO_RCVBUF, rxBufSize);
244         if (txBufSize != null)
245             socket.setOption(StandardSocketOptions.SO_SNDBUF, txBufSize);
246         if (soKeepAlive != null)
247             socket.setOption(StandardSocketOptions.SO_KEEPALIVE, soKeepAlive);
248         if (soReuseAddress != null)
249             socket.setOption(StandardSocketOptions.SO_REUSEADDR, soReuseAddress);
250         if (soLingerOn != null && soLingerOn.booleanValue() && soLingerTime != null)
251             socket.setOption(StandardSocketOptions.SO_LINGER, soLingerTime);
252         if (tcpNoDelay != null)
253             socket.setOption(StandardSocketOptions.TCP_NODELAY, tcpNoDelay);
254     }
255
256     public void setProperties(AsynchronousServerSocketChannel socket) throws IOException {
257         if (rxBufSize != null)
258             socket.setOption(StandardSocketOptions.SO_RCVBUF, rxBufSize);
259         if (soReuseAddress != null)
260             socket.setOption(StandardSocketOptions.SO_REUSEADDR, soReuseAddress);
261     }
262
263     public boolean getDirectBuffer() {
264         return directBuffer;
265     }
266
267     public boolean getDirectSslBuffer() {
268         return directSslBuffer;
269     }
270
271     public boolean getOoBInline() {
272         return ooBInline.booleanValue();
273     }
274
275     public int getPerformanceBandwidth() {
276         return performanceBandwidth.intValue();
277     }
278
279     public int getPerformanceConnectionTime() {
280         return performanceConnectionTime.intValue();
281     }
282
283     public int getPerformanceLatency() {
284         return performanceLatency.intValue();
285     }
286
287     public int getRxBufSize() {
288         return rxBufSize.intValue();
289     }
290
291     public boolean getSoKeepAlive() {
292         return soKeepAlive.booleanValue();
293     }
294
295     public boolean getSoLingerOn() {
296         return soLingerOn.booleanValue();
297     }
298
299     public int getSoLingerTime() {
300         return soLingerTime.intValue();
301     }
302
303     public boolean getSoReuseAddress() {
304         return soReuseAddress.booleanValue();
305     }
306
307     public int getSoTimeout() {
308         return soTimeout.intValue();
309     }
310
311     public boolean getTcpNoDelay() {
312         return tcpNoDelay.booleanValue();
313     }
314
315     public int getTxBufSize() {
316         return txBufSize.intValue();
317     }
318
319     public int getBufferPool() {
320         return bufferPool;
321     }
322
323     public int getBufferPoolSize() {
324         return bufferPoolSize;
325     }
326
327     public int getEventCache() {
328         return eventCache;
329     }
330
331     public int getAppReadBufSize() {
332         return appReadBufSize;
333     }
334
335     public int getAppWriteBufSize() {
336         return appWriteBufSize;
337     }
338
339     public int getProcessorCache() {
340         return processorCache;
341     }
342
343     public long getTimeoutInterval() {
344         return timeoutInterval;
345     }
346
347     public int getDirectBufferPool() {
348         return bufferPool;
349     }
350
351     public void setPerformanceConnectionTime(int performanceConnectionTime) {
352         this.performanceConnectionTime =
353             Integer.valueOf(performanceConnectionTime);
354     }
355
356     public void setTxBufSize(int txBufSize) {
357         this.txBufSize = Integer.valueOf(txBufSize);
358     }
359
360     public void setTcpNoDelay(boolean tcpNoDelay) {
361         this.tcpNoDelay = Boolean.valueOf(tcpNoDelay);
362     }
363
364     public void setSoTimeout(int soTimeout) {
365         this.soTimeout = Integer.valueOf(soTimeout);
366     }
367
368     public void setSoReuseAddress(boolean soReuseAddress) {
369         this.soReuseAddress = Boolean.valueOf(soReuseAddress);
370     }
371
372     public void setSoLingerTime(int soLingerTime) {
373         this.soLingerTime = Integer.valueOf(soLingerTime);
374     }
375
376     public void setSoKeepAlive(boolean soKeepAlive) {
377         this.soKeepAlive = Boolean.valueOf(soKeepAlive);
378     }
379
380     public void setRxBufSize(int rxBufSize) {
381         this.rxBufSize = Integer.valueOf(rxBufSize);
382     }
383
384     public void setPerformanceLatency(int performanceLatency) {
385         this.performanceLatency = Integer.valueOf(performanceLatency);
386     }
387
388     public void setPerformanceBandwidth(int performanceBandwidth) {
389         this.performanceBandwidth = Integer.valueOf(performanceBandwidth);
390     }
391
392     public void setOoBInline(boolean ooBInline) {
393         this.ooBInline = Boolean.valueOf(ooBInline);
394     }
395
396     public void setDirectBuffer(boolean directBuffer) {
397         this.directBuffer = directBuffer;
398     }
399
400     public void setDirectSslBuffer(boolean directSslBuffer) {
401         this.directSslBuffer = directSslBuffer;
402     }
403
404     public void setSoLingerOn(boolean soLingerOn) {
405         this.soLingerOn = Boolean.valueOf(soLingerOn);
406     }
407
408     public void setBufferPool(int bufferPool) {
409         this.bufferPool = bufferPool;
410     }
411
412     public void setBufferPoolSize(int bufferPoolSize) {
413         this.bufferPoolSize = bufferPoolSize;
414     }
415
416     public void setEventCache(int eventCache) {
417         this.eventCache = eventCache;
418     }
419
420     public void setAppReadBufSize(int appReadBufSize) {
421         this.appReadBufSize = appReadBufSize;
422     }
423
424     public void setAppWriteBufSize(int appWriteBufSize) {
425         this.appWriteBufSize = appWriteBufSize;
426     }
427
428     public void setProcessorCache(int processorCache) {
429         this.processorCache = processorCache;
430     }
431
432     public void setTimeoutInterval(long timeoutInterval) {
433         this.timeoutInterval = timeoutInterval;
434     }
435
436     public void setDirectBufferPool(int directBufferPool) {
437         this.bufferPool = directBufferPool;
438     }
439
440     public int getUnlockTimeout() {
441         return unlockTimeout;
442     }
443
444     public void setUnlockTimeout(int unlockTimeout) {
445         this.unlockTimeout = unlockTimeout;
446     }
447
448     void setObjectName(ObjectName oname) {
449         this.oname = oname;
450     }
451
452     ObjectName getObjectName() {
453         return oname;
454     }
455 }
456