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.channel.Channel;
19 import io.netty.channel.ChannelException;
20 import io.netty.channel.socket.ServerSocketChannel;
21 import io.netty.channel.socket.SocketChannel;
22 import io.netty.channel.unix.FileDescriptor;
23 import io.netty.channel.unix.Socket;
24 import io.netty.util.concurrent.GlobalEventExecutor;
25
26 import java.io.IOException;
27 import java.net.InetAddress;
28 import java.net.InetSocketAddress;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Map;
32 import java.util.concurrent.Executor;
33
34 import static io.netty.channel.unix.Socket.newSocketStream;
35
36
37
38
39
40 public final class EpollSocketChannel extends AbstractEpollStreamChannel implements SocketChannel {
41
42 private final EpollSocketChannelConfig config;
43
44 private volatile Collection<InetAddress> tcpMd5SigAddresses = Collections.emptyList();
45
46 public EpollSocketChannel() {
47 super(newSocketStream(), false);
48 config = new EpollSocketChannelConfig(this);
49 }
50
51
52
53
54 @Deprecated
55 public EpollSocketChannel(FileDescriptor fd) {
56 super(fd);
57 config = new EpollSocketChannelConfig(this);
58 }
59
60
61
62
63 public EpollSocketChannel(Socket fd, boolean active) {
64 super(fd, active);
65 config = new EpollSocketChannelConfig(this);
66 }
67
68 EpollSocketChannel(Channel parent, Socket fd, InetSocketAddress remoteAddress) {
69 super(parent, fd, remoteAddress);
70 config = new EpollSocketChannelConfig(this);
71
72 if (parent instanceof EpollServerSocketChannel) {
73 tcpMd5SigAddresses = ((EpollServerSocketChannel) parent).tcpMd5SigAddresses();
74 }
75 }
76
77
78
79
80 public EpollTcpInfo tcpInfo() {
81 return tcpInfo(new EpollTcpInfo());
82 }
83
84
85
86
87
88 public EpollTcpInfo tcpInfo(EpollTcpInfo info) {
89 try {
90 Native.tcpInfo(fd().intValue(), info);
91 return info;
92 } catch (IOException e) {
93 throw new ChannelException(e);
94 }
95 }
96
97 @Override
98 public InetSocketAddress remoteAddress() {
99 return (InetSocketAddress) super.remoteAddress();
100 }
101
102 @Override
103 public InetSocketAddress localAddress() {
104 return (InetSocketAddress) super.localAddress();
105 }
106
107 @Override
108 public EpollSocketChannelConfig config() {
109 return config;
110 }
111
112 @Override
113 public ServerSocketChannel parent() {
114 return (ServerSocketChannel) super.parent();
115 }
116
117 @Override
118 protected AbstractEpollUnsafe newUnsafe() {
119 return new EpollSocketChannelUnsafe();
120 }
121
122 private final class EpollSocketChannelUnsafe extends EpollStreamUnsafe {
123 @Override
124 protected Executor prepareToClose() {
125 try {
126
127
128 if (isOpen() && config().getSoLinger() > 0) {
129
130
131
132
133 ((EpollEventLoop) eventLoop()).remove(EpollSocketChannel.this);
134 return GlobalEventExecutor.INSTANCE;
135 }
136 } catch (Throwable ignore) {
137
138
139
140 }
141 return null;
142 }
143 }
144
145 void setTcpMd5Sig(Map<InetAddress, byte[]> keys) throws IOException {
146 tcpMd5SigAddresses = TcpMd5Util.newTcpMd5Sigs(this, tcpMd5SigAddresses, keys);
147 }
148 }