1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.MessageSizeEstimator;
22 import io.netty.channel.RecvByteBufAllocator;
23 import io.netty.channel.WriteBufferWaterMark;
24 import io.netty.channel.socket.SocketChannelConfig;
25 import io.netty.util.internal.PlatformDependent;
26
27 import java.io.IOException;
28 import java.net.InetAddress;
29 import java.util.Map;
30
31 import static io.netty.channel.ChannelOption.ALLOW_HALF_CLOSURE;
32 import static io.netty.channel.ChannelOption.IP_TOS;
33 import static io.netty.channel.ChannelOption.SO_KEEPALIVE;
34 import static io.netty.channel.ChannelOption.SO_LINGER;
35 import static io.netty.channel.ChannelOption.SO_RCVBUF;
36 import static io.netty.channel.ChannelOption.SO_REUSEADDR;
37 import static io.netty.channel.ChannelOption.SO_SNDBUF;
38 import static io.netty.channel.ChannelOption.TCP_NODELAY;
39
40 public final class EpollSocketChannelConfig extends EpollChannelConfig implements SocketChannelConfig {
41 private volatile boolean allowHalfClosure;
42 private volatile boolean tcpFastopen;
43
44
45
46
47 EpollSocketChannelConfig(EpollSocketChannel channel) {
48 super(channel);
49
50 if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
51 setTcpNoDelay(true);
52 }
53 calculateMaxBytesPerGatheringWrite();
54 }
55
56 @Override
57 public Map<ChannelOption<?>, Object> getOptions() {
58 return getOptions(
59 super.getOptions(),
60 SO_RCVBUF, SO_SNDBUF, TCP_NODELAY, SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, IP_TOS,
61 ALLOW_HALF_CLOSURE, EpollChannelOption.TCP_CORK, EpollChannelOption.TCP_NOTSENT_LOWAT,
62 EpollChannelOption.TCP_KEEPCNT, EpollChannelOption.TCP_KEEPIDLE, EpollChannelOption.TCP_KEEPINTVL,
63 EpollChannelOption.TCP_MD5SIG, EpollChannelOption.TCP_QUICKACK, EpollChannelOption.IP_TRANSPARENT,
64 ChannelOption.TCP_FASTOPEN_CONNECT, EpollChannelOption.SO_BUSY_POLL);
65 }
66
67 @SuppressWarnings("unchecked")
68 @Override
69 public <T> T getOption(ChannelOption<T> option) {
70 if (option == SO_RCVBUF) {
71 return (T) Integer.valueOf(getReceiveBufferSize());
72 }
73 if (option == SO_SNDBUF) {
74 return (T) Integer.valueOf(getSendBufferSize());
75 }
76 if (option == TCP_NODELAY) {
77 return (T) Boolean.valueOf(isTcpNoDelay());
78 }
79 if (option == SO_KEEPALIVE) {
80 return (T) Boolean.valueOf(isKeepAlive());
81 }
82 if (option == SO_REUSEADDR) {
83 return (T) Boolean.valueOf(isReuseAddress());
84 }
85 if (option == SO_LINGER) {
86 return (T) Integer.valueOf(getSoLinger());
87 }
88 if (option == IP_TOS) {
89 return (T) Integer.valueOf(getTrafficClass());
90 }
91 if (option == ALLOW_HALF_CLOSURE) {
92 return (T) Boolean.valueOf(isAllowHalfClosure());
93 }
94 if (option == EpollChannelOption.TCP_CORK) {
95 return (T) Boolean.valueOf(isTcpCork());
96 }
97 if (option == EpollChannelOption.TCP_NOTSENT_LOWAT) {
98 return (T) Long.valueOf(getTcpNotSentLowAt());
99 }
100 if (option == EpollChannelOption.TCP_KEEPIDLE) {
101 return (T) Integer.valueOf(getTcpKeepIdle());
102 }
103 if (option == EpollChannelOption.TCP_KEEPINTVL) {
104 return (T) Integer.valueOf(getTcpKeepIntvl());
105 }
106 if (option == EpollChannelOption.TCP_KEEPCNT) {
107 return (T) Integer.valueOf(getTcpKeepCnt());
108 }
109 if (option == EpollChannelOption.TCP_USER_TIMEOUT) {
110 return (T) Integer.valueOf(getTcpUserTimeout());
111 }
112 if (option == EpollChannelOption.TCP_QUICKACK) {
113 return (T) Boolean.valueOf(isTcpQuickAck());
114 }
115 if (option == EpollChannelOption.IP_TRANSPARENT) {
116 return (T) Boolean.valueOf(isIpTransparent());
117 }
118 if (option == ChannelOption.TCP_FASTOPEN_CONNECT) {
119 return (T) Boolean.valueOf(isTcpFastOpenConnect());
120 }
121 if (option == EpollChannelOption.SO_BUSY_POLL) {
122 return (T) Integer.valueOf(getSoBusyPoll());
123 }
124 return super.getOption(option);
125 }
126
127 @Override
128 public <T> boolean setOption(ChannelOption<T> option, T value) {
129 validate(option, value);
130
131 if (option == SO_RCVBUF) {
132 setReceiveBufferSize((Integer) value);
133 } else if (option == SO_SNDBUF) {
134 setSendBufferSize((Integer) value);
135 } else if (option == TCP_NODELAY) {
136 setTcpNoDelay((Boolean) value);
137 } else if (option == SO_KEEPALIVE) {
138 setKeepAlive((Boolean) value);
139 } else if (option == SO_REUSEADDR) {
140 setReuseAddress((Boolean) value);
141 } else if (option == SO_LINGER) {
142 setSoLinger((Integer) value);
143 } else if (option == IP_TOS) {
144 setTrafficClass((Integer) value);
145 } else if (option == ALLOW_HALF_CLOSURE) {
146 setAllowHalfClosure((Boolean) value);
147 } else if (option == EpollChannelOption.TCP_CORK) {
148 setTcpCork((Boolean) value);
149 } else if (option == EpollChannelOption.TCP_NOTSENT_LOWAT) {
150 setTcpNotSentLowAt((Long) value);
151 } else if (option == EpollChannelOption.TCP_KEEPIDLE) {
152 setTcpKeepIdle((Integer) value);
153 } else if (option == EpollChannelOption.TCP_KEEPCNT) {
154 setTcpKeepCnt((Integer) value);
155 } else if (option == EpollChannelOption.TCP_KEEPINTVL) {
156 setTcpKeepIntvl((Integer) value);
157 } else if (option == EpollChannelOption.TCP_USER_TIMEOUT) {
158 setTcpUserTimeout((Integer) value);
159 } else if (option == EpollChannelOption.IP_TRANSPARENT) {
160 setIpTransparent((Boolean) value);
161 } else if (option == EpollChannelOption.TCP_MD5SIG) {
162 @SuppressWarnings("unchecked")
163 final Map<InetAddress, byte[]> m = (Map<InetAddress, byte[]>) value;
164 setTcpMd5Sig(m);
165 } else if (option == EpollChannelOption.TCP_QUICKACK) {
166 setTcpQuickAck((Boolean) value);
167 } else if (option == ChannelOption.TCP_FASTOPEN_CONNECT) {
168 setTcpFastOpenConnect((Boolean) value);
169 } else if (option == EpollChannelOption.SO_BUSY_POLL) {
170 setSoBusyPoll((Integer) value);
171 } else {
172 return super.setOption(option, value);
173 }
174
175 return true;
176 }
177
178 @Override
179 public int getReceiveBufferSize() {
180 try {
181 return ((EpollSocketChannel) channel).socket.getReceiveBufferSize();
182 } catch (IOException e) {
183 throw new ChannelException(e);
184 }
185 }
186
187 @Override
188 public int getSendBufferSize() {
189 try {
190 return ((EpollSocketChannel) channel).socket.getSendBufferSize();
191 } catch (IOException e) {
192 throw new ChannelException(e);
193 }
194 }
195
196 @Override
197 public int getSoLinger() {
198 try {
199 return ((EpollSocketChannel) channel).socket.getSoLinger();
200 } catch (IOException e) {
201 throw new ChannelException(e);
202 }
203 }
204
205 @Override
206 public int getTrafficClass() {
207 try {
208 return ((EpollSocketChannel) channel).socket.getTrafficClass();
209 } catch (IOException e) {
210 throw new ChannelException(e);
211 }
212 }
213
214 @Override
215 public boolean isKeepAlive() {
216 try {
217 return ((EpollSocketChannel) channel).socket.isKeepAlive();
218 } catch (IOException e) {
219 throw new ChannelException(e);
220 }
221 }
222
223 @Override
224 public boolean isReuseAddress() {
225 try {
226 return ((EpollSocketChannel) channel).socket.isReuseAddress();
227 } catch (IOException e) {
228 throw new ChannelException(e);
229 }
230 }
231
232 @Override
233 public boolean isTcpNoDelay() {
234 try {
235 return ((EpollSocketChannel) channel).socket.isTcpNoDelay();
236 } catch (IOException e) {
237 throw new ChannelException(e);
238 }
239 }
240
241
242
243
244 public boolean isTcpCork() {
245 try {
246 return ((EpollSocketChannel) channel).socket.isTcpCork();
247 } catch (IOException e) {
248 throw new ChannelException(e);
249 }
250 }
251
252
253
254
255 public int getSoBusyPoll() {
256 try {
257 return ((EpollSocketChannel) channel).socket.getSoBusyPoll();
258 } catch (IOException e) {
259 throw new ChannelException(e);
260 }
261 }
262
263
264
265
266
267 public long getTcpNotSentLowAt() {
268 try {
269 return ((EpollSocketChannel) channel).socket.getTcpNotSentLowAt();
270 } catch (IOException e) {
271 throw new ChannelException(e);
272 }
273 }
274
275
276
277
278 public int getTcpKeepIdle() {
279 try {
280 return ((EpollSocketChannel) channel).socket.getTcpKeepIdle();
281 } catch (IOException e) {
282 throw new ChannelException(e);
283 }
284 }
285
286
287
288
289 public int getTcpKeepIntvl() {
290 try {
291 return ((EpollSocketChannel) channel).socket.getTcpKeepIntvl();
292 } catch (IOException e) {
293 throw new ChannelException(e);
294 }
295 }
296
297
298
299
300 public int getTcpKeepCnt() {
301 try {
302 return ((EpollSocketChannel) channel).socket.getTcpKeepCnt();
303 } catch (IOException e) {
304 throw new ChannelException(e);
305 }
306 }
307
308
309
310
311 public int getTcpUserTimeout() {
312 try {
313 return ((EpollSocketChannel) channel).socket.getTcpUserTimeout();
314 } catch (IOException e) {
315 throw new ChannelException(e);
316 }
317 }
318
319 @Override
320 public EpollSocketChannelConfig setKeepAlive(boolean keepAlive) {
321 try {
322 ((EpollSocketChannel) channel).socket.setKeepAlive(keepAlive);
323 return this;
324 } catch (IOException e) {
325 throw new ChannelException(e);
326 }
327 }
328
329 @Override
330 public EpollSocketChannelConfig setPerformancePreferences(
331 int connectionTime, int latency, int bandwidth) {
332 return this;
333 }
334
335 @Override
336 public EpollSocketChannelConfig setReceiveBufferSize(int receiveBufferSize) {
337 try {
338 ((EpollSocketChannel) channel).socket.setReceiveBufferSize(receiveBufferSize);
339 return this;
340 } catch (IOException e) {
341 throw new ChannelException(e);
342 }
343 }
344
345 @Override
346 public EpollSocketChannelConfig setReuseAddress(boolean reuseAddress) {
347 try {
348 ((EpollSocketChannel) channel).socket.setReuseAddress(reuseAddress);
349 return this;
350 } catch (IOException e) {
351 throw new ChannelException(e);
352 }
353 }
354
355 @Override
356 public EpollSocketChannelConfig setSendBufferSize(int sendBufferSize) {
357 try {
358 ((EpollSocketChannel) channel).socket.setSendBufferSize(sendBufferSize);
359 calculateMaxBytesPerGatheringWrite();
360 return this;
361 } catch (IOException e) {
362 throw new ChannelException(e);
363 }
364 }
365
366 @Override
367 public EpollSocketChannelConfig setSoLinger(int soLinger) {
368 try {
369 ((EpollSocketChannel) channel).socket.setSoLinger(soLinger);
370 return this;
371 } catch (IOException e) {
372 throw new ChannelException(e);
373 }
374 }
375
376 @Override
377 public EpollSocketChannelConfig setTcpNoDelay(boolean tcpNoDelay) {
378 try {
379 ((EpollSocketChannel) channel).socket.setTcpNoDelay(tcpNoDelay);
380 return this;
381 } catch (IOException e) {
382 throw new ChannelException(e);
383 }
384 }
385
386
387
388
389 public EpollSocketChannelConfig setTcpCork(boolean tcpCork) {
390 try {
391 ((EpollSocketChannel) channel).socket.setTcpCork(tcpCork);
392 return this;
393 } catch (IOException e) {
394 throw new ChannelException(e);
395 }
396 }
397
398
399
400
401 public EpollSocketChannelConfig setSoBusyPoll(int loopMicros) {
402 try {
403 ((EpollSocketChannel) channel).socket.setSoBusyPoll(loopMicros);
404 return this;
405 } catch (IOException e) {
406 throw new ChannelException(e);
407 }
408 }
409
410
411
412
413
414 public EpollSocketChannelConfig setTcpNotSentLowAt(long tcpNotSentLowAt) {
415 try {
416 ((EpollSocketChannel) channel).socket.setTcpNotSentLowAt(tcpNotSentLowAt);
417 return this;
418 } catch (IOException e) {
419 throw new ChannelException(e);
420 }
421 }
422
423 @Override
424 public EpollSocketChannelConfig setTrafficClass(int trafficClass) {
425 try {
426 ((EpollSocketChannel) channel).socket.setTrafficClass(trafficClass);
427 return this;
428 } catch (IOException e) {
429 throw new ChannelException(e);
430 }
431 }
432
433
434
435
436 public EpollSocketChannelConfig setTcpKeepIdle(int seconds) {
437 try {
438 ((EpollSocketChannel) channel).socket.setTcpKeepIdle(seconds);
439 return this;
440 } catch (IOException e) {
441 throw new ChannelException(e);
442 }
443 }
444
445
446
447
448 public EpollSocketChannelConfig setTcpKeepIntvl(int seconds) {
449 try {
450 ((EpollSocketChannel) channel).socket.setTcpKeepIntvl(seconds);
451 return this;
452 } catch (IOException e) {
453 throw new ChannelException(e);
454 }
455 }
456
457
458
459
460 @Deprecated
461 public EpollSocketChannelConfig setTcpKeepCntl(int probes) {
462 return setTcpKeepCnt(probes);
463 }
464
465
466
467
468 public EpollSocketChannelConfig setTcpKeepCnt(int probes) {
469 try {
470 ((EpollSocketChannel) channel).socket.setTcpKeepCnt(probes);
471 return this;
472 } catch (IOException e) {
473 throw new ChannelException(e);
474 }
475 }
476
477
478
479
480 public EpollSocketChannelConfig setTcpUserTimeout(int milliseconds) {
481 try {
482 ((EpollSocketChannel) channel).socket.setTcpUserTimeout(milliseconds);
483 return this;
484 } catch (IOException e) {
485 throw new ChannelException(e);
486 }
487 }
488
489
490
491
492
493 public boolean isIpTransparent() {
494 try {
495 return ((EpollSocketChannel) channel).socket.isIpTransparent();
496 } catch (IOException e) {
497 throw new ChannelException(e);
498 }
499 }
500
501
502
503
504
505 public EpollSocketChannelConfig setIpTransparent(boolean transparent) {
506 try {
507 ((EpollSocketChannel) channel).socket.setIpTransparent(transparent);
508 return this;
509 } catch (IOException e) {
510 throw new ChannelException(e);
511 }
512 }
513
514
515
516
517
518
519 public EpollSocketChannelConfig setTcpMd5Sig(Map<InetAddress, byte[]> keys) {
520 try {
521 ((EpollSocketChannel) channel).setTcpMd5Sig(keys);
522 return this;
523 } catch (IOException e) {
524 throw new ChannelException(e);
525 }
526 }
527
528
529
530
531
532
533 public EpollSocketChannelConfig setTcpQuickAck(boolean quickAck) {
534 try {
535 ((EpollSocketChannel) channel).socket.setTcpQuickAck(quickAck);
536 return this;
537 } catch (IOException e) {
538 throw new ChannelException(e);
539 }
540 }
541
542
543
544
545
546 public boolean isTcpQuickAck() {
547 try {
548 return ((EpollSocketChannel) channel).socket.isTcpQuickAck();
549 } catch (IOException e) {
550 throw new ChannelException(e);
551 }
552 }
553
554
555
556
557
558
559
560 public EpollSocketChannelConfig setTcpFastOpenConnect(boolean fastOpenConnect) {
561 tcpFastopen = fastOpenConnect;
562 return this;
563 }
564
565
566
567
568 public boolean isTcpFastOpenConnect() {
569 return tcpFastopen;
570 }
571
572 @Override
573 public boolean isAllowHalfClosure() {
574 return allowHalfClosure;
575 }
576
577 @Override
578 public EpollSocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure) {
579 this.allowHalfClosure = allowHalfClosure;
580 return this;
581 }
582
583 @Override
584 public EpollSocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
585 super.setConnectTimeoutMillis(connectTimeoutMillis);
586 return this;
587 }
588
589 @Override
590 @Deprecated
591 public EpollSocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
592 super.setMaxMessagesPerRead(maxMessagesPerRead);
593 return this;
594 }
595
596 @Override
597 public EpollSocketChannelConfig setWriteSpinCount(int writeSpinCount) {
598 super.setWriteSpinCount(writeSpinCount);
599 return this;
600 }
601
602 @Override
603 public EpollSocketChannelConfig setAllocator(ByteBufAllocator allocator) {
604 super.setAllocator(allocator);
605 return this;
606 }
607
608 @Override
609 public EpollSocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
610 super.setRecvByteBufAllocator(allocator);
611 return this;
612 }
613
614 @Override
615 public EpollSocketChannelConfig setAutoRead(boolean autoRead) {
616 super.setAutoRead(autoRead);
617 return this;
618 }
619
620 @Override
621 public EpollSocketChannelConfig setAutoClose(boolean autoClose) {
622 super.setAutoClose(autoClose);
623 return this;
624 }
625
626 @Override
627 @Deprecated
628 public EpollSocketChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
629 super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
630 return this;
631 }
632
633 @Override
634 @Deprecated
635 public EpollSocketChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
636 super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
637 return this;
638 }
639
640 @Override
641 public EpollSocketChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
642 super.setWriteBufferWaterMark(writeBufferWaterMark);
643 return this;
644 }
645
646 @Override
647 public EpollSocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
648 super.setMessageSizeEstimator(estimator);
649 return this;
650 }
651
652 @Override
653 public EpollSocketChannelConfig setEpollMode(EpollMode mode) {
654 super.setEpollMode(mode);
655 return this;
656 }
657
658 private void calculateMaxBytesPerGatheringWrite() {
659
660 int newSendBufferSize = getSendBufferSize() << 1;
661 if (newSendBufferSize > 0) {
662 setMaxBytesPerGatheringWrite(newSendBufferSize);
663 }
664 }
665 }