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());
+		}
+	}
+}