diff options
author | jfrijters <jfrijters> | 2007-07-12 18:09:51 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2007-07-12 18:09:51 +0400 |
commit | 894e32c1b9a6af908523cc45484f1bbfc093bbbc (patch) | |
tree | 42cd6c0afe493304cf576ec9ba03bd868666271e /openjdk/java/net | |
parent | a1ea9638959751c92c3ed1c1ade8d3e2ccdbcd62 (diff) |
- Fixed openjdk.cs compilation error.
- Added OpenJDK derived PlainDatagramSocketImpl implementation.
- Added compilation stubs for jgss.
Diffstat (limited to 'openjdk/java/net')
-rw-r--r-- | openjdk/java/net/PlainDatagramSocketImpl.java | 678 |
1 files changed, 678 insertions, 0 deletions
diff --git a/openjdk/java/net/PlainDatagramSocketImpl.java b/openjdk/java/net/PlainDatagramSocketImpl.java new file mode 100644 index 00000000..6b3eb6c6 --- /dev/null +++ b/openjdk/java/net/PlainDatagramSocketImpl.java @@ -0,0 +1,678 @@ +/* + * Copyright 1996-2003 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package java.net; + +import cli.System.Net.IPAddress; +import cli.System.Net.IPEndPoint; +import cli.System.Net.Sockets.SocketOptionName; +import cli.System.Net.Sockets.SocketOptionLevel; +import cli.System.Net.Sockets.MulticastOption; +import cli.System.Net.Sockets.SocketFlags; +import cli.System.Net.Sockets.SocketType; +import cli.System.Net.Sockets.ProtocolType; +import cli.System.Net.Sockets.AddressFamily; +import ikvm.lang.CIL; +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.util.Enumeration; + +/** + * Concrete datagram and multicast socket implementation base class. + * Note: This is not a public class, so that applets cannot call + * into the implementation directly and hence cannot bypass the + * security checks present in the DatagramSocket and MulticastSocket + * classes. + * + * @author Pavani Diwanji + */ + +class PlainDatagramSocketImpl extends DatagramSocketImpl +{ + // Winsock Error Codes + private static final int WSAEMSGSIZE = 10040; + private static final int WSAECONNRESET = 10054; + + private cli.System.Net.Sockets.Socket netSocket; + /* timeout value for receive() */ + private int timeout = 0; + private int trafficClass = 0; + private boolean connected = false; + private InetAddress connectedAddress = null; + private int connectedPort = -1; + + /* cached socket options */ + private int multicastInterface = 0; + private boolean loopbackMode = true; + private int ttl = -1; + + /* Used for IPv6 on Windows only */ + private FileDescriptor fd1; + private int fduse=-1; /* saved between peek() and receive() calls */ + + /* saved between successive calls to receive, if data is detected + * on both sockets at same time. To ensure that one socket is not + * starved, they rotate using this field + */ + private int lastfd=-1; + + /* + * Needed for ipv6 on windows because we need to know + * if the socket was bound to ::0 or 0.0.0.0, when a caller + * asks for it. In this case, both sockets are used, but we + * don't know whether the caller requested ::0 or 0.0.0.0 + * and need to remember it here. + */ + private InetAddress anyLocalBoundAddr=null; + + /** + * Creates a datagram socket + */ + protected synchronized void create() throws SocketException { + fd = new FileDescriptor(); + fd1 = new FileDescriptor(); + datagramSocketCreate(); + } + + /** + * Binds a datagram socket to a local port. + */ + protected synchronized void bind(int lport, InetAddress laddr) + throws SocketException { + + bind0(lport, laddr); + if (laddr.isAnyLocalAddress()) { + anyLocalBoundAddr = laddr; + } + } + + protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + netSocket.Bind(new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(laddr), lport)); + localPort = ((IPEndPoint)netSocket.get_LocalEndPoint()).get_Port(); + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new BindException(x.getMessage()); + } + catch (cli.System.ObjectDisposedException x1) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Sends a datagram packet. The packet contains the data and the + * destination address to send the packet to. + * @param packet to be sent. + */ + protected void send(DatagramPacket p) throws IOException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + int len = p.getLength(); + int port = p.getPort(); + if (port < 1 || port > 65535) + { + throw new SocketException("Invalid port"); + } + if (netSocket.SendTo(p.getData(), p.getOffset(), len, SocketFlags.wrap(SocketFlags.None), new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(p.getAddress()), port)) != len) + { + throw new SocketException("Not all data was sent"); + } + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw PlainSocketImpl.convertSocketExceptionToIOException(x); + } + catch (cli.System.ObjectDisposedException x1) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Connects a datagram socket to a remote destination. This associates the remote + * address with the local socket so that datagrams may only be sent to this destination + * and received from this destination. + * @param address the remote InetAddress to connect to + * @param port the remote port number + */ + protected void connect(InetAddress address, int port) throws SocketException { + connect0(address, port); + connectedAddress = address; + connectedPort = port; + connected = true; + } + + /** + * Disconnects a previously connected socket. Does nothing if the socket was + * not connected already. + */ + protected void disconnect() { + disconnect0(connectedAddress.family); + connected = false; + connectedAddress = null; + connectedPort = -1; + } + + /** + * Peek at the packet to see who it is from. + * @param return the address which the packet came from. + */ + protected synchronized int peek(InetAddress i) throws IOException + { + throw new IOException("Not Implemented Yet"); + } + + protected synchronized int peekData(DatagramPacket p) throws IOException + { + throw new IOException("Not Implemented Yet"); + } + + /** + * Receive the datagram packet. + * @param Packet Received. + */ + protected synchronized void receive(DatagramPacket p) + throws IOException { + try { + receive0(p); + } finally { + fduse = -1; + } + } + + protected synchronized void receive0(DatagramPacket p) throws IOException + { + byte[] data = p.getData(); + cli.System.Net.EndPoint[] remoteEP = new cli.System.Net.EndPoint[] + { + new cli.System.Net.IPEndPoint(0, 0) + }; + for (; ; ) + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + int length = 0; + try + { + length = netSocket.ReceiveFrom(data, p.offset, p.bufLength, SocketFlags.wrap(SocketFlags.None), remoteEP); + } + finally + { + p.length = length; + } + break; + } + catch (cli.System.Net.Sockets.SocketException x) + { + if (x.get_ErrorCode() == WSAECONNRESET) + { + // A previous send failed (i.e. the remote host responded with a ICMP that the port is closed) and + // the winsock stack helpfully lets us know this, but we don't care so we just retry the receive. + continue; + } + if (x.get_ErrorCode() == WSAEMSGSIZE) + { + // The buffer size was too small for the packet, ReceiveFrom receives the part of the packet + // that fits in the buffer and then throws an exception, so we have to ignore the exception in this case. + break; + } + throw PlainSocketImpl.convertSocketExceptionToIOException(x); + } + catch (cli.System.ObjectDisposedException x1) + { + throw new SocketException("Socket is closed"); + } + } + IPEndPoint endpoint = (IPEndPoint)remoteEP[0]; + p.address = PlainSocketImpl.getInetAddressFromIPEndPoint(endpoint); + p.port = endpoint.get_Port(); + } + + /** + * Set the TTL (time-to-live) option. + * @param TTL to be set. + */ + protected void setTimeToLive(int ttl) throws IOException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive), ttl); + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new SocketException(x.getMessage()); + } + catch (cli.System.ObjectDisposedException x2) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Get the TTL (time-to-live) option. + */ + protected int getTimeToLive() throws IOException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.IpTimeToLive))); + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new SocketException(x.getMessage()); + } + catch (cli.System.ObjectDisposedException x2) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Set the TTL (time-to-live) option. + * @param TTL to be set. + */ + protected void setTTL(byte ttl) throws IOException + { + setTimeToLive(ttl & 0xFF); + } + + /** + * Get the TTL (time-to-live) option. + */ + protected byte getTTL() throws IOException + { + return (byte)getTimeToLive(); + } + + /** + * Join the multicast group. + * @param multicast address to join. + */ + protected void join(InetAddress inetaddr) throws IOException { + join(inetaddr, null); + } + + /** + * Leave the multicast group. + * @param multicast address to leave. + */ + protected void leave(InetAddress inetaddr) throws IOException { + leave(inetaddr, null); + } + /** + * Join the multicast group. + * @param multicast address to join. + * @param netIf specifies the local interface to receive multicast + * datagram packets + * @throws IllegalArgumentException if mcastaddr is null or is a + * SocketAddress subclass not supported by this socket + * @since 1.4 + */ + + protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) + throws IOException { + if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type"); + join(((InetSocketAddress)mcastaddr).getAddress(), netIf); + } + + private void join(InetAddress inetaddr, NetworkInterface netIf) throws IOException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ArgumentException(); + if (false) throw new cli.System.ObjectDisposedException(""); + IPAddress mcastAddr = PlainSocketImpl.getAddressFromInetAddress(inetaddr); + Enumeration e = netIf.getInetAddresses(); + if (e.hasMoreElements()) + { + IPAddress bindAddr = PlainSocketImpl.getAddressFromInetAddress((InetAddress)e.nextElement()); + MulticastOption mcastOption = new MulticastOption(mcastAddr, bindAddr); + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.AddMembership), mcastOption); + } + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw PlainSocketImpl.convertSocketExceptionToIOException(x); + } + catch (cli.System.ArgumentException x1) + { + throw new IOException(x1.getMessage()); + } + catch (cli.System.ObjectDisposedException x2) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Leave the multicast group. + * @param multicast address to leave. + * @param netIf specified the local interface to leave the group at + * @throws IllegalArgumentException if mcastaddr is null or is a + * SocketAddress subclass not supported by this socket + * @since 1.4 + */ + protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) + throws IOException { + if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress)) + throw new IllegalArgumentException("Unsupported address type"); + leave(((InetSocketAddress)mcastaddr).getAddress(), netIf); + } + + private void leave(InetAddress inetaddr, NetworkInterface netIf) throws IOException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ArgumentException(); + if (false) throw new cli.System.ObjectDisposedException(""); + IPAddress mcastAddr = PlainSocketImpl.getAddressFromInetAddress(inetaddr); + Enumeration e = netIf.getInetAddresses(); + if (e.hasMoreElements()) + { + IPAddress bindAddr = PlainSocketImpl.getAddressFromInetAddress((InetAddress)e.nextElement()); + MulticastOption mcastOption = new MulticastOption(mcastAddr, bindAddr); + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.DropMembership), mcastOption); + } + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw PlainSocketImpl.convertSocketExceptionToIOException(x); + } + catch (cli.System.ArgumentException x1) + { + throw new IOException(x1.getMessage()); + } + catch (cli.System.ObjectDisposedException x2) + { + throw new SocketException("Socket is closed"); + } + } + + /** + * Close the socket. + */ + protected void close() { + if (fd != null || fd1 != null) { + datagramSocketClose(); + fd = null; + fd1 = null; + } + } + + /** + * set a value - since we only support (setting) binary options + * here, o must be a Boolean + */ + + public void setOption(int optID, Object o) throws SocketException { + if (fd == null && fd1 == null) { + throw new SocketException("Socket Closed"); + } + switch (optID) { + /* check type safety b4 going native. These should never + * fail, since only java.Socket* has access to + * PlainSocketImpl.setOption(). + */ + case SO_TIMEOUT: + if (o == null || !(o instanceof Integer)) { + throw new SocketException("bad argument for SO_TIMEOUT"); + } + int tmp = ((Integer) o).intValue(); + if (tmp < 0) + throw new IllegalArgumentException("timeout < 0"); + timeout = tmp; + return; + case IP_TOS: + if (o == null || !(o instanceof Integer)) { + throw new SocketException("bad argument for IP_TOS"); + } + trafficClass = ((Integer)o).intValue(); + break; + case SO_REUSEADDR: + if (o == null || !(o instanceof Boolean)) { + throw new SocketException("bad argument for SO_REUSEADDR"); + } + break; + case SO_BROADCAST: + if (o == null || !(o instanceof Boolean)) { + throw new SocketException("bad argument for SO_BROADCAST"); + } + break; + case SO_BINDADDR: + throw new SocketException("Cannot re-bind Socket"); + case SO_RCVBUF: + case SO_SNDBUF: + if (o == null || !(o instanceof Integer) || + ((Integer)o).intValue() < 0) { + throw new SocketException("bad argument for SO_SNDBUF or " + + "SO_RCVBUF"); + } + break; + case IP_MULTICAST_IF: + if (o == null || !(o instanceof InetAddress)) + throw new SocketException("bad argument for IP_MULTICAST_IF"); + break; + case IP_MULTICAST_IF2: + if (o == null || !(o instanceof NetworkInterface)) + throw new SocketException("bad argument for IP_MULTICAST_IF2"); + break; + case IP_MULTICAST_LOOP: + if (o == null || !(o instanceof Boolean)) + throw new SocketException("bad argument for IP_MULTICAST_LOOP"); + break; + default: + throw new SocketException("invalid option: " + optID); + } + socketSetOption(optID, o); + } + + /* + * get option's state - set or not + */ + + public Object getOption(int optID) throws SocketException { + if (fd == null && fd1 == null) { + throw new SocketException("Socket Closed"); + } + + Object result; + + switch (optID) { + case SO_TIMEOUT: + result = new Integer(timeout); + break; + + case IP_TOS: + result = socketGetOption(optID); + if ( ((Integer)result).intValue() == -1) { + result = new Integer(trafficClass); + } + break; + + case SO_BINDADDR: + if (fd != null && fd1 != null) { + return anyLocalBoundAddr; + } + /* fall through */ + case IP_MULTICAST_IF: + case IP_MULTICAST_IF2: + case SO_RCVBUF: + case SO_SNDBUF: + case IP_MULTICAST_LOOP: + case SO_REUSEADDR: + case SO_BROADCAST: + result = socketGetOption(optID); + break; + + default: + throw new SocketException("invalid option: " + optID); + } + + return result; + } + + private void datagramSocketCreate() throws SocketException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + netSocket = new cli.System.Net.Sockets.Socket( + AddressFamily.wrap(AddressFamily.InterNetwork), + SocketType.wrap(SocketType.Dgram), + ProtocolType.wrap(ProtocolType.Udp)); + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast), 1); + fd1 = null; + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new SocketException(x.getMessage()); + } + } + + private void datagramSocketClose() + { + netSocket.Close(); + } + + private void socketSetOption(int opt, Object val) throws SocketException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + switch (opt) + { + case SocketOptions.SO_BROADCAST: + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast), ((Boolean)val).booleanValue() ? 1 : 0); + break; + case SocketOptions.IP_MULTICAST_IF: + { + NetworkInterface netIf = (NetworkInterface)val; + Enumeration e = netIf.getInetAddresses(); + if (e.hasMoreElements()) + { + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface), (int)PlainSocketImpl.getAddressFromInetAddress((InetAddress)e.nextElement()).get_Address()); + } + break; + } + case SocketOptions.IP_MULTICAST_IF2: + throw new SocketException("SocketOptions.IP_MULTICAST_IF2 not implemented"); + case SocketOptions.IP_MULTICAST_LOOP: + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastLoopback), ((Boolean)val).booleanValue() ? 1 : 0); + break; + case SocketOptions.SO_TIMEOUT: + netSocket.SetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout), ((Integer)val).intValue()); + break; + case SocketOptions.SO_REUSEADDR: + PlainSocketImpl.setCommonSocketOption(netSocket, opt, ((Boolean)val).booleanValue(), null); + break; + default: + PlainSocketImpl.setCommonSocketOption(netSocket, opt, false, val); + break; + } + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new SocketException(x.getMessage()); + } + catch (cli.System.ObjectDisposedException x1) + { + throw new SocketException("Socket is closed"); + } + } + + private Object socketGetOption(int opt) throws SocketException + { + try + { + if (false) throw new cli.System.Net.Sockets.SocketException(); + if (false) throw new cli.System.ObjectDisposedException(""); + switch (opt) + { + case SocketOptions.SO_BROADCAST: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.Broadcast))) != 0; + case SocketOptions.IP_MULTICAST_IF: + //return getInetAddressFromInt(CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastInterface)))); + case SocketOptions.IP_MULTICAST_IF2: + throw new SocketException("SocketOptions.IP_MULTICAST_IF(2) not implemented"); + case SocketOptions.IP_MULTICAST_LOOP: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.MulticastLoopback))) != 0; + case SocketOptions.SO_TIMEOUT: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveTimeout))); + case SocketOptions.SO_REUSEADDR: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReuseAddress))) != 0; + case SocketOptions.SO_SNDBUF: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.SendBuffer))); + case SocketOptions.SO_RCVBUF: + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.Socket), SocketOptionName.wrap(SocketOptionName.ReceiveBuffer))); + case SocketOptions.IP_TOS: + // TODO handle IPv6 here + return CIL.unbox_int(netSocket.GetSocketOption(SocketOptionLevel.wrap(SocketOptionLevel.IP), SocketOptionName.wrap(SocketOptionName.TypeOfService))); + case SocketOptions.SO_BINDADDR: + return PlainSocketImpl.getInetAddressFromIPEndPoint((IPEndPoint)netSocket.get_LocalEndPoint()); + default: + throw new SocketException("Invalid socket option: " + opt); + } + } + catch (cli.System.Net.Sockets.SocketException x) + { + throw new SocketException(x.getMessage()); + } + catch (cli.System.ObjectDisposedException x1) + { + throw new SocketException("Socket is closed"); + } + } + + private void connect0(InetAddress address, int port) throws SocketException + { + throw new SocketException("not implemented"); + } + + private void disconnect0(int family) + { + // TODO + } +} + |