AFGenericSocket.java

  1. /*
  2.  * junixsocket
  3.  *
  4.  * Copyright 2009-2024 Christian Kohlschütter
  5.  *
  6.  * Licensed under the Apache License, Version 2.0 (the "License");
  7.  * you may not use this file except in compliance with the License.
  8.  * You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.newsclub.net.unix;

  19. import java.io.FileDescriptor;
  20. import java.io.IOException;
  21. import java.net.Socket;
  22. import java.net.SocketException;

  23. /**
  24.  * Implementation of an unknown-type socket.
  25.  *
  26.  * @author Christian Kohlschütter
  27.  */
  28. final class AFGenericSocket extends AFSocket<AFGenericSocketAddress> implements
  29.     AFGenericSocketExtensions {
  30.   private static AFGenericSocketImplExtensions staticExtensions = null;

  31.   AFGenericSocket(FileDescriptor fdObj, AFSocketFactory<AFGenericSocketAddress> factory)
  32.       throws SocketException {
  33.     super(new AFGenericSocketImpl(fdObj), factory);
  34.   }

  35.   @SuppressWarnings("unused")
  36.   private static synchronized AFGenericSocketImplExtensions getStaticImplExtensions()
  37.       throws IOException {
  38.     if (staticExtensions == null) {
  39.       try (AFGenericSocket socket = new AFGenericSocket(null, null)) {
  40.         staticExtensions = (AFGenericSocketImplExtensions) socket.getImplExtensions();
  41.       }
  42.     }
  43.     return staticExtensions;
  44.   }

  45.   /**
  46.    * Returns <code>true</code> iff {@link AFGenericSocket}s (sockets of unknown/otherwise
  47.    * unsupported type) are supported by the current Java VM and the kernel.
  48.    *
  49.    * To support {@link AFGenericSocket}s, a custom JNI library must be loaded that is supplied with
  50.    * <em>junixsocket</em>.
  51.    *
  52.    * This call is equivalent to checking {@link AFSocket#isSupported()}.
  53.    *
  54.    * @return {@code true} iff supported.
  55.    */
  56.   public static boolean isSupported() {
  57.     return AFSocket.isSupported();
  58.   }

  59.   @Override
  60.   protected AFGenericSocketChannel newChannel() {
  61.     return new AFGenericSocketChannel(this);
  62.   }

  63.   /**
  64.    * Creates a new, unbound {@link AFSocket}.
  65.    *
  66.    * This "default" implementation is a bit "lenient" with respect to the specification.
  67.    *
  68.    * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
  69.    * {@link Socket#setTcpNoDelay(boolean)}.
  70.    *
  71.    * @return A new, unbound socket.
  72.    * @throws IOException if the operation fails.
  73.    */
  74.   public static AFGenericSocket newInstance() throws IOException {
  75.     return (AFGenericSocket) AFSocket.newInstance(AFGenericSocket::new,
  76.         (AFGenericSocketFactory) null);
  77.   }

  78.   static AFGenericSocket newInstance(AFGenericSocketFactory factory) throws SocketException {
  79.     return (AFGenericSocket) AFSocket.newInstance(AFGenericSocket::new, factory);
  80.   }

  81.   /**
  82.    * Creates a new, unbound, "strict" {@link AFSocket}.
  83.    *
  84.    * This call uses an implementation that tries to be closer to the specification than
  85.    * {@link #newInstance()}, at least for some cases.
  86.    *
  87.    * @return A new, unbound socket.
  88.    * @throws IOException if the operation fails.
  89.    */
  90.   public static AFGenericSocket newStrictInstance() throws IOException {
  91.     return (AFGenericSocket) AFSocket.newInstance(AFGenericSocket::new,
  92.         (AFGenericSocketFactory) null);
  93.   }

  94.   /**
  95.    * Creates a new {@link AFSocket} and connects it to the given {@link AFGenericSocketAddress}.
  96.    *
  97.    * @param addr The address to connect to.
  98.    * @return A new, connected socket.
  99.    * @throws IOException if the operation fails.
  100.    */
  101.   public static AFGenericSocket connectTo(AFGenericSocketAddress addr) throws IOException {
  102.     return (AFGenericSocket) AFSocket.connectTo(AFGenericSocket::new, addr);
  103.   }

  104.   @Override
  105.   public AFGenericSocketChannel getChannel() {
  106.     return (AFGenericSocketChannel) super.getChannel();
  107.   }
  108. }