8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.net.rdma;
27
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.OutputStream;
31 import java.io.FileDescriptor;
32 import java.lang.reflect.Field;
33 import java.net.InetAddress;
34 import java.net.Inet4Address;
35 import java.net.Inet6Address;
36 import java.net.ProtocolFamily;
37 import java.net.ServerSocket;
38 import java.net.Socket;
39 import java.net.SocketImpl;
40 import java.net.SocketOption;
41 import java.net.SocketException;
42 import java.net.StandardProtocolFamily;
43 import java.net.UnknownHostException;
44 import java.net.InetAddress;
45 import java.net.SocketAddress;
46 import java.net.InetSocketAddress;
47 import java.net.StandardSocketOptions;
48 import java.net.SocketOptions;
49 import java.security.AccessController;
50 import java.security.PrivilegedAction;
51 import java.util.Objects;
52 import java.util.Set;
53 import sun.nio.ch.Net;
54 import sun.net.ConnectionResetException;
55 import sun.net.ext.RdmaSocketOptions;
56
57 public abstract class RdmaSocketImpl extends SocketImpl
58 {
59 private ProtocolFamily family;
60
61 Socket socket = null;
62 ServerSocket serverSocket = null;
63
64 int timeout; // timeout in millisec
65
66 int trafficClass;
67
68 InputStream socketInputStream;
69 OutputStream socketOutputStream;
70
71 private boolean shut_rd = false;
72 private boolean shut_wr = false;
73
74 /* number of threads using the FileDescriptor */
75 protected int fdUseCount = 0;
105 });
106 UnsupportedOperationException uoe = null;
107 try {
108 initProto();
109 } catch (UnsupportedOperationException e) {
110 uoe = e;
111 }
112 unsupported = uoe;
113 }
114
115 private static final Void checkSupported() {
116 if (unsupported != null) {
117 Exception e = unsupported;
118 throw new UnsupportedOperationException(e.getMessage(), e);
119 } else {
120 return null;
121 }
122 }
123
124 public RdmaSocketImpl(ProtocolFamily family) {
125 this(checkSupported());
126 Objects.requireNonNull(family, "'family' is null");
127 if ((family != StandardProtocolFamily.INET) &&
128 (family != StandardProtocolFamily.INET6)) {
129 throw new UnsupportedOperationException(
130 "Protocol family not supported");
131 }
132 if (family == StandardProtocolFamily.INET6) {
133 if (!Net.isIPv6Available()) {
134 throw new UnsupportedOperationException(
135 "IPv6 not available");
136 }
137 }
138 this.family = family;
139 }
140
141 private RdmaSocketImpl(Void unused) { }
142
143 private static volatile boolean checkedRdma;
144 private static volatile boolean isRdmaAvailable;
145
146 boolean isRdmaAvailable() {
147 if (!checkedRdma) {
148 isRdmaAvailable = isRdmaAvailable0();
149 checkedRdma = true;
150 }
151 return isRdmaAvailable;
152 }
153
154 void setSocket(Socket soc) {
155 this.socket = soc;
156 }
157
158 Socket getSocket() {
159 return socket;
160 }
161
162 void setServerSocket(ServerSocket soc) {
163 this.serverSocket = soc;
164 }
165
166 ServerSocket getServerSocket() {
167 return serverSocket;
168 }
169
170 @Override
171 protected abstract Set<SocketOption<?>> supportedOptions();
172
173 protected synchronized void create(boolean stream) throws IOException {
174 this.stream = stream;
175 if (stream) {
176 fd = new FileDescriptor();
177
178 boolean preferIPv6 = Net.isIPv6Available() &&
179 (family != StandardProtocolFamily.INET);
180 rdmaSocketCreate(preferIPv6, true);
181 }
182 }
183
184 protected void connect(String host, int port)
185 throws UnknownHostException, IOException {
186 boolean connected = false;
187 try {
188 InetAddress address = InetAddress.getByName(host);
189 this.port = port;
190 this.address = address;
191
192 connectToAddress(address, port, timeout);
193 connected = true;
194 } finally {
195 if (!connected) {
196 try {
197 close();
198 } catch (IOException ioe) {
199 }
200 }
201 }
202 }
203
204 protected void connect(InetAddress address, int port) throws IOException {
205 if (family == StandardProtocolFamily.INET
206 && !(address instanceof Inet4Address))
207 throw new IllegalArgumentException(
208 "address type not match");
209 if (family == StandardProtocolFamily.INET6
210 && !(address instanceof Inet6Address))
211 throw new IllegalArgumentException(
212 "address type not match");
213
214 this.port = port;
215 this.address = address;
216 try {
217 connectToAddress(address, port, timeout);
218 return;
219 } catch (IOException e) {
220 close();
221 throw e;
222 }
223 }
224
225 protected void connect(SocketAddress address, int timeout)
226 throws IOException {
227 boolean connected = false;
228 try {
229 if (address == null || !(address instanceof InetSocketAddress))
230 throw new IllegalArgumentException("unsupported address type");
231 InetSocketAddress addr = (InetSocketAddress) address;
232 InetAddress ia = addr.getAddress();
233 if (family == StandardProtocolFamily.INET
234 && !(ia instanceof Inet4Address))
235 throw new IllegalArgumentException(
236 "address type not match");
237 if (family == StandardProtocolFamily.INET6
238 && !(ia instanceof Inet6Address))
239 throw new IllegalArgumentException(
240 "address type not match");
241 if (addr.isUnresolved())
242 throw new UnknownHostException(addr.getHostName());
243 this.port = addr.getPort();
244 this.address = addr.getAddress();
245
246 connectToAddress(this.address, port, timeout);
247 connected = true;
248 } finally {
249 if (!connected) {
250 try {
251 close();
252 } catch (IOException ioe) {
253 }
254 }
255 }
256 }
257
258 private void connectToAddress(InetAddress address, int port, int timeout)
259 throws IOException {
260 if (address.isAnyLocalAddress()) {
355 }
356
357 protected void socketSetOption(int opt, boolean b, Object val)
358 throws SocketException {
359 if (opt == SocketOptions.SO_REUSEPORT &&
360 !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
361 throw new UnsupportedOperationException("unsupported option");
362 }
363 try {
364 rdmaSocketSetOption(opt, b, val);
365 } catch (SocketException se) {
366 if (socket == null || !socket.isConnected())
367 throw se;
368 }
369 }
370
371 synchronized void doConnect(InetAddress address, int port, int timeout)
372 throws IOException {
373 try {
374 acquireFD();
375 boolean preferIPv6 = Net.isIPv6Available() &&
376 (family != StandardProtocolFamily.INET);
377 try {
378 rdmaSocketConnect(preferIPv6, address, port, timeout);
379 synchronized (fdLock) {
380 if (closePending) {
381 throw new SocketException ("Socket closed");
382 }
383 }
384 } finally {
385 releaseFD();
386 }
387 } catch (IOException e) {
388 close();
389 throw e;
390 }
391 }
392
393 protected synchronized void bind(InetAddress address, int lport)
394 throws IOException {
395 if (address == null)
396 throw new IllegalArgumentException("address is null");
397 if (family == StandardProtocolFamily.INET
398 && !(address instanceof Inet4Address))
399 throw new IllegalArgumentException(
400 "address type not match");
401 if (family == StandardProtocolFamily.INET6
402 && !(address instanceof Inet6Address))
403 throw new IllegalArgumentException(
404 "address type not match");
405 boolean preferIPv6 = Net.isIPv6Available() &&
406 (family != StandardProtocolFamily.INET);
407 rdmaSocketBind(preferIPv6, address, lport);
408 }
409
410 protected synchronized void listen(int count) throws IOException {
411 rdmaSocketListen(count);
412 }
413
414 protected void accept(SocketImpl s) throws IOException {
415 acquireFD();
416 try {
417 rdmaSocketAccept(s);
418 } finally {
419 releaseFD();
420 }
421 }
422
423 protected synchronized InputStream getInputStream() throws IOException {
424 synchronized (fdLock) {
425 if (isClosedOrPending())
426 throw new IOException("Socket Closed");
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.net.rdma;
27
28 import java.io.FileDescriptor;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.net.Inet4Address;
33 import java.net.Inet6Address;
34 import java.net.InetAddress;
35 import java.net.InetSocketAddress;
36 import java.net.ProtocolFamily;
37 import java.net.ServerSocket;
38 import java.net.Socket;
39 import java.net.SocketAddress;
40 import java.net.SocketException;
41 import java.net.SocketImpl;
42 import java.net.SocketOption;
43 import java.net.SocketOptions;
44 import java.net.StandardSocketOptions;
45 import java.net.UnknownHostException;
46 import java.util.Objects;
47 import java.util.Set;
48 import sun.nio.ch.Net;
49 import static java.net.StandardProtocolFamily.INET;
50 import static java.net.StandardProtocolFamily.INET6;
51
52 public abstract class RdmaSocketImpl extends SocketImpl
53 {
54 private ProtocolFamily family;
55
56 Socket socket = null;
57 ServerSocket serverSocket = null;
58
59 int timeout; // timeout in millisec
60
61 int trafficClass;
62
63 InputStream socketInputStream;
64 OutputStream socketOutputStream;
65
66 private boolean shut_rd = false;
67 private boolean shut_wr = false;
68
69 /* number of threads using the FileDescriptor */
70 protected int fdUseCount = 0;
100 });
101 UnsupportedOperationException uoe = null;
102 try {
103 initProto();
104 } catch (UnsupportedOperationException e) {
105 uoe = e;
106 }
107 unsupported = uoe;
108 }
109
110 private static final Void checkSupported() {
111 if (unsupported != null) {
112 Exception e = unsupported;
113 throw new UnsupportedOperationException(e.getMessage(), e);
114 } else {
115 return null;
116 }
117 }
118
119 public RdmaSocketImpl(ProtocolFamily family) {
120 this(checkSupported(), family);
121 }
122
123 private RdmaSocketImpl(Void unused, ProtocolFamily family) {
124 Objects.requireNonNull(family, "null family");
125 if (!(family == INET || family == INET6)) {
126 throw new UnsupportedOperationException("Protocol family not supported");
127 }
128 if (family == INET6) {
129 if (!Net.isIPv6Available()) {
130 throw new UnsupportedOperationException(
131 "IPv6 not available");
132 }
133 }
134 this.family = family;
135 }
136
137 private static volatile boolean checkedRdma;
138 private static volatile boolean isRdmaAvailable;
139
140 boolean isRdmaAvailable() {
141 if (!checkedRdma) {
142 isRdmaAvailable = isRdmaAvailable0();
143 checkedRdma = true;
144 }
145 return isRdmaAvailable;
146 }
147
148 void setSocket(Socket soc) {
149 this.socket = soc;
150 }
151
152 Socket getSocket() {
153 return socket;
154 }
155
156 void setServerSocket(ServerSocket soc) {
157 this.serverSocket = soc;
158 }
159
160 ServerSocket getServerSocket() {
161 return serverSocket;
162 }
163
164 @Override
165 protected abstract Set<SocketOption<?>> supportedOptions();
166
167 protected synchronized void create(boolean stream) throws IOException {
168 this.stream = stream;
169 if (stream) {
170 fd = new FileDescriptor();
171
172 boolean preferIPv6 = Net.isIPv6Available() && (family != INET);
173 rdmaSocketCreate(preferIPv6, true);
174 }
175 }
176
177 protected void connect(String host, int port)
178 throws UnknownHostException, IOException {
179 boolean connected = false;
180 try {
181 InetAddress address = InetAddress.getByName(host);
182 this.port = port;
183 this.address = address;
184
185 connectToAddress(address, port, timeout);
186 connected = true;
187 } finally {
188 if (!connected) {
189 try {
190 close();
191 } catch (IOException ioe) {
192 }
193 }
194 }
195 }
196
197 protected void connect(InetAddress address, int port) throws IOException {
198 if (family == INET && !(address instanceof Inet4Address))
199 throw new IllegalArgumentException("address type mismatch");
200 if (family == INET6 && !(address instanceof Inet6Address))
201 throw new IllegalArgumentException("address type mismatch");
202
203 this.port = port;
204 this.address = address;
205 try {
206 connectToAddress(address, port, timeout);
207 return;
208 } catch (IOException e) {
209 close();
210 throw e;
211 }
212 }
213
214 protected void connect(SocketAddress address, int timeout)
215 throws IOException {
216 boolean connected = false;
217 try {
218 if (address == null || !(address instanceof InetSocketAddress))
219 throw new IllegalArgumentException("unsupported address type");
220 InetSocketAddress addr = (InetSocketAddress) address;
221 InetAddress ia = addr.getAddress();
222 if (family == INET && !(ia instanceof Inet4Address))
223 throw new IllegalArgumentException("address type mismatch");
224 if (family == INET6 && !(ia instanceof Inet6Address))
225 throw new IllegalArgumentException("address type mismatch");
226 if (addr.isUnresolved())
227 throw new UnknownHostException(addr.getHostName());
228 this.port = addr.getPort();
229 this.address = addr.getAddress();
230
231 connectToAddress(this.address, port, timeout);
232 connected = true;
233 } finally {
234 if (!connected) {
235 try {
236 close();
237 } catch (IOException ioe) {
238 }
239 }
240 }
241 }
242
243 private void connectToAddress(InetAddress address, int port, int timeout)
244 throws IOException {
245 if (address.isAnyLocalAddress()) {
340 }
341
342 protected void socketSetOption(int opt, boolean b, Object val)
343 throws SocketException {
344 if (opt == SocketOptions.SO_REUSEPORT &&
345 !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
346 throw new UnsupportedOperationException("unsupported option");
347 }
348 try {
349 rdmaSocketSetOption(opt, b, val);
350 } catch (SocketException se) {
351 if (socket == null || !socket.isConnected())
352 throw se;
353 }
354 }
355
356 synchronized void doConnect(InetAddress address, int port, int timeout)
357 throws IOException {
358 try {
359 acquireFD();
360 boolean preferIPv6 = Net.isIPv6Available() && (family != INET);
361 try {
362 rdmaSocketConnect(preferIPv6, address, port, timeout);
363 synchronized (fdLock) {
364 if (closePending) {
365 throw new SocketException ("Socket closed");
366 }
367 }
368 } finally {
369 releaseFD();
370 }
371 } catch (IOException e) {
372 close();
373 throw e;
374 }
375 }
376
377 private final InetAddress anyLocalAddress() throws IOException {
378 if (family == INET)
379 return InetAddress.getByName("0.0.0.0");
380 else if (family == INET6)
381 return InetAddress.getByName("::");
382 else
383 throw new IllegalArgumentException("Unsupported address type " + family);
384 }
385
386 protected synchronized void bind(InetAddress address, int lport)
387 throws IOException {
388 if (address == null)
389 throw new IllegalArgumentException("address is null");
390
391 if (address.isAnyLocalAddress())
392 address = anyLocalAddress();
393
394 if (family == INET && !(address instanceof Inet4Address))
395 throw new IllegalArgumentException("address type mismatch");
396 if (family == INET6 && !(address instanceof Inet6Address))
397 throw new IllegalArgumentException("address type mismatch");
398 boolean preferIPv6 = Net.isIPv6Available() && (family != INET);
399 rdmaSocketBind(preferIPv6, address, lport);
400 }
401
402 protected synchronized void listen(int count) throws IOException {
403 rdmaSocketListen(count);
404 }
405
406 protected void accept(SocketImpl s) throws IOException {
407 acquireFD();
408 try {
409 rdmaSocketAccept(s);
410 } finally {
411 releaseFD();
412 }
413 }
414
415 protected synchronized InputStream getInputStream() throws IOException {
416 synchronized (fdLock) {
417 if (isClosedOrPending())
418 throw new IOException("Socket Closed");
|