1 /* 2 * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 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 rdma.ch; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.io.FileDescriptor; 32 33 import java.util.Set; 34 import java.util.HashSet; 35 import java.util.Collections; 36 import java.net.Socket; 37 import java.net.ServerSocket; 38 import java.net.SocketImpl; 39 import java.net.SocketOption; 40 import java.net.SocketException; 41 import java.net.UnknownHostException; 42 import java.net.InetAddress; 43 import java.net.SocketAddress; 44 import java.net.InetSocketAddress; 45 import java.net.StandardSocketOptions; 46 import java.net.SocketOptions; 47 import java.lang.reflect.Field; 48 import sun.net.ConnectionResetException; 49 import java.security.AccessController; 50 import java.security.PrivilegedAction; 51 import sun.net.ext.RdmaSocketOptions; 52 53 public class RdmaSocketImpl extends SocketImpl 54 { 55 Socket socket = null; 56 ServerSocket serverSocket = null; 57 58 int timeout; // timeout in millisec 59 60 int trafficClass; 61 62 InputStream socketInputStream; 63 OutputStream socketOutputStream; 64 65 private boolean shut_rd = false; 66 private boolean shut_wr = false; 67 68 /* number of threads using the FileDescriptor */ 69 protected int fdUseCount = 0; 70 71 /* lock when increment/decrementing fdUseCount */ 72 protected final Object fdLock = new Object(); 73 74 /* indicates a close is pending on the file descriptor */ 75 protected boolean closePending = false; 76 77 /* indicates connection reset state */ 78 private int CONNECTION_NOT_RESET = 0; 79 private int CONNECTION_RESET_PENDING = 1; 80 private int CONNECTION_RESET = 2; 81 private int resetState; 82 private final Object resetLock = new Object(); 83 84 /* whether this Socket is a stream (TCP) socket or not (UDP) 85 */ 86 protected boolean stream; 87 88 static final sun.net.ext.RdmaSocketOptions rdmaOptions = 89 sun.net.ext.RdmaSocketOptions.getInstance(); 90 91 private static PlatformRdmaSocketImpl platformRdmaSocketImpl = 92 PlatformRdmaSocketImpl.get(); 93 94 private static Field sCreateState; 95 private static Field sBoundState; 96 private static Field sConnectState; 97 private static Field ssCreateState; 98 private static Field ssBoundState; 99 private static boolean socketStateSet; 100 private static boolean serverSocketStateSet; 101 102 boolean isRdmaAvailable() { 103 return platformRdmaSocketImpl.isRdmaAvailable(); 104 } 105 106 @Override 107 protected void setSocket(Socket soc) { 108 this.socket = soc; 109 try { 110 if (!socketStateSet) { 111 sCreateState = Socket.class.getDeclaredField("created"); 112 sCreateState.setAccessible(true); 113 sBoundState = Socket.class.getDeclaredField("bound"); 114 sBoundState.setAccessible(true); 115 sConnectState= Socket.class.getDeclaredField("connected"); 116 sConnectState.setAccessible(true); 117 sCreateState.setBoolean(socket, false); 118 sBoundState.setBoolean(socket, false); 119 sConnectState.setBoolean(socket, false); 120 } 121 } catch (NoSuchFieldException | IllegalAccessException e) { 122 throw new Error(e); 123 } 124 socketStateSet = true; 125 } 126 127 Socket getSocket() { 128 return socket; 129 } 130 131 @Override 132 protected void setServerSocket(ServerSocket soc) { 133 this.serverSocket = soc; 134 try { 135 if (!serverSocketStateSet) { 136 ssCreateState = ServerSocket.class.getDeclaredField("created"); 137 ssCreateState.setAccessible(true); 138 ssBoundState = ServerSocket.class.getDeclaredField("bound"); 139 ssBoundState.setAccessible(true); 140 ssCreateState.setBoolean(serverSocket, false); 141 ssBoundState.setBoolean(serverSocket, false); 142 } 143 } catch (NoSuchFieldException | IllegalAccessException e) { 144 throw new Error(e); 145 } 146 serverSocketStateSet = true; 147 } 148 149 ServerSocket getServerSocket() { 150 return serverSocket; 151 } 152 153 private static final Set<SocketOption<?>> socketOptions; 154 155 private static final Set<SocketOption<?>> serverSocketOptions; 156 157 static { 158 socketOptions = Set.of(StandardSocketOptions.SO_SNDBUF, 159 StandardSocketOptions.SO_RCVBUF, 160 StandardSocketOptions.SO_REUSEADDR, 161 StandardSocketOptions.SO_LINGER, 162 StandardSocketOptions.TCP_NODELAY); 163 164 serverSocketOptions = Set.of(StandardSocketOptions.SO_RCVBUF, 165 StandardSocketOptions.SO_REUSEADDR); 166 } 167 168 @Override 169 protected Set<SocketOption<?>> supportedOptions() { 170 Set<SocketOption<?>> options = new HashSet<>(); 171 if (socket != null) 172 options.addAll(socketOptions); 173 else 174 options.addAll(serverSocketOptions); 175 176 if (isRdmaAvailable()) { 177 RdmaSocketOptions rdmaOptions = 178 RdmaSocketOptions.getInstance(); 179 options.addAll(rdmaOptions.options()); 180 } 181 options = Collections.unmodifiableSet(options); 182 return options; 183 } 184 185 protected synchronized void create(boolean stream) throws IOException { 186 this.stream = stream; 187 if (stream) { 188 fd = new FileDescriptor(); 189 platformRdmaSocketImpl.rdmaSocketCreate(true, this); 190 } 191 try { 192 if (socket != null) { 193 sCreateState.setBoolean(socket, true); 194 } 195 if (serverSocket != null) 196 ssCreateState.setBoolean(serverSocket, true); 197 } catch (IllegalAccessException e) { 198 throw new AssertionError(e); 199 } 200 } 201 202 protected void connect(String host, int port) 203 throws UnknownHostException, IOException 204 { 205 boolean connected = false; 206 try { 207 InetAddress address = InetAddress.getByName(host); 208 this.port = port; 209 this.address = address; 210 211 connectToAddress(address, port, timeout); 212 connected = true; 213 } finally { 214 if (!connected) { 215 try { 216 close(); 217 } catch (IOException ioe) { 218 } 219 } 220 } 221 } 222 223 protected void connect(InetAddress address, int port) throws IOException { 224 this.port = port; 225 this.address = address; 226 227 try { 228 connectToAddress(address, port, timeout); 229 return; 230 } catch (IOException e) { 231 close(); 232 throw e; 233 } 234 } 235 236 protected void connect(SocketAddress address, int timeout) 237 throws IOException { 238 boolean connected = false; 239 try { 240 if (address == null || !(address instanceof InetSocketAddress)) 241 throw new IllegalArgumentException("unsupported address type"); 242 InetSocketAddress addr = (InetSocketAddress) address; 243 if (addr.isUnresolved()) 244 throw new UnknownHostException(addr.getHostName()); 245 this.port = addr.getPort(); 246 this.address = addr.getAddress(); 247 248 connectToAddress(this.address, port, timeout); 249 connected = true; 250 } finally { 251 if (!connected) { 252 try { 253 close(); 254 } catch (IOException ioe) { 255 } 256 } 257 } 258 } 259 260 private void connectToAddress(InetAddress address, int port, int timeout) throws IOException { 261 if (address.isAnyLocalAddress()) { 262 doConnect(InetAddress.getLocalHost(), port, timeout); 263 } else { 264 doConnect(address, port, timeout); 265 } 266 } 267 268 protected <T> void setOption(SocketOption<T> name, T value) throws IOException { 269 if (!rdmaOptions.isOptionSupported(name)) { 270 int opt; 271 if (name == StandardSocketOptions.SO_SNDBUF && 272 socket != null) { 273 if (socket.isConnected()) 274 throw new UnsupportedOperationException( 275 "RDMA socket cannot set SO_SNDBUF after connect."); 276 opt = SocketOptions.SO_SNDBUF; 277 } else if (name == StandardSocketOptions.SO_RCVBUF) { 278 if (socket != null && socket.isConnected()) 279 throw new UnsupportedOperationException( 280 "RDMA socket cannot set SO_RCVBUF after connect."); 281 if (serverSocket != null && serverSocket.isBound()) 282 throw new UnsupportedOperationException( 283 "RDMA server socket cannot set SO_RCVBUF after bind."); 284 opt = SocketOptions.SO_RCVBUF; 285 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 286 opt = SocketOptions.SO_REUSEADDR; 287 } else if (name == StandardSocketOptions.TCP_NODELAY && 288 (socket != null)) { 289 opt = SocketOptions.TCP_NODELAY; 290 } else if (name == StandardSocketOptions.SO_LINGER && 291 (socket != null)) { 292 opt = SocketOptions.SO_LINGER; 293 } else { 294 throw new UnsupportedOperationException("unsupported option"); 295 } 296 setOption(opt, value); 297 } else { 298 rdmaOptions.setOption(fd, name, value); 299 } 300 } 301 302 @SuppressWarnings("unchecked") 303 protected <T> T getOption(SocketOption<T> name) throws IOException { 304 if (!rdmaOptions.isOptionSupported(name)) { 305 int opt; 306 if (name == StandardSocketOptions.SO_SNDBUF && 307 (socket != null)) { 308 opt = SocketOptions.SO_SNDBUF; 309 } else if (name == StandardSocketOptions.SO_RCVBUF) { 310 opt = SocketOptions.SO_RCVBUF; 311 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 312 opt = SocketOptions.SO_REUSEADDR; 313 } else if (name == StandardSocketOptions.SO_LINGER && 314 (socket != null)) { 315 return (T)getOption(SocketOptions.SO_LINGER); 316 } else if (name == StandardSocketOptions.TCP_NODELAY && 317 (socket != null)) { 318 opt = SocketOptions.TCP_NODELAY; 319 } else { 320 throw new UnsupportedOperationException("unsupported option"); 321 } 322 return (T) getOption(opt); 323 } else { 324 return (T) rdmaOptions.getOption(fd, name); 325 } 326 } 327 328 public void setOption(int opt, Object val) throws SocketException { 329 if (isClosedOrPending()) { 330 throw new SocketException("Socket Closed"); 331 } 332 boolean on = true; 333 switch (opt) { 334 case SO_LINGER: 335 if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean))) 336 throw new SocketException("Bad parameter for option"); 337 if (val instanceof Boolean) { 338 /* true only if disabling - enabling should be Integer */ 339 on = false; 340 } 341 break; 342 case SO_TIMEOUT: 343 if (val == null || (!(val instanceof Integer))) 344 throw new SocketException("Bad parameter for SO_TIMEOUT"); 345 int tmp = ((Integer) val).intValue(); 346 if (tmp < 0) 347 throw new IllegalArgumentException("timeout < 0"); 348 timeout = tmp; 349 break; 350 case SO_BINDADDR: 351 throw new SocketException("Cannot re-bind socket"); 352 case TCP_NODELAY: 353 if (val == null || !(val instanceof Boolean)) 354 throw new SocketException("bad parameter for TCP_NODELAY"); 355 on = ((Boolean)val).booleanValue(); 356 break; 357 case SO_SNDBUF: 358 case SO_RCVBUF: 359 int value = ((Integer)val).intValue(); 360 int maxValue = 1024 * 1024 * 1024 - 1; //maximum value for the buffer 361 if (val == null || !(val instanceof Integer) || 362 !(value > 0)) { 363 throw new SocketException("bad parameter for SO_SNDBUF " + 364 "or SO_RCVBUF"); 365 } 366 if (value >= maxValue) 367 value = maxValue; 368 break; 369 case SO_REUSEADDR: 370 if (val == null || !(val instanceof Boolean)) 371 throw new SocketException("bad parameter for SO_REUSEADDR"); 372 on = ((Boolean)val).booleanValue(); 373 if (serverSocket != null && serverSocket.isBound()) 374 throw new UnsupportedOperationException( 375 "RDMA server socket cannot set " + 376 "SO_REUSEADDR after bind."); 377 if (socket != null && socket.isConnected()) 378 throw new UnsupportedOperationException( 379 "RDMA socket cannot set " + 380 "SO_REUSEADDR after connect."); 381 break; 382 default: 383 throw new SocketException("unrecognized TCP option: " + opt); 384 } 385 socketSetOption(opt, on, val); 386 } 387 388 public Object getOption(int opt) throws SocketException { 389 if (isClosedOrPending()) { 390 throw new SocketException("Socket Closed"); 391 } 392 if (opt == SO_TIMEOUT) { 393 return timeout; 394 } 395 int ret = 0; 396 397 switch (opt) { 398 case TCP_NODELAY: 399 ret = platformRdmaSocketImpl.rdmaSocketGetOption(this, opt, null); 400 return Boolean.valueOf(ret != -1); 401 case SO_LINGER: 402 ret = platformRdmaSocketImpl.rdmaSocketGetOption(this, opt, null); 403 return (ret == -1) ? Boolean.FALSE: (Object)(ret); 404 case SO_REUSEADDR: 405 ret = platformRdmaSocketImpl.rdmaSocketGetOption(this, opt, null); 406 return Boolean.valueOf(ret != -1); 407 case SO_BINDADDR: 408 RdmaInetAddressContainer in = new RdmaInetAddressContainer(); 409 ret = platformRdmaSocketImpl.rdmaSocketGetOption(this, opt, in); 410 return in.addr; 411 case SO_SNDBUF: 412 case SO_RCVBUF: 413 ret = platformRdmaSocketImpl.rdmaSocketGetOption(this, opt, null); 414 return ret; 415 default: 416 return null; 417 } 418 } 419 420 protected void socketSetOption(int opt, boolean b, Object val) throws SocketException { 421 if (opt == SocketOptions.SO_REUSEPORT && 422 !supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) { 423 throw new UnsupportedOperationException("unsupported option"); 424 } 425 try { 426 platformRdmaSocketImpl.rdmaSocketSetOption(this, opt, b, val); 427 } catch (SocketException se) { 428 if (socket == null || !socket.isConnected()) 429 throw se; 430 } 431 } 432 433 synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException { 434 try { 435 acquireFD(); 436 try { 437 platformRdmaSocketImpl.rdmaSocketConnect(this, address, port, timeout); 438 synchronized (fdLock) { 439 if (closePending) { 440 throw new SocketException ("Socket closed"); 441 } 442 } 443 try { 444 if (socket != null) { 445 sBoundState.setBoolean(socket, true); 446 sConnectState.setBoolean(socket, true); 447 } 448 } catch (IllegalAccessException e) { 449 throw new AssertionError(e); 450 } 451 } finally { 452 releaseFD(); 453 } 454 } catch (IOException e) { 455 close(); 456 throw e; 457 } 458 } 459 460 protected synchronized void bind(InetAddress address, int lport) 461 throws IOException 462 { 463 platformRdmaSocketImpl.rdmaSocketBind(this, address, lport); 464 try { 465 if (socket != null) 466 sBoundState.setBoolean(socket, true); 467 if (serverSocket != null) 468 ssBoundState.setBoolean(serverSocket, true); 469 } catch (IllegalAccessException e) { 470 throw new AssertionError(e); 471 } 472 } 473 474 protected synchronized void listen(int count) throws IOException { 475 platformRdmaSocketImpl.rdmaSocketListen(this, count); 476 } 477 478 protected void accept(SocketImpl s) throws IOException { 479 acquireFD(); 480 try { 481 platformRdmaSocketImpl.rdmaSocketAccept(s, this); 482 } finally { 483 releaseFD(); 484 } 485 } 486 487 protected synchronized InputStream getInputStream() throws IOException { 488 synchronized (fdLock) { 489 if (isClosedOrPending()) 490 throw new IOException("Socket Closed"); 491 if (shut_rd) 492 throw new IOException("Socket input is shutdown"); 493 if (socketInputStream == null) 494 socketInputStream = platformRdmaSocketImpl.getRdmaInputStream(this); 495 } 496 return socketInputStream; 497 } 498 499 protected synchronized OutputStream getOutputStream() throws IOException { 500 synchronized (fdLock) { 501 if (isClosedOrPending()) 502 throw new IOException("Socket Closed"); 503 if (shut_wr) 504 throw new IOException("Socket output is shutdown"); 505 if (socketOutputStream == null) 506 socketOutputStream = platformRdmaSocketImpl.getRdmaOutputStream(this); 507 } 508 return socketOutputStream; 509 } 510 511 protected FileDescriptor getFileDescriptor() { 512 return fd; 513 } 514 515 protected void setFileDescriptor(FileDescriptor fd) { 516 this.fd = fd; 517 } 518 519 protected void setAddress(InetAddress address) { 520 this.address = address; 521 } 522 523 void setPort(int port) { 524 this.port = port; 525 } 526 527 void setLocalPort(int localport) { 528 this.localport = localport; 529 } 530 531 protected synchronized int available() throws IOException { 532 if (isClosedOrPending()) { 533 throw new IOException("Stream closed."); 534 } 535 536 if (isConnectionReset() || shut_rd) { 537 return 0; 538 } 539 540 int n = 0; 541 try { 542 n = platformRdmaSocketImpl.rdmaSocketAvailable(this); 543 if (n == 0 && isConnectionResetPending()) { 544 setConnectionReset(); 545 } 546 } catch (ConnectionResetException exc1) { 547 setConnectionResetPending(); 548 try { 549 n = platformRdmaSocketImpl.rdmaSocketAvailable(this); 550 if (n == 0) { 551 setConnectionReset(); 552 } 553 } catch (ConnectionResetException exc2) { 554 } 555 } 556 return n; 557 } 558 559 protected void close() throws IOException { 560 synchronized(fdLock) { 561 if (fd != null) { 562 if (fdUseCount == 0) { 563 if (closePending) { 564 return; 565 } 566 closePending = true; 567 try { 568 platformRdmaSocketImpl.rdmaSocketClose(true, this); 569 } finally { 570 platformRdmaSocketImpl.rdmaSocketClose(false, this); 571 } 572 fd = null; 573 return; 574 } else { 575 if (!closePending) { 576 closePending = true; 577 fdUseCount--; 578 platformRdmaSocketImpl.rdmaSocketClose(true, this); 579 } 580 } 581 } 582 } 583 } 584 585 void reset() throws IOException { 586 if (fd != null) { 587 platformRdmaSocketImpl.rdmaSocketClose(false, this); 588 } 589 fd = null; 590 postReset(); 591 } 592 593 void postReset() throws IOException { 594 address = null; 595 port = 0; 596 localport = 0; 597 } 598 599 protected void shutdownInput() throws IOException { 600 if (fd != null) { 601 platformRdmaSocketImpl.rdmaSocketShutdownInput(SHUT_RD, this, socketInputStream); 602 shut_rd = true; 603 } 604 } 605 606 protected void shutdownOutput() throws IOException { 607 if (fd != null) { 608 platformRdmaSocketImpl.rdmaSocketShutdown(SHUT_WR, this); 609 shut_wr = true; 610 } 611 } 612 613 protected boolean supportsUrgentData () { 614 return true; 615 } 616 617 protected void sendUrgentData (int data) throws IOException { 618 if (fd == null) { 619 throw new IOException("Socket Closed"); 620 } 621 platformRdmaSocketImpl.rdmaSocketSendUrgentData(this, data); 622 } 623 624 FileDescriptor acquireFD() { 625 synchronized (fdLock) { 626 fdUseCount++; 627 return fd; 628 } 629 } 630 631 void releaseFD() { 632 synchronized (fdLock) { 633 fdUseCount--; 634 if (fdUseCount == -1) { 635 if (fd != null) { 636 try { 637 platformRdmaSocketImpl.rdmaSocketClose(false, this); 638 } catch (IOException e) { 639 } finally { 640 fd = null; 641 } 642 } 643 } 644 } 645 } 646 647 public boolean isConnectionReset() { 648 synchronized (resetLock) { 649 return (resetState == CONNECTION_RESET); 650 } 651 } 652 653 public boolean isConnectionResetPending() { 654 synchronized (resetLock) { 655 return (resetState == CONNECTION_RESET_PENDING); 656 } 657 } 658 659 public void setConnectionReset() { 660 synchronized (resetLock) { 661 resetState = CONNECTION_RESET; 662 } 663 } 664 665 public void setConnectionResetPending() { 666 synchronized (resetLock) { 667 if (resetState == CONNECTION_NOT_RESET) { 668 resetState = CONNECTION_RESET_PENDING; 669 } 670 } 671 672 } 673 674 public boolean isClosedOrPending() { 675 synchronized (fdLock) { 676 if (closePending || (fd == null)) { 677 return true; 678 } else { 679 return false; 680 } 681 } 682 } 683 684 public int getTimeout() { 685 return timeout; 686 } 687 688 protected InetAddress getInetAddress() { 689 return address; 690 } 691 692 protected int getPort() { 693 return port; 694 } 695 696 protected int getLocalPort() { 697 return localport; 698 } 699 700 public static final int SHUT_RD = 0; 701 public static final int SHUT_WR = 1; 702 703 static class PlatformRdmaSocketImpl { 704 705 @SuppressWarnings("unchecked") 706 private static PlatformRdmaSocketImpl newInstance(String cn) { 707 Class<PlatformRdmaSocketImpl> c; 708 try { 709 c = (Class<PlatformRdmaSocketImpl>)Class.forName(cn); 710 return c.getConstructor(new Class<?>[] {}).newInstance(); 711 } catch (ReflectiveOperationException x) { 712 throw new AssertionError(x); 713 } 714 } 715 716 private static PlatformRdmaSocketImpl create() { 717 String osname = AccessController.doPrivileged( 718 new PrivilegedAction<String>() { 719 public String run() { 720 return System.getProperty("os.name"); 721 } 722 }); 723 if ("Linux".equals(osname)) 724 return newInstance("rdma.ch.LinuxRdmaSocketImpl"); 725 return new PlatformRdmaSocketImpl(); 726 } 727 728 private static final PlatformRdmaSocketImpl instance = create(); 729 730 static PlatformRdmaSocketImpl get() { 731 return instance; 732 } 733 734 boolean isRdmaAvailable() { 735 return false; 736 } 737 738 InputStream getRdmaInputStream(RdmaSocketImpl impl) throws IOException { 739 throw new UnsupportedOperationException("unsupported socket operation"); 740 } 741 742 OutputStream getRdmaOutputStream(RdmaSocketImpl impl) throws IOException { 743 throw new UnsupportedOperationException("unsupported socket operation"); 744 } 745 746 void rdmaSocketClose(boolean useDeferredClose, RdmaSocketImpl impl) throws IOException { 747 throw new UnsupportedOperationException("unsupported socket operation"); 748 } 749 750 void rdmaSocketCreate(boolean isServer, RdmaSocketImpl impl) throws IOException { 751 throw new UnsupportedOperationException("unsupported socket operation"); 752 } 753 754 void rdmaSocketConnect(RdmaSocketImpl impl, InetAddress address, int port, int timeout) 755 throws IOException { 756 throw new UnsupportedOperationException("unsupported socket operation"); 757 } 758 759 void rdmaSocketBind(RdmaSocketImpl impl, InetAddress address, int port) 760 throws IOException { 761 throw new UnsupportedOperationException("unsupported socket operation"); 762 } 763 764 void rdmaSocketListen(RdmaSocketImpl impl, int count) 765 throws IOException { 766 throw new UnsupportedOperationException("unsupported socket operation"); 767 } 768 769 void rdmaSocketAccept(SocketImpl s, RdmaSocketImpl impl) 770 throws IOException { 771 throw new UnsupportedOperationException("unsupported socket operation"); 772 } 773 774 int rdmaSocketAvailable(RdmaSocketImpl impl) 775 throws IOException { 776 throw new UnsupportedOperationException("unsupported socket operation"); 777 } 778 779 void rdmaSocketShutdown(int howto, RdmaSocketImpl impl) 780 throws IOException { 781 throw new UnsupportedOperationException("unsupported socket operation"); 782 } 783 784 void rdmaSocketShutdownInput(int howto, RdmaSocketImpl impl, 785 InputStream socketInputStream) throws IOException { 786 throw new UnsupportedOperationException("unsupported socket operation"); 787 } 788 789 void rdmaSocketSetOption(RdmaSocketImpl impl, int cmd, boolean on, Object value) 790 throws SocketException { 791 throw new UnsupportedOperationException("unsupported socket operation"); 792 } 793 794 int rdmaSocketGetOption(RdmaSocketImpl impl, int opt, Object iaContainerObj) 795 throws SocketException { 796 throw new UnsupportedOperationException("unsupported socket operation"); 797 } 798 799 void rdmaSocketSendUrgentData(RdmaSocketImpl impl, int data) 800 throws IOException { 801 throw new UnsupportedOperationException("unsupported socket operation"); 802 } 803 } 804 }