1 /*
   2  * Copyright (c) 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 jdk.net;
  27 
  28 import java.net.ProtocolFamily;
  29 import java.net.ServerSocket;
  30 import java.net.Socket;
  31 import java.net.SocketException;
  32 import java.net.SocketOption;
  33 import java.net.StandardSocketOptions;
  34 import java.nio.channels.Selector;
  35 import java.nio.channels.ServerSocketChannel;
  36 import java.nio.channels.SocketChannel;
  37 import java.nio.channels.spi.SelectorProvider;
  38 import java.io.IOException;
  39 import java.util.Collections;
  40 import java.util.HashMap;
  41 import java.util.HashSet;
  42 import java.util.Map;
  43 import java.util.Set;
  44 import jdk.internal.net.rdma.RdmaPollSelectorProvider;
  45 import jdk.internal.net.rdma.RdmaSocketProvider;
  46 
  47 /**
  48  * Factory methods for creating RDMA-based TCP sockets and channels.
  49  *
  50  * <p>The {@link #openSocket(ProtocolFamily family) openSocket} and {@link
  51  * #openServerSocket(ProtocolFamily family) openServerSocket} methods
  52  * create RDMA-based TCP sockets.
  53  * 
  54  * <p>The {@link #openSelector() openSelector}, {@link
  55  * #openSocketChannel(ProtocolFamily family) openSocketChannel}, and {@link
  56  * #openServerSocketChannel(ProtocolFamily family) openServerSocketChannel}
  57  * methods create selectors and selectable channels for use with RDMA sockets.
  58  * These objects are created by a {@link java.nio.channels.spi.SelectorProvider
  59  * SelectorProvider} that is not the default {@code SelectorProvider}.
  60  * Consequently, selectable channels to RDMA sockets may not be multiplexed
  61  * with selectable channels created by the default selector provider. The
  62  * selector provider does not support datagram channels and pipes.
  63  * The openDatagramChannel and openPipe methods throw UOE.
  64  * 
  65  * @since 12
  66  */
  67 public class RdmaSockets {
  68 
  69     private RdmaSockets() {}
  70 
  71     /**
  72      * Creates an unbound and unconnected RDMA socket.
  73      *
  74      * <p> A RDMA socket supports the same socket options that {@code
  75      * java.net.Socket} defines. In addition, it supports the socket options
  76      * specified by {@link RdmaSocketOptions}.
  77      *
  78      * <p> When binding the socket to a local address, or invoking connect
  79      * to connect the socket, the socket address specified to those methods
  80      * must correspond to the protocol family specified here.
  81      *
  82      * @param   family
  83      *          The protocol family
  84      *
  85      * @throws IOException
  86      *         If an I/O error occurs
  87      * @throws NullPointerException
  88      *         If name is null
  89      * @throws UnsupportedOperationException
  90      *         If RDMA sockets are not supported on this platform or if the
  91      *         specified protocol family is not supported. For example,
  92      *         suppose the parameter is specified as {@link
  93      *         java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
  94      *         but IPv6 is not enabled on the platform.
  95      */
  96     public static Socket openSocket(ProtocolFamily family) throws IOException {
  97         if(family == null)
  98             throw new NullPointerException("protocol family is null");
  99         return RdmaSocketProvider.openSocket(family);
 100     }
 101 
 102     /**
 103      * Creates an unbound RDMA server socket.
 104      *
 105      * <p> A RDMA socket supports the same socket options that {@code
 106      * java.net.ServerSocket} defines.
 107      *
 108      * <p> When binding the socket to an address, the socket address specified
 109      * to the bind method must correspond to the protocol family specified here.
 110      *
 111      * @param   family
 112      *          The protocol family
 113      *
 114      * @throws IOException
 115      *         If an I/O error occurs
 116      * @throws NullPointerException
 117      *         If name is null
 118      * @throws UnsupportedOperationException
 119      *         If RDMA sockets are not supported on this platform or if the
 120      *         specified protocol family is not supported. For example,
 121      *         suppose the parameter is specified as {@link
 122      *         java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
 123      *         but IPv6 is not enabled on the platform.
 124      */
 125     public static ServerSocket openServerSocket(ProtocolFamily family)
 126             throws IOException {
 127         if(family == null)
 128             throw new NullPointerException("protocol family is null");
 129         return RdmaSocketProvider.openServerSocket(family);
 130     }
 131 
 132     /**
 133      * Opens a socket channel to a RDMA socket. A newly created socket channel
 134      * is {@link SocketChannel#isOpen() open}, not yet bound to a {@link
 135      * SocketChannel#getLocalAddress() local address}, and not yet
 136      * {@link SocketChannel#isConnected() connected}.
 137      *
 138      * <p> A socket channel to a RDMA socket supports all of the socket options
 139      * specified by {@code SocketChannel}. In addition, it supports the
 140      * socket options specified by {@link RdmaSocketOptions}.
 141      *
 142      * <p> When binding the channel's socket to a local address, or invoking
 143      * connect to connect channel's socket, the socket address specified to
 144      * those methods must correspond to the protocol family specified here.
 145      *
 146      * @param   family
 147      *          The protocol family
 148      *
 149      * @throws IOException
 150      *         If an I/O error occurs
 151      * @throws NullPointerException
 152      *         If name is null
 153      * @throws UnsupportedOperationException
 154      *         If RDMA sockets are not supported on this platform or if the
 155      *         specified protocol family is not supported. For example,
 156      *         suppose the parameter is specified as {@link
 157      *         java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
 158      *         but IPv6 is not enabled on the platform.
 159      */
 160     public static SocketChannel openSocketChannel(ProtocolFamily family)
 161             throws IOException {
 162         if(family == null)
 163             throw new NullPointerException("protocol family is null");
 164         SelectorProvider provider = RdmaPollSelectorProvider.provider();
 165         return ((RdmaPollSelectorProvider)provider).openSocketChannel(family);
 166     }
 167 
 168     /**
 169      * Opens a server socket channel to a RDMA socket. A newly created socket
 170      * channel is {@link SocketChannel#isOpen() open} but not yet bound to a
 171      * {@link SocketChannel#getLocalAddress() local address}.
 172      *
 173      * <p> When binding the channel's socket to an address , the socket address
 174      * specified to the bind method must correspond to the protocol family
 175      * specified here.
 176      *
 177      * @param   family
 178      *          The protocol family
 179      *
 180      * @throws IOException
 181      *         If an I/O error occurs
 182      * @throws NullPointerException
 183      *         If name is null
 184      * @throws UnsupportedOperationException
 185      *         If RDMA sockets are not supported on this platform or if the
 186      *         specified protocol family is not supported. For example,
 187      *         suppose the parameter is specified as {@link
 188      *         java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
 189      *         but IPv6 is not enabled on the platform.
 190      */
 191     public static ServerSocketChannel openServerSocketChannel(
 192             ProtocolFamily family) throws IOException {
 193         if(family == null)
 194             throw new NullPointerException("protocol family is null");
 195         SelectorProvider provider = RdmaPollSelectorProvider.provider();
 196         return ((RdmaPollSelectorProvider)provider)
 197                 .openServerSocketChannel(family);
 198     }
 199  
 200     /**
 201      * Opens a selector to multiplex selectable channels to RDMA sockets.
 202      *
 203      * @throws IOException
 204      *         If an I/O error occurs
 205      * @throws UnsupportedOperationException
 206      *         If RDMA sockets are not supported on this platform
 207      */
 208     public static Selector openSelector() throws IOException {
 209         SelectorProvider provider = RdmaPollSelectorProvider.provider();
 210         return provider.openSelector();
 211     }
 212 }