View Javadoc
1   /*
2    * Copyright 2016 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.epoll;
17  
18  import io.netty.channel.DefaultFileRegion;
19  import io.netty.channel.unix.Errors.NativeIoException;
20  import io.netty.channel.unix.NativeInetAddress;
21  import io.netty.channel.unix.PeerCredentials;
22  import io.netty.channel.unix.Socket;
23  import io.netty.util.internal.ThrowableUtil;
24  
25  import java.io.IOException;
26  import java.net.InetAddress;
27  import java.nio.channels.ClosedChannelException;
28  
29  import static io.netty.channel.unix.Errors.ERRNO_EPIPE_NEGATIVE;
30  import static io.netty.channel.unix.Errors.ioResult;
31  import static io.netty.channel.unix.Errors.newConnectionResetException;
32  
33  /**
34   * A socket which provides access Linux native methods.
35   */
36  final class LinuxSocket extends Socket {
37      private static final long MAX_UINT32_T = 0xFFFFFFFFL;
38      private static final NativeIoException SENDFILE_CONNECTION_RESET_EXCEPTION =
39              newConnectionResetException("syscall:sendfile(...)", ERRNO_EPIPE_NEGATIVE);
40      private static final ClosedChannelException SENDFILE_CLOSED_CHANNEL_EXCEPTION = ThrowableUtil.unknownStackTrace(
41              new ClosedChannelException(), Native.class, "sendfile(...)");
42  
43      public LinuxSocket(int fd) {
44          super(fd);
45      }
46  
47      void setTcpDeferAccept(int deferAccept) throws IOException {
48          setTcpDeferAccept(intValue(), deferAccept);
49      }
50  
51      void setTcpQuickAck(boolean quickAck) throws IOException {
52          setTcpQuickAck(intValue(), quickAck ? 1 : 0);
53      }
54  
55      void setTcpCork(boolean tcpCork) throws IOException {
56          setTcpCork(intValue(), tcpCork ? 1 : 0);
57      }
58  
59      void setSoBusyPoll(int loopMicros) throws IOException {
60          setSoBusyPoll(intValue(), loopMicros);
61      }
62  
63      void setTcpNotSentLowAt(long tcpNotSentLowAt) throws IOException {
64          if (tcpNotSentLowAt < 0 || tcpNotSentLowAt > MAX_UINT32_T) {
65              throw new IllegalArgumentException("tcpNotSentLowAt must be a uint32_t");
66          }
67          setTcpNotSentLowAt(intValue(), (int) tcpNotSentLowAt);
68      }
69  
70      void setTcpFastOpen(int tcpFastopenBacklog) throws IOException {
71          setTcpFastOpen(intValue(), tcpFastopenBacklog);
72      }
73  
74      void setTcpFastOpenConnect(boolean tcpFastOpenConnect) throws IOException {
75          setTcpFastOpenConnect(intValue(), tcpFastOpenConnect ? 1 : 0);
76      }
77  
78      boolean isTcpFastOpenConnect() throws IOException {
79          return isTcpFastOpenConnect(intValue()) != 0;
80      }
81  
82      void setTcpKeepIdle(int seconds) throws IOException {
83          setTcpKeepIdle(intValue(), seconds);
84      }
85  
86      void setTcpKeepIntvl(int seconds) throws IOException {
87          setTcpKeepIntvl(intValue(), seconds);
88      }
89  
90      void setTcpKeepCnt(int probes) throws IOException {
91          setTcpKeepCnt(intValue(), probes);
92      }
93  
94      void setTcpUserTimeout(int milliseconds) throws IOException {
95          setTcpUserTimeout(intValue(), milliseconds);
96      }
97  
98      void setIpFreeBind(boolean enabled) throws IOException {
99          setIpFreeBind(intValue(), enabled ? 1 : 0);
100     }
101 
102     void setIpTransparent(boolean enabled) throws IOException {
103         setIpTransparent(intValue(), enabled ? 1 : 0);
104     }
105 
106     void setIpRecvOrigDestAddr(boolean enabled) throws IOException {
107         setIpRecvOrigDestAddr(intValue(), enabled ? 1 : 0);
108     }
109 
110     void getTcpInfo(EpollTcpInfo info) throws IOException {
111         getTcpInfo(intValue(), info.info);
112     }
113 
114     void setTcpMd5Sig(InetAddress address, byte[] key) throws IOException {
115         final NativeInetAddress a = NativeInetAddress.newInstance(address);
116         setTcpMd5Sig(intValue(), a.address(), a.scopeId(), key);
117     }
118 
119     boolean isTcpCork() throws IOException  {
120         return isTcpCork(intValue()) != 0;
121     }
122 
123     int getSoBusyPoll() throws IOException  {
124         return getSoBusyPoll(intValue());
125     }
126 
127     int getTcpDeferAccept() throws IOException {
128         return getTcpDeferAccept(intValue());
129     }
130 
131     boolean isTcpQuickAck() throws IOException {
132         return isTcpQuickAck(intValue()) != 0;
133     }
134 
135     long getTcpNotSentLowAt() throws IOException {
136         return getTcpNotSentLowAt(intValue()) & MAX_UINT32_T;
137     }
138 
139     int getTcpKeepIdle() throws IOException {
140         return getTcpKeepIdle(intValue());
141     }
142 
143     int getTcpKeepIntvl() throws IOException {
144         return getTcpKeepIntvl(intValue());
145     }
146 
147     int getTcpKeepCnt() throws IOException {
148         return getTcpKeepCnt(intValue());
149     }
150 
151     int getTcpUserTimeout() throws IOException {
152         return getTcpUserTimeout(intValue());
153     }
154 
155     boolean isIpFreeBind() throws IOException {
156         return isIpFreeBind(intValue()) != 0;
157     }
158 
159     boolean isIpTransparent() throws IOException {
160         return isIpTransparent(intValue()) != 0;
161     }
162 
163     boolean isIpRecvOrigDestAddr() throws IOException {
164         return isIpRecvOrigDestAddr(intValue()) != 0;
165     }
166 
167     PeerCredentials getPeerCredentials() throws IOException {
168         return getPeerCredentials(intValue());
169     }
170 
171     long sendFile(DefaultFileRegion src, long baseOffset, long offset, long length) throws IOException {
172         // Open the file-region as it may be created via the lazy constructor. This is needed as we directly access
173         // the FileChannel field via JNI.
174         src.open();
175 
176         long res = sendFile(intValue(), src, baseOffset, offset, length);
177         if (res >= 0) {
178             return res;
179         }
180         return ioResult("sendfile", (int) res, SENDFILE_CONNECTION_RESET_EXCEPTION, SENDFILE_CLOSED_CHANNEL_EXCEPTION);
181     }
182 
183     public static LinuxSocket newSocketStream() {
184         return new LinuxSocket(newSocketStream0());
185     }
186 
187     public static LinuxSocket newSocketDgram() {
188         return new LinuxSocket(newSocketDgram0());
189     }
190 
191     public static LinuxSocket newSocketDomain() {
192         return new LinuxSocket(newSocketDomain0());
193     }
194 
195     private static native long sendFile(int socketFd, DefaultFileRegion src, long baseOffset,
196                                         long offset, long length) throws IOException;
197 
198     private static native int getTcpDeferAccept(int fd) throws IOException;
199     private static native int isTcpQuickAck(int fd) throws IOException;
200     private static native int isTcpCork(int fd) throws IOException;
201     private static native int getSoBusyPoll(int fd) throws IOException;
202     private static native int getTcpNotSentLowAt(int fd) throws IOException;
203     private static native int getTcpKeepIdle(int fd) throws IOException;
204     private static native int getTcpKeepIntvl(int fd) throws IOException;
205     private static native int getTcpKeepCnt(int fd) throws IOException;
206     private static native int getTcpUserTimeout(int fd) throws IOException;
207     private static native int isIpFreeBind(int fd) throws IOException;
208     private static native int isIpTransparent(int fd) throws IOException;
209     private static native int isIpRecvOrigDestAddr(int fd) throws IOException;
210     private static native void getTcpInfo(int fd, long[] array) throws IOException;
211     private static native PeerCredentials getPeerCredentials(int fd) throws IOException;
212     private static native int isTcpFastOpenConnect(int fd) throws IOException;
213 
214     private static native void setTcpDeferAccept(int fd, int deferAccept) throws IOException;
215     private static native void setTcpQuickAck(int fd, int quickAck) throws IOException;
216     private static native void setTcpCork(int fd, int tcpCork) throws IOException;
217     private static native void setSoBusyPoll(int fd, int loopMicros) throws IOException;
218     private static native void setTcpNotSentLowAt(int fd, int tcpNotSentLowAt) throws IOException;
219     private static native void setTcpFastOpen(int fd, int tcpFastopenBacklog) throws IOException;
220     private static native void setTcpFastOpenConnect(int fd, int tcpFastOpenConnect) throws IOException;
221     private static native void setTcpKeepIdle(int fd, int seconds) throws IOException;
222     private static native void setTcpKeepIntvl(int fd, int seconds) throws IOException;
223     private static native void setTcpKeepCnt(int fd, int probes) throws IOException;
224     private static native void setTcpUserTimeout(int fd, int milliseconds)throws IOException;
225     private static native void setIpFreeBind(int fd, int freeBind) throws IOException;
226     private static native void setIpTransparent(int fd, int transparent) throws IOException;
227     private static native void setIpRecvOrigDestAddr(int fd, int transparent) throws IOException;
228     private static native void setTcpMd5Sig(int fd, byte[] address, int scopeId, byte[] key) throws IOException;
229 }