You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/12/01 07:04:00 UTC
svn commit: r350181 [109/198] - in
/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/
depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/
depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/
depends/oss/win....
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/MulticastSocket.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/MulticastSocket.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/MulticastSocket.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/MulticastSocket.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,637 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.util.Enumeration;
+
+import com.ibm.oti.util.Msg;
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * This class models a multicast socket for sending & receiving datagram packets
+ * to a multicast group.
+ *
+ * @see DatagramSocket
+ */
+public class MulticastSocket extends DatagramSocket {
+
+ final static int SO_REUSEPORT = 512;
+
+ private InetAddress interfaceSet = null;
+
+ /**
+ * Constructs a multicast socket, bound to any available port on the
+ * localhost.
+ *
+ * @throws IOException
+ * if a problem occurs creating or binding the socket
+ */
+ public MulticastSocket() throws IOException {
+ super();
+ }
+
+ /**
+ * Answers a multicast socket, bound to the nominated port on the localhost.
+ *
+ * @param aPort
+ * the port to bind on the localhost
+ *
+ * @throws IOException
+ * if a problem occurs creating or binding the socket
+ */
+ public MulticastSocket(int aPort) throws IOException {
+ super(aPort);
+ }
+
+ /**
+ * Answer the network address used by the socket. This is useful on
+ * multi-homed machines.
+ *
+ * @return java.net.InetAddress the network address
+ * @exception java.net.SocketException
+ * The exception thrown while getting the address
+ */
+ public InetAddress getInterface() throws SocketException {
+ checkClosedAndBind(false);
+ if (interfaceSet == null) {
+ InetAddress ipvXaddress = (InetAddress) impl
+ .getOption(SocketOptions.IP_MULTICAST_IF);
+ if (ipvXaddress.isAnyLocalAddress()) {
+ // the address was not set at the IPV4 level so check the IPV6
+ // level
+ NetworkInterface theInterface = getNetworkInterface();
+ if (theInterface != null) {
+ Enumeration addresses = theInterface.getInetAddresses();
+ if (addresses != null) {
+ while (addresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) addresses
+ .nextElement();
+ if (nextAddress instanceof Inet6Address) {
+ return nextAddress;
+ }
+ }
+ }
+ }
+ }
+ return ipvXaddress;
+ }
+ return interfaceSet;
+ }
+
+ /**
+ * Answer the network interface used by the socket. This is useful on
+ * multi-homed machines.
+ *
+ * @return java.net.NetworkInterface the network address
+ * @exception java.net.SocketException
+ * The exception thrown while getting the address
+ *
+ * @since 1.4
+ */
+ public NetworkInterface getNetworkInterface() throws SocketException {
+ checkClosedAndBind(false);
+
+ // check if it is set at the IPV6 level. If so then use that. Otherwise
+ // do it at the IPV4 level
+ Integer theIndex = new Integer(0);
+ try {
+ theIndex = (Integer) impl.getOption(SocketOptions.IP_MULTICAST_IF2);
+ } catch (SocketException e) {
+ // we may get an exception if IPV6 is not enabled.
+ }
+
+ if (theIndex.intValue() != 0) {
+ Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
+ while (theInterfaces.hasMoreElements()) {
+ NetworkInterface nextInterface = (NetworkInterface) theInterfaces
+ .nextElement();
+ if (nextInterface.getIndex() == theIndex.intValue()) {
+ return nextInterface;
+ }
+ }
+ }
+
+ // ok it was not set at the IPV6 level so try at the IPV4 level
+ InetAddress theAddress = (InetAddress) impl
+ .getOption(SocketOptions.IP_MULTICAST_IF);
+ if (theAddress != null) {
+ if (!theAddress.isAnyLocalAddress()) {
+ return NetworkInterface.getByInetAddress(theAddress);
+ }
+
+ // not set as we got the any address so return a dummy network
+ // interface with only the any address. We do this to be
+ // compatible
+ InetAddress theAddresses[] = new InetAddress[1];
+ if ((Socket.preferIPv4Stack() == false)
+ && (InetAddress.preferIPv6Addresses() == true)) {
+ theAddresses[0] = Inet6Address.ANY;
+ } else {
+ theAddresses[0] = Inet4Address.ANY;
+ }
+ return new NetworkInterface(null, null, theAddresses,
+ NetworkInterface.UNSET_INTERFACE_INDEX);
+ }
+
+ // ok not set at all so return null
+ return null;
+ }
+
+ /**
+ * Answer the time-to-live (TTL) for multicast packets sent on this socket.
+ *
+ * @return java.net.InetAddress
+ * @exception java.io.IOException
+ * The exception description.
+ */
+ public int getTimeToLive() throws IOException {
+ checkClosedAndBind(false);
+ return impl.getTimeToLive();
+ }
+
+ /**
+ * Answer the time-to-live (TTL) for multicast packets sent on this socket.
+ *
+ * @return java.net.InetAddress
+ * @exception java.io.IOException
+ * The exception description.
+ * @deprecated Replaced by getTimeToLive
+ * @see #getTimeToLive()
+ */
+ public byte getTTL() throws IOException {
+ checkClosedAndBind(false);
+ return impl.getTTL();
+ }
+
+ boolean isMulticastSocket() {
+ return true;
+ }
+
+ /**
+ * Add this socket to the multicast group. A socket must joint a group
+ * before data may be received. A socket may be a member of multiple groups
+ * but may join any group once.
+ *
+ * @param groupAddr
+ * the multicast group to be joined
+ * @exception java.io.IOException
+ * may be thrown while joining a group
+ */
+ public void joinGroup(InetAddress groupAddr) throws IOException {
+ checkClosedAndBind(false);
+ if (!groupAddr.isMulticastAddress())
+ throw new IOException(Msg.getString("K0039"));
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkMulticast(groupAddr);
+ impl.join(groupAddr);
+ }
+
+ /**
+ * Add this socket to the multicast group. A socket must join a group before
+ * data may be received. A socket may be a member of multiple groups but may
+ * join any group once.
+ *
+ * @param groupAddress
+ * the multicast group to be joined
+ * @param netInterface
+ * the network interface on which the addresses should be dropped
+ * @exception java.io.IOException
+ * will be thrown if address is not a multicast address
+ * @exception java.lang.SecurityException
+ * will be thrown if caller is not authorized to join group
+ * @exception java.lang.IllegalArgumentException
+ * will be through if groupAddr is null
+ *
+ * @since 1.4
+ */
+ public void joinGroup(SocketAddress groupAddress,
+ NetworkInterface netInterface) throws java.io.IOException {
+ checkClosedAndBind(false);
+ if (null == groupAddress) {
+ throw new IllegalArgumentException(Msg.getString("K0331"));
+ }
+
+ if ((netInterface != null) && (netInterface.getFirstAddress() == null)) {
+ // this is ok if we could set it at the
+ throw new SocketException(Msg.getString("K0335"));
+ }
+
+ if (groupAddress instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) groupAddress)
+ .getAddress();
+
+ if ((groupAddr) == null) {
+ throw new SocketException(Msg.getString(
+ "K0317", groupAddr.getHostName())); //$NON-NLS-1$
+ }
+
+ if (!groupAddr.isMulticastAddress()) {
+ throw new IOException(Msg.getString("K0039"));
+ }
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkMulticast(groupAddr);
+ }
+ impl.joinGroup(groupAddress, netInterface);
+ } else {
+ throw new IllegalArgumentException(Msg.getString(
+ "K0316", groupAddress.getClass())); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Remove the socket from the multicast group.
+ *
+ * @param groupAddr
+ * the multicast group to be left
+ * @exception java.io.IOException
+ * will be thrown if address is not a multicast address
+ * @exception java.lang.SecurityException
+ * will be thrown if caller is not authorized to join group
+ * @exception java.lang.IllegalArgumentException
+ * will be through if groupAddr is null
+ */
+ public void leaveGroup(InetAddress groupAddr) throws IOException {
+ checkClosedAndBind(false);
+ if (!groupAddr.isMulticastAddress())
+ throw new IOException(Msg.getString("K003a"));
+ SecurityManager security = System.getSecurityManager();
+ if (security != null)
+ security.checkMulticast(groupAddr);
+ impl.leave(groupAddr);
+ }
+
+ /**
+ * Remove the socket from the multicast group.
+ *
+ * @param groupAddress
+ * the multicast group to be left
+ * @param netInterface
+ * the network interface on which the addresses should be dropped
+ * @exception java.io.IOException
+ * will be thrown if address is not a multicast address
+ * @exception java.lang.SecurityException
+ * will be thrown if caller is not authorized to join group
+ * @exception java.lang.IllegalArgumentException
+ * will be through if groupAddr is null
+ *
+ * @since 1.4
+ */
+ public void leaveGroup(SocketAddress groupAddress,
+ NetworkInterface netInterface) throws java.io.IOException {
+ checkClosedAndBind(false);
+ if (null == groupAddress) {
+ throw new IllegalArgumentException(Msg.getString("K0331"));
+ }
+
+ if ((netInterface != null) && (netInterface.getFirstAddress() == null)) {
+ // this is ok if we could set it at the
+ throw new SocketException(Msg.getString("K0335"));
+ }
+
+ if (groupAddress instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) groupAddress)
+ .getAddress();
+
+ if ((groupAddr) == null) {
+ throw new SocketException(Msg.getString(
+ "K0317", groupAddr.getHostName())); //$NON-NLS-1$
+ }
+
+ if (!groupAddr.isMulticastAddress()) {
+ throw new IOException(Msg.getString("K003a"));
+ }
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkMulticast(groupAddr);
+ }
+ impl.leaveGroup(groupAddress, netInterface);
+ } else {
+ throw new IllegalArgumentException(Msg.getString(
+ "K0316", groupAddress.getClass())); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Send the packet on this socket. The packet must satisfy the security
+ * policy before it may be sent.
+ *
+ * @param pack
+ * the DatagramPacket to send
+ * @param ttl
+ * the ttl setting for this transmission, overriding the socket
+ * default
+ *
+ * @exception java.io.IOException
+ * If a send error occurs.
+ *
+ * @deprecated use MulticastSocket#setTimeToLive
+ */
+ public void send(DatagramPacket pack, byte ttl) throws IOException {
+ checkClosedAndBind(false);
+ InetAddress packAddr = pack.getAddress();
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ if (packAddr.isMulticastAddress())
+ security.checkMulticast(packAddr, ttl);
+ else
+ security.checkConnect(packAddr.getHostName(), pack.getPort());
+ }
+ int currTTL = getTimeToLive();
+ if (packAddr.isMulticastAddress() && (byte) currTTL != ttl) {
+ try {
+ setTimeToLive(ttl & 0xff);
+ impl.send(pack);
+ } finally {
+ setTimeToLive(currTTL);
+ }
+ } else {
+ impl.send(pack);
+ }
+ }
+
+ /**
+ * Set the network address used by the socket. This is useful on multi-homed
+ * machines.
+ *
+ * @param addr
+ * java.net.InetAddress the interface network address
+ * @exception java.net.SocketException
+ * the exception may be thrown while setting the address
+ */
+ public void setInterface(InetAddress addr) throws SocketException {
+ checkClosedAndBind(false);
+ if (addr == null)
+ throw new NullPointerException();
+ if (addr.isAnyLocalAddress()) {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF, Inet4Address.ANY);
+ } else if (addr instanceof Inet4Address) {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF, addr);
+ // keep the address used to do the set as we must return the same
+ // value and for IPv6 we may not be able to get it back uniquely
+ interfaceSet = addr;
+ }
+
+ // now we should also make sure this works for IPV6
+ // get the network interface for the addresss and set the interface
+ // using its index
+ // however if IPV6 is not enabled then we may get an exception.
+ // if IPV6 is not enabled
+ NetworkInterface theInterface = NetworkInterface.getByInetAddress(addr);
+ if ((theInterface != null) && (theInterface.getIndex() != 0)) {
+ try {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF2, new Integer(
+ theInterface.getIndex()));
+ } catch (SocketException e) {
+ }
+ } else if (addr.isAnyLocalAddress()) {
+ try {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF2, new Integer(0));
+ } catch (SocketException e) {
+ }
+ } else if (addr instanceof Inet6Address) {
+ throw new SocketException(Msg.getString("K0338"));
+ }
+ }
+
+ /**
+ * Set the network interface used by the socket. This is useful on
+ * multi-homed machines.
+ *
+ * @param netInterface
+ * NetworkInterface the interface to be used
+ * @exception java.net.SocketException
+ * the exception may be thrown while setting the address
+ *
+ * @since 1.4
+ */
+ public void setNetworkInterface(NetworkInterface netInterface)
+ throws SocketException {
+ checkClosedAndBind(false);
+ if (netInterface != null) {
+ InetAddress firstAddress = netInterface.getFirstAddress();
+ if (firstAddress != null) {
+ if (netInterface.getIndex() == NetworkInterface.UNSET_INTERFACE_INDEX) {
+ // set the address using IP_MULTICAST_IF to make sure this
+ // works for both IPV4 and IPV6
+ impl.setOption(SocketOptions.IP_MULTICAST_IF,
+ InetAddress.ANY);
+
+ try {
+ // we have the index so now we pass set the interface
+ // using IP_MULTICAST_IF2. This is what
+ // is used to set the interface on systems which support
+ // IPV6
+ impl
+ .setOption(
+ SocketOptions.IP_MULTICAST_IF2,
+ new Integer(
+ NetworkInterface.NO_INTERFACE_INDEX));
+ } catch (SocketException e) {
+ // for now just do this, -- could be narrowed?
+ }
+ }
+
+ // now try to set using IPV4 way. Howerver, if interface passed
+ // in has no ip addresses associated with it then we cannot do it.
+ // first we have to make sure there is an IPV4 address that we
+ // can use to call set interface otherwise we will not set it
+ Enumeration theAddresses = netInterface.getInetAddresses();
+ boolean found = false;
+ firstAddress = null;
+ while ((theAddresses.hasMoreElements()) && (found != true)) {
+ InetAddress theAddress = (InetAddress) theAddresses
+ .nextElement();
+ if (theAddress instanceof Inet4Address) {
+ firstAddress = theAddress;
+ found = true;
+ }
+ }
+ if (netInterface.getIndex() == NetworkInterface.NO_INTERFACE_INDEX) {
+ // the system does not support IPV6 and does not provide
+ // indexes for the network interfaces. Just pass in the first
+ // address for the network interface
+ if (firstAddress != null) {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF,
+ firstAddress);
+ } else {
+ // we should never get here as there should not be any
+ // network interfaces
+ // which have no IPV4 address and which doe not have the
+ // network interface
+ // index not set correctly
+ throw new SocketException(Msg.getString("K0335"));
+ }
+ } else {
+ // set the address using IP_MULTICAST_IF to make sure this
+ // works for both IPV4 and IPV6
+ if (firstAddress != null) {
+ impl.setOption(SocketOptions.IP_MULTICAST_IF,
+ firstAddress);
+ }
+
+ try {
+ // we have the index so now we pass set the interface
+ // using IP_MULTICAST_IF2. This is what
+ // is used to set the interface on systems which support
+ // IPV6
+ impl.setOption(SocketOptions.IP_MULTICAST_IF2,
+ new Integer(netInterface.getIndex()));
+ } catch (SocketException e) {
+ // for now just do this -- could be narrowed?
+ }
+ }
+ } else {
+ // this is ok if we could set it at the
+ throw new SocketException(Msg.getString("K0335"));
+ }
+ } else {
+ // throw a socket exception indicating that we do not support this
+ throw new SocketException(Msg.getString("K0334"));
+ }
+ interfaceSet = null;
+ }
+
+ /**
+ * Set the time-to-live (TTL) for multicast packets sent on this socket.
+ *
+ * @param ttl
+ * the time-to-live, 0<ttl<= 255
+ * @exception java.io.IOException
+ * The exception thrown while setting the TTL
+ */
+ public void setTimeToLive(int ttl) throws IOException {
+ checkClosedAndBind(false);
+ if (0 <= ttl && ttl <= 255)
+ impl.setTimeToLive(ttl);
+ else
+ throw new IllegalArgumentException(Msg.getString("K003c"));
+ }
+
+ /**
+ * Set the time-to-live (TTL) for multicast packets sent on this socket.
+ *
+ * @param ttl
+ * the time-to-live, 0<ttl<= 255
+ * @exception java.io.IOException
+ * The exception thrown while setting the TTL
+ * @deprecated Replaced by setTimeToLive
+ * @see #setTimeToLive(int)
+ */
+ public void setTTL(byte ttl) throws IOException {
+ checkClosedAndBind(false);
+ impl.setTTL(ttl);
+ }
+
+ synchronized void createSocket(int aPort, InetAddress addr)
+ throws SocketException {
+ impl = factory != null ? factory.createDatagramSocketImpl()
+ : createSocketImpl();
+ impl.create();
+ try {
+ // the required default options are now set in the VM where they
+ // should be
+ impl.bind(aPort, addr);
+ isBound = true;
+ } catch (SocketException e) {
+ close();
+ throw e;
+ }
+ }
+
+ /**
+ * Constructs a MulticastSocket bound to the host/port specified by the
+ * SocketAddress, or an unbound DatagramSocket if the SocketAddress is null.
+ *
+ * @param localAddr
+ * the local machine address and port to bind to
+ *
+ * @throws IllegalArgumentException
+ * if the SocketAddress is not supported
+ * @throws IOException
+ * if a problem occurs creating or binding the socket
+ *
+ * @since 1.4
+ */
+ public MulticastSocket(SocketAddress localAddr) throws IOException {
+ super(localAddr);
+ }
+
+ /**
+ * Get the state of the IP_MULTICAST_LOOP socket option.
+ *
+ * @return <code>true</code> if the IP_MULTICAST_LOOP is enabled,
+ * <code>false</code> otherwise.
+ *
+ * @throws SocketException
+ * if the socket is closed or the option is invalid.
+ *
+ * @since 1.4
+ */
+ public boolean getLoopbackMode() throws SocketException {
+ checkClosedAndBind(false);
+ return ((Boolean) impl.getOption(SocketOptions.IP_MULTICAST_LOOP))
+ .booleanValue();
+ }
+
+ /**
+ * Set the IP_MULTICAST_LOOP socket option.
+ *
+ * @param loop
+ * the socket IP_MULTICAST_LOOP option setting
+ *
+ * @throws SocketException
+ * if the socket is closed or the option is invalid.
+ *
+ * @since 1.4
+ */
+ public void setLoopbackMode(boolean loop) throws SocketException {
+ checkClosedAndBind(false);
+ impl.setOption(SocketOptions.IP_MULTICAST_LOOP, loop ? Boolean.TRUE
+ : Boolean.FALSE);
+ }
+
+ /**
+ * Answer a concrete instance of MulticastSocketImpl, either as declared in
+ * the system properties or the default, PlainDatagramSocketImpl. The latter
+ * does not support security checks.
+ *
+ * @return DatagramSocketImpl the concrete instance
+ *
+ * @exception SocketException
+ * if an error occurs during the instantiation of a type
+ * declared in the system properties
+ */
+ DatagramSocketImpl createSocketImpl() throws SocketException {
+ Object socketImpl = null;
+ String prefix;
+ prefix = (String) AccessController.doPrivileged(new PriviAction(
+ "impl.prefix", "Plain"));
+ try {
+ Class aClass = Class.forName("java.net." + prefix
+ + "MulticastSocketImpl");
+ socketImpl = aClass.newInstance();
+ } catch (Exception e) {
+ throw new SocketException(Msg.getString("K0033"));
+ }
+ return (DatagramSocketImpl) socketImpl;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegCacheElement.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegCacheElement.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegCacheElement.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegCacheElement.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,55 @@
+/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+/**
+ * This class is used to hold information about failed name lookups
+ */
+class NegCacheElement {
+
+ // we need the time to figure out when the entry is stale
+ long timeAdded = System.currentTimeMillis();
+
+ // holds the name of the host for which the lookup failed
+ String hostName;
+
+ /**
+ * default constructor
+ */
+ public NegCacheElement() {
+ super();
+ }
+
+ /**
+ * Constructor used to set the hostname for the failed entry
+ *
+ * @param hostName
+ * name of the host on which the lookup failed
+ */
+ public NegCacheElement(String hostName) {
+ this.hostName = hostName;
+ }
+
+ /**
+ * Answers the hostname for the cache element
+ *
+ * @return hostName name of the host on which the lookup failed
+ */
+ String hostName() {
+ return hostName;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegativeCache.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegativeCache.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegativeCache.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NegativeCache.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,128 @@
+/* Copyright 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.security.AccessController;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * This class is used to manage the negative name lookup cache.
+ */
+class NegativeCache extends LinkedHashMap {
+
+ static NegativeCache negCache = null;
+
+ // maximum number of entries in the cache
+ static final int MAX_NEGATIVE_ENTRIES = 5;
+
+ // the loading for the cache
+ static final float LOADING = (float) 0.75;
+
+ /**
+ * Answers the hostname for the cache element
+ *
+ * @return hostName name of the host on which the lookup failed
+ */
+ NegativeCache(int initialCapacity, float loadFactor, boolean accessOrder) {
+ super(initialCapacity, loadFactor, accessOrder);
+ }
+
+ /**
+ * Answers if we should remove the Eldest entry. We remove the eldest entry
+ * if the size has grown beyond the maximum size allowed for the cache. We
+ * create the LinkedHashMap such that this deletes the least recently used
+ * entry
+ *
+ * @param eldest
+ * the map enty which will be deleted if we return true
+ */
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > MAX_NEGATIVE_ENTRIES;
+ }
+
+ /**
+ * Adds the host name and the corresponding name lookup fail message to the
+ * cache
+ *
+ * @param hostName
+ * the name of the host for which the lookup failed
+ * @param failedMessage
+ * the message returned when we failed the lookup
+ */
+ static void put(String hostName, String failedMessage) {
+ checkCacheExists();
+ negCache.put(hostName, new NegCacheElement(failedMessage));
+ }
+
+ /**
+ * Answers the message that occured when we failed to lookup the host if
+ * such a failure is within the cache and the entry has not yet expired
+ *
+ * @param hostName
+ * the name of the host for which we are looking for an entry
+ * @return the message which was returned when the host failed to be looked
+ * up if there is still a valid entry within the cache
+ */
+ static String getFailedMessage(String hostName) {
+ checkCacheExists();
+ NegCacheElement element = (NegCacheElement) negCache.get(hostName);
+ if (element != null) {
+ // check if element is still valid
+ String ttlValue = (String) AccessController
+ .doPrivileged(new PriviAction(
+ "networkaddress.cache.negative.ttl"));
+ int ttl = 10;
+ try {
+ if (ttlValue != null)
+ ttl = Integer.decode(ttlValue).intValue();
+ } catch (NumberFormatException e) {
+ }
+ if (ttl == 0) {
+ negCache.clear();
+ element = null;
+ } else if (ttl != -1) {
+ if (element.timeAdded + (ttl * 1000) < System
+ .currentTimeMillis()) {
+ // remove the element from the cache and return null
+ negCache.remove(hostName);
+ element = null;
+ }
+ }
+ }
+ if (element != null) {
+ return element.hostName();
+ }
+ return null;
+ }
+
+ /**
+ * This method checks if we have created the cache and if not creates it
+ */
+ static void checkCacheExists() {
+ if (negCache == null) {
+ // Create with the access order set so ordering is based on when the
+ // entries were last accessed. We make the default cache size one
+ // greater than the maximum number of entries as we will grow to one
+ // larger and then delete the LRU entry
+ negCache = new NegativeCache(MAX_NEGATIVE_ENTRIES + 1, LOADING,
+ true);
+ }
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetPermission.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetPermission.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetPermission.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetPermission.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,60 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+/**
+ * This class represents permission to access network resources.
+ * <p>
+ * There are three valid target names:
+ * <dl>
+ * <dt>setDefaultAuthenticator</dt>
+ * <dd>Allows the default authenticator to be set.</dd>
+ * <dt>requestPasswordAuthentication</dt>
+ * <dd>Allows the default authenticator to be retrieved.</dd>
+ * <dt>specifyStreamHandler</dt>
+ * <dd>Allows a stream (protocol) handler to be set when constructing an URL
+ * object</dd>
+ * </dl>
+ *
+ * @see java.security.BasicPermission
+ * @see SecurityManager
+ */
+public final class NetPermission extends java.security.BasicPermission {
+
+ /**
+ * Creates an instance of this class with the given name.
+ *
+ * @param name
+ * String the name of the new permission.
+ */
+ public NetPermission(String name) {
+ super(name);
+ }
+
+ /**
+ * Creates an instance of this class with the given name and action list.
+ * The action list is ignored.
+ *
+ * @param name
+ * String the name of the new permission.
+ * @param actions
+ * String ignored.
+ */
+ public NetPermission(String name, String actions) {
+ super(name, actions);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetworkInterface.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetworkInterface.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetworkInterface.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NetworkInterface.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,391 @@
+/* Copyright 2005, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import com.ibm.oti.util.Msg;
+
+/**
+ * This class provides an methods that are used to get information about the
+ * network interfaces supported by the system
+ */
+public final class NetworkInterface extends Object {
+
+ private static final int CHECK_CONNECT_NO_PORT = -1;
+
+ static final int NO_INTERFACE_INDEX = 0;
+
+ static final int UNSET_INTERFACE_INDEX = -1;
+
+ private String name = null;
+
+ private String displayName = null;
+
+ private InetAddress addresses[] = null;
+
+ // The interface index is a positive integer which is non-negative. Where
+ // value is zero then we do not have an index for the interface (which
+ // occurs in systems which only support IPV4)
+ private int interfaceIndex = 0;
+
+ private int hashCode = 0;
+
+ /**
+ * This native answers the list of network interfaces supported by the
+ * system. An array is returned which is easier to generate and which can
+ * easily be converted into the required enumeration on the java side
+ *
+ * @return an array of zero or more NetworkInterface objects
+ *
+ * @throws SocketException
+ * if an error occurs when getting network interface information
+ */
+ private static native NetworkInterface[] getNetworkInterfacesImpl()
+ throws SocketException;
+
+ /**
+ * This constructor is used by the native method in order to construct the
+ * NetworkInterface objects in the array tht it returns
+ *
+ * @param name
+ * internal name associated with the interface
+ * @param displayName
+ * a user interpretable name for the interface
+ * @param addresses
+ * the Inet addresses associated with the interface
+ * @param interfaceIndex
+ * an index for the interface. Only set for platforms that
+ * support IPV6
+ */
+ NetworkInterface(String name, String displayName, InetAddress addresses[],
+ int interfaceIndex) {
+ this.name = name;
+ this.displayName = displayName;
+ this.addresses = addresses;
+ this.interfaceIndex = interfaceIndex;
+ }
+
+ /**
+ * Answers the index for the network interface. Unless the system supports
+ * IPV6 this will be 0.
+ *
+ * @return the index
+ */
+ int getIndex() {
+ return interfaceIndex;
+ }
+
+ /**
+ * Answers the first address for the network interface. This is used in the
+ * natives when we need one of the addresses for the interface and any one
+ * will do
+ *
+ * @return the first address if one exists, otherwise null.
+ */
+ InetAddress getFirstAddress() {
+ if ((addresses != null) && (addresses.length >= 1)) {
+ return addresses[0];
+ }
+ return null;
+ }
+
+ /**
+ * Answers the name associated with the network interface
+ *
+ * @return name associated with the network interface
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Answers the list of inet addresses bound to the interface
+ *
+ * @return list of inet addresses bound to the interface
+ */
+ public Enumeration getInetAddresses() {
+ // create new vector from which Enumeration to be returned can be
+ // generated set the initial capacity to be the number of addresses for
+ // the network interface which is the maximum required size
+
+ // just return null if there are not addresses associated with the
+ // interface
+ if (addresses == null) {
+ return null;
+ }
+
+ // for those configuration that support the security manager we only
+ // return addresses for which checkConnect returns true
+ Vector accessibleAddresses = new Vector(addresses.length);
+
+ // get the security manager. If one does not exist just return
+ // the full list
+ SecurityManager security = System.getSecurityManager();
+ if (security == null) {
+ return (new Vector(Arrays.asList(addresses))).elements();
+ }
+
+ // ok security manager exists so check each address and return
+ // those that pass
+ for (int i = 0; i < addresses.length; i++) {
+ if (security != null) {
+ try {
+ // since we don't have a port in this case we pass in
+ // NO_PORT
+ security.checkConnect(addresses[i].getHostName(),
+ CHECK_CONNECT_NO_PORT);
+ accessibleAddresses.add(addresses[i]);
+ } catch (SecurityException e) {
+ }
+ }
+ }
+
+ Enumeration theAccessibleElements = accessibleAddresses.elements();
+
+ if (theAccessibleElements.hasMoreElements()) {
+ return accessibleAddresses.elements();
+ }
+
+ return null;
+ }
+
+ /**
+ * Answers the user readable name associated with the network interface
+ *
+ * @return display name associated with the network interface or null if one
+ * is not available
+ */
+ public String getDisplayName() {
+ // we should return the display name unless it is blank in this
+ // case return the name so that something is displayed.
+ if (!(displayName.equals(""))) {
+ return displayName;
+ }
+ return name;
+
+ }
+
+ /**
+ * Answers the network interface with the specified name, if one exists
+ *
+ * @return network interface for name specified if it exists, otherwise null
+ *
+ * @throws SocketException
+ * if an error occurs when getting network interface information
+ * @throws NullPointerException
+ * if the interface name passed in is null
+ */
+ public static NetworkInterface getByName(String interfaceName)
+ throws SocketException {
+
+ if (interfaceName == null) {
+ throw new NullPointerException(Msg.getString("K0330"));
+ }
+
+ // get the list of interfaces, and then loop through the list to look
+ // for one with a matching name
+ Enumeration interfaces = getNetworkInterfaces();
+ if (interfaces != null) {
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface netif = (NetworkInterface) interfaces
+ .nextElement();
+ if (netif.getName().equals(interfaceName)) {
+ return netif;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Answers the network interface which has the specified inet address bound
+ * to it, if one exists.
+ *
+ * @param address
+ * address of interest
+ * @return network interface for inet address specified if it exists,
+ * otherwise null
+ *
+ * @throws SocketException
+ * if an error occurs when getting network interface information
+ * @throws NullPointerException
+ * if the address passed in is null
+ */
+ public static NetworkInterface getByInetAddress(InetAddress address)
+ throws SocketException {
+
+ if (address == null) {
+ throw new NullPointerException(Msg.getString("K0331"));
+ }
+
+ // get the list of interfaces, and then loop through the list. For each
+ // interface loop through the associated set of inet addresses and see
+ // if
+ // one matches. If so return that network interface
+ Enumeration interfaces = getNetworkInterfaces();
+ if (interfaces != null) {
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface netif = (NetworkInterface) interfaces
+ .nextElement();
+ // to be compatible use the raw addresses without any security
+ // filtering
+ // Enumeration netifAddresses = netif.getInetAddresses();
+ if ((netif.addresses != null) && (netif.addresses.length != 0)) {
+ Enumeration netifAddresses = (new Vector(Arrays
+ .asList(netif.addresses))).elements();
+ if (netifAddresses != null) {
+ while (netifAddresses.hasMoreElements()) {
+ if (address.equals(netifAddresses
+ .nextElement())) {
+ return netif;
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Answers the list of network interfaces supported by the system or null if
+ * no interfaces are supported by the system
+ *
+ * @return Enumeration containing one NetworkInterface object for each
+ * interface supported by the system
+ *
+ * @throws SocketException
+ * if an error occurs when getting network interface information
+ */
+ public static Enumeration getNetworkInterfaces() throws SocketException {
+ NetworkInterface[] interfaces = getNetworkInterfacesImpl();
+ if (interfaces == null) {
+ return null;
+ }
+ return (new Vector(Arrays.asList(interfaces))).elements();
+ }
+
+ /**
+ * Compares the specified object to this NetworkInterface and answer if they
+ * are equal. The object must be an instance of NetworkInterface with the
+ * same name, displayName and list of network interfaces to be the same
+ *
+ * @param obj
+ * the object to compare
+ * @return true if the specified object is equal to this NetworkInterfcae,
+ * false otherwise
+ *
+ * @see #hashCode
+ */
+ public boolean equals(Object obj) {
+
+ // just return true if it is the exact same object
+ if (obj == this)
+ return true;
+
+ if (obj instanceof NetworkInterface) {
+ // make sure that some simple checks pass. If the name is not the
+ // same then we are sure it is not the same one. We don't check the
+ // hashcode as it is generated from the name which we check
+ NetworkInterface netif = (NetworkInterface) obj;
+
+ if (netif.getIndex() != interfaceIndex) {
+ return false;
+ }
+
+ if (!(name.equals("")) && (!netif.getName().equals(name))) {
+ return false;
+ }
+
+ if ((name.equals("")) && (!netif.getName().equals(displayName))) {
+ return false;
+ }
+
+ // now check that the inet addresses are the same
+ Enumeration netifAddresses = netif.getInetAddresses();
+ Enumeration localifAddresses = getInetAddresses();
+ if ((netifAddresses == null) && (localifAddresses != null)) {
+ return false;
+ }
+
+ if ((netifAddresses == null) && (localifAddresses == null)) {
+ // neither have any addresses so they are the same
+ return true;
+ }
+
+ if (netifAddresses != null) {
+ while (netifAddresses.hasMoreElements()
+ && localifAddresses.hasMoreElements()) {
+ if (!((InetAddress) localifAddresses.nextElement())
+ .equals(netifAddresses.nextElement())) {
+ return false;
+ }
+ }
+ // now make sure that they had the same number of inet
+ // addresses, if not
+ // they are not the same interfac
+ if (netifAddresses.hasMoreElements()
+ || localifAddresses.hasMoreElements()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Answers a hash code for this NetworkInterface object. Since the name
+ * should be unique for each network interface the hash code is generated
+ * using this name
+ *
+ * @return the hashcode for hashtable indexing
+ */
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = name.hashCode();
+ }
+ return hashCode;
+ }
+
+ /**
+ * Answers a string containing a concise, human-readable description of the
+ * network interface
+ *
+ * @return a printable representation for the network interface
+ */
+ public String toString() {
+ StringBuffer stringRepresentation = new StringBuffer("[" + name + "]["
+ + displayName + "]");
+
+ // get the addresses through this call to make sure we only reveal
+ // those that we should
+ Enumeration theAddresses = getInetAddresses();
+ if (theAddresses != null) {
+ while (theAddresses.hasMoreElements()) {
+ InetAddress nextAddress = (InetAddress) theAddresses
+ .nextElement();
+ stringRepresentation.append("[" + nextAddress.toString() + "]");
+ }
+ }
+ return stringRepresentation.toString();
+ }
+
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NoRouteToHostException.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NoRouteToHostException.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NoRouteToHostException.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/NoRouteToHostException.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,43 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+/**
+ * The NoRouteToHostException may be thrown when attempting to connect to a
+ * remote machine and because of network fault or firewall, no route can be
+ * established.
+ */
+public class NoRouteToHostException extends SocketException {
+
+ /**
+ * Constructs a new instance of this class with its walkback filled in.
+ */
+ public NoRouteToHostException() {
+ super();
+ }
+
+ /**
+ * Constructs a new instance of this class with its walkback and message
+ * filled in.
+ *
+ * @param detailMessage
+ * String The detail message for the exception.
+ */
+ public NoRouteToHostException(String detailMessage) {
+ super(detailMessage);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PasswordAuthentication.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PasswordAuthentication.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PasswordAuthentication.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PasswordAuthentication.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,59 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+/**
+ * This class is a data structure that contains the username and password.
+ */
+public final class PasswordAuthentication {
+
+ private String userName;
+
+ private char[] password;
+
+ /**
+ * Creates an instance of a password authentication with a username and
+ * password.
+ *
+ * @param userName
+ * java.lang.String the username
+ * @param password
+ * char[] the password
+ */
+ public PasswordAuthentication(String userName, char[] password) {
+ this.userName = userName;
+ this.password = (char[]) password.clone();
+ }
+
+ /**
+ * Answers the reference of the password of this class.
+ *
+ * @return char[] the reference of the password
+ */
+ public char[] getPassword() {
+ return (char[]) password.clone();
+ }
+
+ /**
+ * Answers the username of this class.
+ *
+ * @return java.lang.String the username of this class
+ */
+ public String getUserName() {
+ return userName;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainDatagramSocketImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainDatagramSocketImpl.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainDatagramSocketImpl.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainDatagramSocketImpl.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,670 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.security.AccessController;
+
+import com.ibm.oti.util.Msg;
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * The default, concrete instance of datagram sockets. This class does not
+ * support security checks. Alternative types of DatagramSocketImpl's may be
+ * used by setting the <code>impl.prefix</code> system property.
+ */
+
+class PlainDatagramSocketImpl extends DatagramSocketImpl {
+
+ private final static int SO_BROADCAST = 32;
+
+ final static int IP_MULTICAST_ADD = 19;
+
+ final static int IP_MULTICAST_DROP = 20;
+
+ final static int IP_MULTICAST_TTL = 17;
+
+ private boolean bindToDevice;
+
+ private byte[] ipaddress = { 0, 0, 0, 0 };
+
+ private int ttl = 1;
+
+ private volatile boolean isNativeConnected = false;
+
+ // for datagram and multicast sockets we have to set
+ // REUSEADDR and REUSEPORT when REUSEADDR is set
+ // for other types of sockets we need to just set REUSEADDR
+ // therefore we have this other option which sets
+ // both if supported by the platform.
+ // this cannot be in SOCKET_OPTIONS because since it
+ // is a public interface it ends up being public even
+ // if it is not declared public
+ static final int REUSEADDR_AND_REUSEPORT = 10001;
+
+ // used to keep address to which the socket was connected to at the
+ // native level
+ private InetAddress connectedAddress = null;
+
+ private int connectedPort = -1;
+
+ // used to store the trafficClass value which is simply returned
+ // as the value that was set. We also need it to pass it to methods
+ // that specify an address packets are going to be sent to
+ private int trafficClass = 0;
+
+ // Fill in the JNI id caches
+ private static native void oneTimeInitialization(boolean jcl_IPv6_support);
+
+ static {
+ oneTimeInitialization(true);
+ }
+
+ /**
+ * Bind the datagram socket to the nominated localhost/port. Sockets must be
+ * bound prior to attempting to send or receive data.
+ *
+ * @param port
+ * the port on the localhost to bind
+ * @param addr
+ * the address on the multihomed localhost to bind
+ *
+ * @exception SocketException
+ * if an error occured during bind, such as if the port was
+ * already bound
+ */
+ protected void bind(int port, InetAddress addr) throws SocketException {
+ String prop = (String) AccessController.doPrivileged(new PriviAction(
+ "bindToDevice"));
+ boolean useBindToDevice = prop != null
+ && prop.toLowerCase().equals("true");
+ bindToDevice = socketBindImpl2(fd, port, useBindToDevice, addr);
+ if (0 != port) {
+ localPort = port;
+ } else {
+ localPort = Socket.getSocketLocalPortImpl(fd, InetAddress
+ .preferIPv6Addresses());
+ }
+
+ try {
+ // Ignore failures
+ setOption(SO_BROADCAST, Boolean.TRUE);
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Close the socket.
+ */
+ protected void close() {
+
+ synchronized (fd) {
+ if (fd.valid()) {
+ Socket.socketCloseImpl(fd);
+ initializeSocket();
+ }
+ }
+ }
+
+ /**
+ * Allocate the socket descriptor in the IP stack.
+ */
+ protected void create() throws SocketException {
+ createDatagramSocketImpl(fd, Socket.preferIPv4Stack());
+ }
+
+ protected void finalize() {
+ close();
+ }
+
+ /**
+ * Answer the local address from the IP stack. This method should not be
+ * called directly as it does not check the security policy.
+ *
+ * @return InetAddress the local address to which the socket is bound.
+ * @see DatagramSocket
+ */
+ InetAddress getLocalAddress() {
+ return Socket.getSocketLocalAddressImpl(fd, InetAddress
+ .preferIPv6Addresses());
+ }
+
+ /**
+ * Answer the nominated socket option. As the timeouts are not set as
+ * options in the IP stack, the field value is returned.
+ *
+ * @return Object the nominated socket option value
+ */
+ public Object getOption(int optID) throws SocketException {
+ if (optID == SocketOptions.SO_TIMEOUT) {
+ return new Integer(receiveTimeout);
+ } else if (optID == SocketOptions.IP_TOS) {
+ return new Integer(trafficClass);
+ } else {
+ // Call the native first so there will be
+ // an exception if the socket if closed.
+ Object result = Socket.getSocketOptionImpl(fd, optID);
+ if (optID == SocketOptions.IP_MULTICAST_IF
+ && (Socket.getSocketFlags() & Socket.MULTICAST_IF) != 0) {
+
+ return new Inet4Address(ipaddress);
+ }
+ return result;
+ }
+ }
+
+ protected int getTimeToLive() throws IOException {
+ // Call the native first so there will be an exception if the socket if
+ // closed.
+ int result = (((Byte) getOption(IP_MULTICAST_TTL)).byteValue()) & 0xFF;
+ if ((Socket.getSocketFlags() & Socket.MULTICAST_TTL) != 0)
+ return ttl;
+ return result;
+ }
+
+ protected byte getTTL() throws IOException {
+ // Call the native first so there will be an exception if the socket if
+ // closed.
+ byte result = ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
+ if ((Socket.getSocketFlags() & Socket.MULTICAST_TTL) != 0)
+ return (byte) ttl;
+ return result;
+ }
+
+ /**
+ * Add this socket to the multicast group. A socket must joint a group
+ * before data may be received. A socket may be a member of multiple groups
+ * but may join any group once.
+ *
+ * @param addr
+ * the multicast group to be joined
+ * @exception java.io.IOException
+ * may be thrown while joining a group
+ */
+ protected void join(InetAddress addr) throws IOException {
+ setOption(IP_MULTICAST_ADD, new GenericIPMreq(addr));
+ }
+
+ /**
+ * Add this socket to the multicast group. A socket must join a group before
+ * data may be received. A socket may be a member of multiple groups but may
+ * join any group once.
+ *
+ * @param addr
+ * the multicast group to be joined
+ * @param netInterface
+ * the network interface on which the addresses should be dropped
+ * @exception java.io.IOException
+ * may be thrown while joining a group
+ */
+ protected void joinGroup(SocketAddress addr, NetworkInterface netInterface)
+ throws IOException {
+ if (addr instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
+ setOption(IP_MULTICAST_ADD, new GenericIPMreq(groupAddr,
+ netInterface));
+ }
+ }
+
+ /**
+ * Remove the socket from the multicast group.
+ *
+ * @param addr
+ * the multicast group to be left
+ * @exception java.io.IOException
+ * May be thrown while leaving the group
+ */
+ protected void leave(InetAddress addr) throws IOException {
+ setOption(IP_MULTICAST_DROP, new GenericIPMreq(addr));
+ }
+
+ /**
+ * Remove the socket from the multicast group.
+ *
+ * @param addr
+ * the multicast group to be left
+ * @param netInterface
+ * the network interface on which the addresses should be dropped
+ * @exception java.io.IOException
+ * May be thrown while leaving the group
+ */
+ protected void leaveGroup(SocketAddress addr, NetworkInterface netInterface)
+ throws IOException {
+ if (addr instanceof InetSocketAddress) {
+ InetAddress groupAddr = ((InetSocketAddress) addr).getAddress();
+ setOption(IP_MULTICAST_DROP, new GenericIPMreq(groupAddr,
+ netInterface));
+ }
+ }
+
+ /**
+ * Connect the socket to a port and address
+ *
+ * @param aFD
+ * the FileDescriptor to associate with the socket
+ * @param port
+ * the port to connect to
+ * @param trafficClass
+ * the traffic Class to be used then the connection is made
+ * @param inetAddress
+ * address to connect to.
+ *
+ * @exception SocketException
+ * if the connect fails
+ */
+ protected static native void connectDatagramImpl2(FileDescriptor aFD,
+ int port, int trafficClass, InetAddress inetAddress)
+ throws SocketException;
+
+ /**
+ * Disconnect the socket to a port and address
+ *
+ * @param aFD
+ * the FileDescriptor to associate with the socket
+ *
+ * @exception SocketException
+ * if the disconnect fails
+ */
+ protected static native void disconnectDatagramImpl(FileDescriptor aFD)
+ throws SocketException;
+
+ /**
+ * Allocate a datagram socket in the IP stack. The socket is associated with
+ * the <code>aFD</code>.
+ *
+ * @param aFD
+ * the FileDescriptor to associate with the socket
+ * @param preferIPv4Stack
+ * IP stack preference if underlying platform is V4/V6
+ * @exception SocketException
+ * upon an allocation error
+ */
+ protected static native void createDatagramSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /**
+ * Bind the socket to the port/localhost in the IP stack.
+ *
+ * @param aFD
+ * the socket descriptor
+ * @param port
+ * the option selector
+ * @param bindToDevice
+ * bind the socket to the specified interface
+ * @param inetAddress
+ * address to connect to.
+ * @exception SocketException
+ * thrown if bind operation fails
+ */
+ protected static native boolean socketBindImpl2(FileDescriptor aFD,
+ int port, boolean bindToDevice, InetAddress inetAddress)
+ throws SocketException;
+
+ /**
+ * Peek on the socket, update <code>sender</code> address and answer the
+ * sender port.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @param sender
+ * an InetAddress, to be updated with the sender's address
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @return int the sender port
+ *
+ * @exception IOException
+ * upon an read error or timeout
+ */
+ protected static native int peekDatagramImpl(FileDescriptor aFD,
+ InetAddress sender, int receiveTimeout) throws IOException;
+
+ /**
+ * Recieve data on the socket into the specified buffer. The packet fields
+ * <code>data</code> & <code>length</code> are passed in addition to
+ * <code>packet</code> to eliminate the JNI field access calls.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @param packet
+ * the DatagramPacket to receive into
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @param peek
+ * indicates to peek at the data
+ * @exception IOException
+ * upon an read error or timeout
+ */
+ protected static native int receiveDatagramImpl2(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /**
+ * Recieve data on the connected socket into the specified buffer. The
+ * packet fields <code>data</code> & <code>length</code> are passed in
+ * addition to <code>packet</code> to eliminate the JNI field access
+ * calls.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @param packet
+ * the DatagramPacket to receive into
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @param peek
+ * indicates to peek at the data
+ * @exception IOException
+ * upon an read error or timeout
+ */
+ protected static native int recvConnectedDatagramImpl(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /**
+ * Send the <code>data</code> to the nominated target <code>address</code>
+ * and <code>port</code>. These values are derived from the
+ * DatagramPacket to reduce the field calls within JNI.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param port
+ * the target host port
+ * @param trafficClass
+ * the traffic class to be used when the datagram is sent
+ * @param inetAddress
+ * address to connect to.
+ *
+ * @exception IOException
+ * upon an read error or timeout
+ */
+ protected static native int sendDatagramImpl2(FileDescriptor fd,
+ byte[] data, int offset, int length, int port,
+ boolean bindToDevice, int trafficClass, InetAddress inetAddress)
+ throws IOException;
+
+ /**
+ * Send the <code>data</code> to the address and port to which the was
+ * connnected and <code>port</code>.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param bindToDevice
+ * not used, current kept in case needed as was the case for
+ * sendDatagramImpl
+ * @exception IOException
+ * upon an read error or timeout
+ */
+ protected static native int sendConnectedDatagramImpl(FileDescriptor fd,
+ byte[] data, int offset, int length, boolean bindToDevice)
+ throws IOException;
+
+ protected int peek(InetAddress sender) throws IOException {
+ if (isNativeConnected) {
+ // in this case we know the port and address from which the data
+ // must have be been received as the socket is connected. However,
+ // we still need to do the receive in order to know that there was
+ // data received. We use a short buffer as we don't actually need
+ // the packet, only the knowledge that it is there
+ byte[] storageArray = new byte[10];
+ DatagramPacket pack = new DatagramPacket(storageArray,
+ storageArray.length);
+ recvConnectedDatagramImpl(fd, pack, pack.getData(), pack
+ .getOffset(), pack.getLength(), receiveTimeout, true); // peek
+ sender.ipaddress = connectedAddress.getAddress();
+ return connectedPort;
+ }
+ return peekDatagramImpl(fd, sender, receiveTimeout);
+ }
+
+ /**
+ * Answer the data that may be read at this socket. Any data larger than the
+ * packet buffer length will be discarded. The read will block until either
+ * data is is read or, if the timeout is defined, the operation times out.
+ *
+ * @exception IOException
+ * if an error or timeout occurs during a read
+ */
+ protected void receive(DatagramPacket pack) throws java.io.IOException {
+ try {
+ if (isNativeConnected) {
+ // do not peek
+ recvConnectedDatagramImpl(fd, pack, pack.getData(), pack
+ .getOffset(), pack.getLength(), receiveTimeout, false);
+ updatePacketRecvAddress(pack);
+ } else {
+ receiveDatagramImpl2(fd, pack, pack.getData(),
+ pack.getOffset(), pack.getLength(), receiveTimeout,
+ false // do not peek
+ );
+ }
+ } catch (InterruptedIOException e) {
+ throw new SocketTimeoutException(e.getMessage());
+ }
+ }
+
+ /**
+ * Send the data on this socket.
+ *
+ * @exception IOException
+ * if an error occurs during the write
+ */
+ protected void send(DatagramPacket packet) throws IOException {
+
+ if (isNativeConnected) {
+ sendConnectedDatagramImpl(fd, packet.getData(), packet.getOffset(),
+ packet.getLength(), bindToDevice);
+ } else {
+ sendDatagramImpl2(fd, packet.getData(), packet.getOffset(), packet
+ .getLength(), packet.getPort(), bindToDevice, trafficClass,
+ packet.getAddress());
+ }
+ }
+
+ /**
+ * Set the nominated socket option. As the timeouts are not set as options
+ * in the IP stack, the value is stored in an instance field.
+ *
+ * @exception SocketException
+ * thrown if the option value is unsupported or invalid
+ */
+ public void setOption(int optID, Object val) throws SocketException {
+ // for datagram sockets on some platforms we have to set both the
+ // REUSEADDR AND REUSEPORT so for REUSEADDR set this option option
+ // which tells the VM to set the two values as appropriate for the
+ // platform
+ if (optID == SocketOptions.SO_REUSEADDR) {
+ optID = REUSEADDR_AND_REUSEPORT;
+ }
+
+ if (optID == SocketOptions.SO_TIMEOUT) {
+ receiveTimeout = ((Integer) val).intValue();
+ } else {
+ int flags = Socket.getSocketFlags();
+ try {
+ Socket.setSocketOptionImpl(fd, optID | (flags << 16), val);
+ } catch (SocketException e) {
+ // we don't throw an exception for IP_TOS even if the platform
+ // won't let us set the requested value
+ if (optID != SocketOptions.IP_TOS) {
+ throw e;
+ }
+ }
+ if (optID == SocketOptions.IP_MULTICAST_IF
+ && (flags & Socket.MULTICAST_IF) != 0) {
+ InetAddress inet = (InetAddress) val;
+ if (InetAddress.bytesToInt(inet.ipaddress, 0) == 0
+ || inet.equals(InetAddress.LOOPBACK)) {
+ ipaddress = ((InetAddress) val).getAddress();
+ } else {
+ InetAddress local = null;
+ try {
+ local = InetAddress.getLocalHost();
+ } catch (UnknownHostException e) {
+ throw new SocketException("getLocalHost(): "
+ + e.toString());
+ }
+ if (inet.equals(local)) {
+ ipaddress = ((InetAddress) val).getAddress();
+ } else {
+ throw new SocketException(val + " != getLocalHost(): "
+ + local);
+ }
+ }
+ }
+ // save this value as it is acutally used differently for IPv4 and
+ // IPv6 so we cannot get the value using the getOption. The option
+ // is actually only set for IPv4 and a masked version of the value
+ // will be set as only a subset of the values are allowed on the
+ // socket. Therefore we need to retain it to return the value that
+ // was set. We also need the value to be passed into a number of
+ // natives so that it can be used properly with IPv6
+ if (optID == SocketOptions.IP_TOS) {
+ trafficClass = ((Integer) val).intValue();
+ }
+ }
+ }
+
+ protected void setTimeToLive(int ttl) throws java.io.IOException {
+ setOption(IP_MULTICAST_TTL, new Byte((byte) (ttl & 0xFF)));
+ if ((Socket.getSocketFlags() & Socket.MULTICAST_TTL) != 0) {
+ this.ttl = ttl;
+ }
+ }
+
+ protected void setTTL(byte ttl) throws java.io.IOException {
+ setOption(IP_MULTICAST_TTL, new Byte(ttl));
+ if ((Socket.getSocketFlags() & Socket.MULTICAST_TTL) != 0) {
+ this.ttl = ttl;
+ }
+ }
+
+ /**
+ * Connect the socket to the specified remote address and port.
+ *
+ * @param inetAddr
+ * the remote address
+ * @param port
+ * the remote port
+ *
+ * @exception SocketException
+ * possibly thrown, if the datagram socket cannot be
+ * connected to the specified remote address and port
+ */
+ protected void connect(InetAddress inetAddr, int port)
+ throws SocketException {
+
+ connectDatagramImpl2(fd, port, trafficClass, inetAddr);
+
+ // if we get here then we are connected at the native level
+ try {
+ connectedAddress = InetAddress.getByAddress(inetAddr.getAddress());
+ } catch (UnknownHostException e) {
+ // this is never expected to happen as we should not have gotten
+ // here if the address is not resolvable
+ throw new SocketException(Msg.getString(
+ "K0317", inetAddr.getHostName())); //$NON-NLS-1$
+ }
+ connectedPort = port;
+ isNativeConnected = true;
+ }
+
+ /**
+ * Disconnect the socket from the remote address and port.
+ */
+ protected void disconnect() {
+ try {
+ disconnectDatagramImpl(fd);
+ } catch (Exception e) {
+ // there is currently no way to return an error so just eat any
+ // exception
+ }
+ connectedPort = -1;
+ connectedAddress = null;
+ isNativeConnected = false;
+ }
+
+ /**
+ * Receive data into the supplied datagram packet by peeking. The data is
+ * not removed and will be received by another peekData() or receive() call.
+ *
+ * This call will block until either data is received or, if a timeout is
+ * set, the timeout expires.
+ *
+ * @param pack
+ * the DatagramPacket used to store the data
+ *
+ * @return the port the packet was received from
+ *
+ * @exception IOException
+ * if an error occurs
+ */
+ protected int peekData(DatagramPacket pack) throws IOException {
+ try {
+ if (isNativeConnected) {
+ recvConnectedDatagramImpl(fd, pack, pack.getData(), pack
+ .getOffset(), pack.getLength(), receiveTimeout, true); // peek
+ updatePacketRecvAddress(pack);
+ } else {
+ receiveDatagramImpl2(fd, pack, pack.getData(),
+ pack.getOffset(), pack.getLength(), receiveTimeout,
+ true); // peek
+ }
+ } catch (InterruptedIOException e) {
+ throw new SocketTimeoutException(e.getMessage());
+ }
+ return pack.getPort();
+ }
+
+ /**
+ * Set the received address and port in the packet. We do this when the
+ * Datagram socket is connected at the native level and the
+ * recvConnnectedDatagramImpl does not update the packet with address from
+ * which the packet was received
+ *
+ * @param packet
+ * the packet to be updated
+ */
+ private void updatePacketRecvAddress(DatagramPacket packet) {
+ packet.setAddress(connectedAddress);
+ packet.port = connectedPort;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainMulticastSocketImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainMulticastSocketImpl.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainMulticastSocketImpl.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainMulticastSocketImpl.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,50 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.io.FileDescriptor;
+
+/**
+ * This class was added so we can create sockets with options that are needed
+ * for server sockets. It just overrides create so that we call new natives
+ * which only set the options required for server sockets. In order to preserve
+ * behaviour of older versions the create PlainSocketImpl was left as is and
+ * this new class was added. For newer versions an instance of this class is
+ * used, for earlier versions the original PlainSocketImpl is used.
+ */
+class PlainMulticastSocketImpl extends PlainDatagramSocketImpl {
+
+ /**
+ * Answer the result of attempting to create a multicast socket in the IP
+ * stack. Any special options required for server sockets will be set by
+ * this method.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @exception SocketException
+ * if an error occurs while creating the socket
+ */
+ static native void createMulticastSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /**
+ * Allocate the socket descriptor in the IP stack.
+ */
+ protected void create() throws SocketException {
+ createMulticastSocketImpl(fd, Socket.preferIPv4Stack());
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainServerSocketImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainServerSocketImpl.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainServerSocketImpl.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/luni/src/java/net/PlainServerSocketImpl.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,62 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+
+import java.io.FileDescriptor;
+
+/**
+ * This class was added so we can create sockets with options that are needed
+ * for server sockets. It just overrides create so that we call new natives
+ * which only set the options required for server sockets. In order to preserve
+ * behaviour of older versions the create PlainSocketImpl was left as is and
+ * this new class was added. For newer versions an instance of this class is
+ * used, for earlier versions the original PlainSocketImpl is used.
+ */
+class PlainServerSocketImpl extends PlainSocketImpl {
+
+ /**
+ * Answer the result of attempting to create a server stream socket in the
+ * IP stack. Any special options required for server sockets will be set by
+ * this method.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @exception SocketException
+ * if an error occurs while creating the socket
+ */
+ static native void createServerStreamSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /**
+ * Creates a new unconnected socket. If streaming is true, create a stream
+ * socket, else a datagram socket. The deprecated datagram usage is not
+ * supported and will throw an exception.
+ *
+ * @param isStreaming
+ * true, if the socket is type streaming
+ * @exception SocketException
+ * if an error occurs while creating the socket
+ */
+ protected void create(boolean isStreaming) throws SocketException {
+ this.streaming = isStreaming;
+ if (isStreaming) {
+ createServerStreamSocketImpl(fd, Socket.preferIPv4Stack());
+ } else {
+ createDatagramSocketImpl(fd, Socket.preferIPv4Stack());
+ }
+ }
+}