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.net.ServerSocket; 30 import java.net.Socket; 31 import java.net.SocketException; 32 import java.net.SocketOption; 33 import java.net.SocketOptions; 34 import java.net.StandardSocketOptions; 35 import java.util.HashMap; 36 import java.util.Map; 37 import java.util.Set; 38 import jdk.net.RdmaSocketOptions; 39 40 public class RdmaSocketProvider { 41 private static boolean rdmaLibInstalled = false; 42 private static boolean rdmaLibChecked = false; 43 44 static class RdmaClientSocketImpl extends RdmaSocketImpl { 45 46 @Override 47 protected <T> void setOption(SocketOption<T> name, T value) 48 throws IOException { 49 if(rdmaLibChecked && !rdmaLibInstalled) 50 throw new UnsupportedOperationException( 51 "librdmacm library is not installed!"); 52 53 rdmaLibChecked = true; 54 try { 55 if (!rdmaOptions.isOptionSupported(name)) { 56 int opt; 57 if (name == StandardSocketOptions.SO_SNDBUF) { 58 opt = SocketOptions.SO_SNDBUF; 59 } else if (name == StandardSocketOptions.SO_RCVBUF) { 60 opt = SocketOptions.SO_RCVBUF; 61 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 62 opt = SocketOptions.SO_REUSEADDR; 63 } else if (name == StandardSocketOptions.TCP_NODELAY) { 64 opt = SocketOptions.TCP_NODELAY; 65 } else { 66 throw new UnsupportedOperationException( 67 "unsupported option: " + name); 68 } 69 setOption(opt, value); 70 } else { 71 rdmaOptions.setOption(fd, name, value); 72 } 73 rdmaLibInstalled = true; 74 } catch (ExceptionInInitializerError e) { 75 rdmaLibInstalled = false; 76 throw new UnsupportedOperationException( 77 "librdmacm library is not installed!"); 78 } 79 } 80 81 @SuppressWarnings("unchecked") 82 @Override 83 protected <T> T getOption(SocketOption<T> name) throws IOException { 84 if(rdmaLibChecked && !rdmaLibInstalled) 85 throw new UnsupportedOperationException( 86 "librdmacm library is not installed!"); 87 88 rdmaLibChecked = true; 89 Object value; 90 try { 91 if (!rdmaOptions.isOptionSupported(name)) { 92 int opt; 93 if (name == StandardSocketOptions.SO_SNDBUF) { 94 opt = SocketOptions.SO_SNDBUF; 95 } else if (name == StandardSocketOptions.SO_RCVBUF) { 96 opt = SocketOptions.SO_RCVBUF; 97 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 98 opt = SocketOptions.SO_REUSEADDR; 99 } else if (name == StandardSocketOptions.TCP_NODELAY) { 100 opt = SocketOptions.TCP_NODELAY; 101 } else { 102 throw new UnsupportedOperationException( 103 "unsupported option: " + name); 104 } 105 value = getOption(opt); 106 } else { 107 value = rdmaOptions.getOption(fd, name); 108 } 109 rdmaLibInstalled = true; 110 return (T) value; 111 } catch (ExceptionInInitializerError e) { 112 rdmaLibInstalled = false; 113 throw new UnsupportedOperationException( 114 "librdmacm library is not installed!"); 115 } 116 } 117 } 118 119 static class RdmaServerSocketImpl extends RdmaSocketImpl { 120 121 @Override 122 protected <T> void setOption(SocketOption<T> name, T value) 123 throws IOException { 124 if(rdmaLibChecked && !rdmaLibInstalled) 125 throw new UnsupportedOperationException( 126 "librdmacm library is not installed!"); 127 128 rdmaLibChecked = true; 129 130 try { 131 if (!rdmaOptions.isOptionSupported(name)) { 132 int opt; 133 if (name == StandardSocketOptions.SO_RCVBUF) { 134 opt = SocketOptions.SO_RCVBUF; 135 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 136 opt = SocketOptions.SO_REUSEADDR; 137 } else { 138 throw new UnsupportedOperationException( 139 "unsupported option: " + name); 140 } 141 setOption(opt, value); 142 } else { 143 rdmaOptions.setOption(fd, name, value); 144 } 145 rdmaLibInstalled = true; 146 } catch (ExceptionInInitializerError e) { 147 rdmaLibInstalled = false; 148 throw new UnsupportedOperationException( 149 "librdmacm library is not installed!"); 150 } 151 } 152 153 @SuppressWarnings("unchecked") 154 @Override 155 protected <T> T getOption(SocketOption<T> name) throws IOException { 156 if(rdmaLibChecked && !rdmaLibInstalled) 157 throw new UnsupportedOperationException( 158 "librdmacm library is not installed!"); 159 160 rdmaLibChecked = true; 161 Object value; 162 try { 163 if (!rdmaOptions.isOptionSupported(name)) { 164 int opt; 165 if (name == StandardSocketOptions.SO_RCVBUF) { 166 opt = SocketOptions.SO_RCVBUF; 167 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 168 opt = SocketOptions.SO_REUSEADDR; 169 } else { 170 throw new UnsupportedOperationException( 171 "unsupported option: " + name); 172 } 173 rdmaLibInstalled = true; 174 value = getOption(opt); 175 } else { 176 rdmaLibInstalled = true; 177 value = rdmaOptions.getOption(fd, name); 178 } 179 rdmaLibInstalled = true; 180 return (T) value; 181 } catch (ExceptionInInitializerError e) { 182 rdmaLibInstalled = false; 183 throw new UnsupportedOperationException( 184 "librdmacm library is not installed!"); 185 } 186 } 187 } 188 189 public static Socket openSocket() throws IOException { 190 if(rdmaLibChecked && !rdmaLibInstalled) 191 throw new UnsupportedOperationException( 192 "librdmacm library is not installed!"); 193 194 rdmaLibChecked = true; 195 196 RdmaClientSocketImpl impl; 197 try { 198 impl = new RdmaClientSocketImpl(); 199 rdmaLibInstalled = true; 200 } catch (ExceptionInInitializerError e) { 201 rdmaLibInstalled = false; 202 throw new UnsupportedOperationException( 203 "librdmacm library is not installed!"); 204 } 205 Socket s = new Socket(impl) { 206 private final Set<SocketOption<?>> options = 207 Set.of(StandardSocketOptions.SO_SNDBUF, 208 StandardSocketOptions.SO_RCVBUF, 209 StandardSocketOptions.SO_REUSEADDR, 210 StandardSocketOptions.TCP_NODELAY, 211 RdmaSocketOptions.RDMA_SQSIZE, 212 RdmaSocketOptions.RDMA_RQSIZE, 213 RdmaSocketOptions.RDMA_INLINE); 214 215 @Override 216 public Set<SocketOption<?>> supportedOptions() { 217 return options; 218 } 219 }; 220 return s; 221 } 222 223 public static ServerSocket openServerSocket() throws IOException { 224 if(rdmaLibChecked && !rdmaLibInstalled) 225 throw new UnsupportedOperationException( 226 "librdmacm library is not installed!"); 227 228 rdmaLibChecked = true; 229 230 RdmaServerSocketImpl impl; 231 try { 232 impl = new RdmaServerSocketImpl(); 233 rdmaLibInstalled = true; 234 } catch (ExceptionInInitializerError e) { 235 rdmaLibInstalled = false; 236 throw new UnsupportedOperationException( 237 "librdmacm library is not installed!"); 238 } 239 ServerSocket ss = new ServerSocket(impl) { 240 private final Set<SocketOption<?>> options = 241 Set.of(StandardSocketOptions.SO_RCVBUF, 242 StandardSocketOptions.SO_REUSEADDR, 243 RdmaSocketOptions.RDMA_SQSIZE, 244 RdmaSocketOptions.RDMA_RQSIZE, 245 RdmaSocketOptions.RDMA_INLINE); 246 247 @Override 248 public Set<SocketOption<?>> supportedOptions() { 249 return options; 250 } 251 public Socket accept() throws IOException { 252 if (isClosed()) 253 throw new SocketException("Socket is closed"); 254 if (!isBound()) 255 throw new SocketException("Socket is not bound yet"); 256 257 Socket s = openSocket(); 258 implAccept(s); 259 return s; 260 } 261 }; 262 return ss; 263 } 264 265 private RdmaSocketProvider() {} 266 } | 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.net.ServerSocket; 30 import java.net.Socket; 31 import java.net.SocketException; 32 import java.net.SocketImpl; 33 import java.net.SocketOption; 34 import java.net.SocketOptions; 35 import java.net.StandardSocketOptions; 36 import java.util.HashMap; 37 import java.util.Map; 38 import java.util.Set; 39 import jdk.net.RdmaSocketOptions; 40 41 public class RdmaSocketProvider { 42 43 static class RdmaClientSocketImpl extends RdmaSocketImpl { 44 45 private final Set<SocketOption<?>> options = 46 Set.of(StandardSocketOptions.SO_SNDBUF, 47 StandardSocketOptions.SO_RCVBUF, 48 StandardSocketOptions.SO_REUSEADDR, 49 StandardSocketOptions.TCP_NODELAY, 50 RdmaSocketOptions.RDMA_SQSIZE, 51 RdmaSocketOptions.RDMA_RQSIZE, 52 RdmaSocketOptions.RDMA_INLINE); 53 54 @Override 55 public Set<SocketOption<?>> supportedOptions() { 56 return options; 57 } 58 59 @Override 60 protected <T> void setOption(SocketOption<T> name, T value) 61 throws IOException { 62 if (!rdmaOptions.isOptionSupported(name)) { 63 int opt; 64 if (name == StandardSocketOptions.SO_SNDBUF) { 65 opt = SocketOptions.SO_SNDBUF; 66 } else if (name == StandardSocketOptions.SO_RCVBUF) { 67 opt = SocketOptions.SO_RCVBUF; 68 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 69 opt = SocketOptions.SO_REUSEADDR; 70 } else if (name == StandardSocketOptions.TCP_NODELAY) { 71 opt = SocketOptions.TCP_NODELAY; 72 } else { 73 throw new UnsupportedOperationException( 74 "unsupported option: " + name); 75 } 76 setOption(opt, value); 77 } else { 78 rdmaOptions.setOption(fd, name, value); 79 } 80 } 81 82 @SuppressWarnings("unchecked") 83 @Override 84 protected <T> T getOption(SocketOption<T> name) throws IOException { 85 Object value; 86 if (!rdmaOptions.isOptionSupported(name)) { 87 int opt; 88 if (name == StandardSocketOptions.SO_SNDBUF) { 89 opt = SocketOptions.SO_SNDBUF; 90 } else if (name == StandardSocketOptions.SO_RCVBUF) { 91 opt = SocketOptions.SO_RCVBUF; 92 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 93 opt = SocketOptions.SO_REUSEADDR; 94 } else if (name == StandardSocketOptions.TCP_NODELAY) { 95 opt = SocketOptions.TCP_NODELAY; 96 } else { 97 throw new UnsupportedOperationException( 98 "unsupported option: " + name); 99 } 100 value = getOption(opt); 101 } else { 102 value = rdmaOptions.getOption(fd, name); 103 } 104 return (T) value; 105 } 106 } 107 108 static class RdmaServerSocketImpl extends RdmaSocketImpl { 109 private final Set<SocketOption<?>> options = 110 Set.of(StandardSocketOptions.SO_RCVBUF, 111 StandardSocketOptions.SO_REUSEADDR, 112 RdmaSocketOptions.RDMA_SQSIZE, 113 RdmaSocketOptions.RDMA_RQSIZE, 114 RdmaSocketOptions.RDMA_INLINE); 115 116 @Override 117 public Set<SocketOption<?>> supportedOptions() { 118 return options; 119 } 120 121 @Override 122 protected <T> void setOption(SocketOption<T> name, T value) 123 throws IOException { 124 if (!rdmaOptions.isOptionSupported(name)) { 125 int opt; 126 if (name == StandardSocketOptions.SO_RCVBUF) { 127 opt = SocketOptions.SO_RCVBUF; 128 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 129 opt = SocketOptions.SO_REUSEADDR; 130 } else { 131 throw new UnsupportedOperationException( 132 "unsupported option: " + name); 133 } 134 setOption(opt, value); 135 } else { 136 rdmaOptions.setOption(fd, name, value); 137 } 138 } 139 140 @SuppressWarnings("unchecked") 141 @Override 142 protected <T> T getOption(SocketOption<T> name) throws IOException { 143 Object value; 144 if (!rdmaOptions.isOptionSupported(name)) { 145 int opt; 146 if (name == StandardSocketOptions.SO_RCVBUF) { 147 opt = SocketOptions.SO_RCVBUF; 148 } else if (name == StandardSocketOptions.SO_REUSEADDR) { 149 opt = SocketOptions.SO_REUSEADDR; 150 } else { 151 throw new UnsupportedOperationException( 152 "unsupported option: " + name); 153 } 154 value = getOption(opt); 155 } else { 156 value = rdmaOptions.getOption(fd, name); 157 } 158 return (T) value; 159 } 160 } 161 162 public static Socket openSocket() throws IOException { 163 return new Socket(new RdmaClientSocketImpl()) { }; 164 } 165 166 public static ServerSocket openServerSocket() throws IOException { 167 return new ServerSocket( new RdmaServerSocketImpl()) { 168 public Socket accept() throws IOException { 169 if (isClosed()) 170 throw new SocketException("Socket is closed"); 171 if (!isBound()) 172 throw new SocketException("Socket is not bound yet"); 173 174 Socket s = openSocket(); 175 implAccept(s); 176 return s; 177 } 178 }; 179 } 180 181 private RdmaSocketProvider() {} 182 } |