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