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.ByteBuf;
19 import io.netty.channel.Channel;
20 import io.netty.channel.ChannelException;
21 import io.netty.channel.ChannelOutboundBuffer;
22 import io.netty.channel.socket.InternetProtocolFamily;
23 import io.netty.channel.socket.ServerSocketChannel;
24 import io.netty.channel.socket.SocketChannel;
25 import io.netty.util.concurrent.GlobalEventExecutor;
26
27 import java.io.IOException;
28 import java.net.InetAddress;
29 import java.net.InetSocketAddress;
30 import java.net.SocketAddress;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Map;
34 import java.util.concurrent.Executor;
35
36 import static io.netty.channel.epoll.LinuxSocket.newSocketStream;
37 import static io.netty.channel.epoll.Native.IS_SUPPORTING_TCP_FASTOPEN_CLIENT;
38
39
40
41
42
43 public final class EpollSocketChannel extends AbstractEpollStreamChannel implements SocketChannel {
44
45 private final EpollSocketChannelConfig config;
46
47 private volatile Collection<InetAddress> tcpMd5SigAddresses = Collections.emptyList();
48
49 public EpollSocketChannel() {
50 super(newSocketStream(), false);
51 config = new EpollSocketChannelConfig(this);
52 }
53
54 public EpollSocketChannel(InternetProtocolFamily protocol) {
55 super(newSocketStream(protocol), false);
56 config = new EpollSocketChannelConfig(this);
57 }
58
59 public EpollSocketChannel(int fd) {
60 super(fd);
61 config = new EpollSocketChannelConfig(this);
62 }
63
64 EpollSocketChannel(LinuxSocket fd, boolean active) {
65 super(fd, active);
66 config = new EpollSocketChannelConfig(this);
67 }
68
69 EpollSocketChannel(Channel parent, LinuxSocket fd, InetSocketAddress remoteAddress) {
70 super(parent, fd, remoteAddress);
71 config = new EpollSocketChannelConfig(this);
72
73 if (parent instanceof EpollServerSocketChannel) {
74 tcpMd5SigAddresses = ((EpollServerSocketChannel) parent).tcpMd5SigAddresses();
75 }
76 }
77
78
79
80
81
82 public EpollTcpInfo tcpInfo() {
83 return tcpInfo(new EpollTcpInfo());
84 }
85
86
87
88
89
90 public EpollTcpInfo tcpInfo(EpollTcpInfo info) {
91 try {
92 socket.getTcpInfo(info);
93 return info;
94 } catch (IOException e) {
95 throw new ChannelException(e);
96 }
97 }
98
99 @Override
100 public InetSocketAddress remoteAddress() {
101 return (InetSocketAddress) super.remoteAddress();
102 }
103
104 @Override
105 public InetSocketAddress localAddress() {
106 return (InetSocketAddress) super.localAddress();
107 }
108
109 @Override
110 public EpollSocketChannelConfig config() {
111 return config;
112 }
113
114 @Override
115 public ServerSocketChannel parent() {
116 return (ServerSocketChannel) super.parent();
117 }
118
119 @Override
120 protected AbstractEpollUnsafe newUnsafe() {
121 return new EpollSocketChannelUnsafe();
122 }
123
124 @Override
125 boolean doConnect0(SocketAddress remote) throws Exception {
126 if (IS_SUPPORTING_TCP_FASTOPEN_CLIENT && config.isTcpFastOpenConnect()) {
127 ChannelOutboundBuffer outbound = unsafe().outboundBuffer();
128 outbound.addFlush();
129 Object curr;
130 if ((curr = outbound.current()) instanceof ByteBuf) {
131 ByteBuf initialData = (ByteBuf) curr;
132
133
134 long localFlushedAmount = doWriteOrSendBytes(
135 initialData, (InetSocketAddress) remote, true);
136 if (localFlushedAmount > 0) {
137
138
139 outbound.removeBytes(localFlushedAmount);
140 return true;
141 }
142 }
143 }
144 return super.doConnect0(remote);
145 }
146
147 private final class EpollSocketChannelUnsafe extends EpollStreamUnsafe {
148 @Override
149 protected Executor prepareToClose() {
150 try {
151
152
153 if (isOpen() && config().getSoLinger() > 0) {
154
155
156
157
158 ((EpollEventLoop) eventLoop()).remove(EpollSocketChannel.this);
159 return GlobalEventExecutor.INSTANCE;
160 }
161 } catch (Throwable ignore) {
162
163
164
165 }
166 return null;
167 }
168 }
169
170 void setTcpMd5Sig(Map<InetAddress, byte[]> keys) throws IOException {
171
172 synchronized (this) {
173 tcpMd5SigAddresses = TcpMd5Util.newTcpMd5Sigs(this, tcpMd5SigAddresses, keys);
174 }
175 }
176 }